2023DASCTF六月挑战赛二进制专项--reverse

一. careful

  • 动态调试 设置断点在 ds:gethostbyname 处
  • 进入gethostbyname 内部其实存在了内联HOOK hook了这个API函数 修改了传入的参数 然后调用真正的API
  • 需要更进一步步入进入该内联函数分析
  • 最后看参数即可得到flag

二. babyre

  • 首先找到关键字符串

  • 交叉引用到7A80处

  • __int64 __fastcall sub_140007A80(int a1, __int64 a2)
    {
      char *v2; // rdi
      __int64 i; // rcx
      char v5[32]; // [rsp+0h] [rbp-40h] BYREF
      char v6; // [rsp+40h] [rbp+0h] BYREF
      DWORD dwProcessId; // [rsp+44h] [rbp+4h]
      HANDLE v8; // [rsp+68h] [rbp+28h]
      char Parameter[132]; // [rsp+90h] [rbp+50h] BYREF
      int j; // [rsp+114h] [rbp+D4h]
      HRSRC hResInfo; // [rsp+138h] [rbp+F8h]
      size_t Size; // [rsp+154h] [rbp+114h]
      HGLOBAL hResData; // [rsp+178h] [rbp+138h]
      void *Src; // [rsp+198h] [rbp+158h]
      void *v15; // [rsp+1B8h] [rbp+178h]
      __int64 v16; // [rsp+1D8h] [rbp+198h]
      __int64 v17; // [rsp+1F8h] [rbp+1B8h]
      int k; // [rsp+214h] [rbp+1D4h]
      __int64 v19; // [rsp+2E8h] [rbp+2A8h]
    
      v2 = &v6;
      for ( i = 130i64; i; --i )
      {
        *(_DWORD *)v2 = -858993460;
        v2 += 4;
      }
      sub_1400012A8(&unk_1400140F4);
      dwProcessId = GetCurrentProcessId();
      v8 = OpenProcess(0x1FFFFFu, 0, dwProcessId);
      if ( a1 != 2 )
        exit(0);
      for ( j = 0; ; ++j )
      {
        v19 = j;
        if ( j >= strlen(*(const char **)(a2 + 8)) )
          break;
        Parameter[j] = *(_BYTE *)(*(_QWORD *)(a2 + 8) + j);
      }
      hResInfo = FindResourceW(0i64, (LPCWSTR)0x65, L"cod");
      LODWORD(Size) = SizeofResource(0i64, hResInfo);
      hResData = LoadResource(0i64, hResInfo);
      Src = LockResource(hResData);
      v15 = malloc((unsigned int)Size);
      memcpy(v15, Src, (unsigned int)Size);
      sub_140001087(v15);//decrypt shellcode
      v16 = qword_14000FC30(v8, 0i64, 874i64, 4096i64, 64);//VirtualAllocEx
      qword_14000FC28(v8, v16, v15, 874i64, 0i64);//WriteProcessMemory
      v17 = qword_14000FC18(v8, 0i64, 0i64, v16, Parameter, 0, 0i64);//CreateRemoteThread
      Sleep(0x1F4u);
      for ( k = 0; k < 44; ++k )
        ;
      CreateThread(0i64, 0i64, StartAddress, Parameter, 0, 0i64);//子进程:checkflag
      Sleep(0x190u);
      sub_140001253(v5, &unk_14000BEE0);
      return 0i64;
    }
    
  • cod二进制资源,在2940中会进行解密

  • 关于cod:通过对资源进行解密 并且Write到自身的内存中去 然后通过远程线程执行

  • 其中会用到反调试在28F0

  • 直接静态即可

  • 将cod提取至resource hack

  • 生成.bin文件后解密

  • 解密脚本如下:

  • arr = [0x18, 0x57, 0x68, 0x64]
    with open('C:\\Users\\lenovo\\Desktop\\COD101', 'rb') as f:
        b = f.read()
    b = bytearray(b)
    for i in range(len(b)):
        b[i] = b[i] ^ arr[i % 4]
    with open('C:\\Users\\lenovo\\Desktop\\COD_de', 'wb') as f:
        f.write(b)
    
  • 将解密后的bin文件用ida分析

  • 按c键将二进制数据转换成汇编代码

  • 下面开始去花

  • 其中注意loc_1EE,

  • 直接nop掉

  • 这时就能生成伪代码了

  • __int64 __fastcall sub_0(_BYTE *a1)
    {
      void *v1; // rax
      __int64 result; // rax
      char v3[292]; // [rsp+40h] [rbp+10h]
      unsigned int j; // [rsp+164h] [rbp+134h]
      unsigned int v5; // [rsp+184h] [rbp+154h]
      unsigned int v6; // [rsp+1A4h] [rbp+174h]
      int v7; // [rsp+1C4h] [rbp+194h]
      char v8[44]; // [rsp+1E8h] [rbp+1B8h] BYREF
      unsigned int v9; // [rsp+214h] [rbp+1E4h]
      _BYTE *i; // [rsp+238h] [rbp+208h]
      int v11; // [rsp+254h] [rbp+224h]
      __int64 v12; // [rsp+3E8h] [rbp+3B8h]
    
      memset(v1, 0, 0x101ui64);
      qmemcpy(v8, "]Bb)", 4);
      v8[4] = 3;
      v8[5] = 54;
      v8[6] = 71;
      v8[7] = 65;
      v8[8] = 21;
      v8[9] = 54;
      v9 = 0;
      for ( i = a1; *i; ++i )
        ++v9;
      for ( j = 0; j < 256; ++j )
        v3[j] = j;
      v6 = 0;
      v5 = 0;
      for ( j = 0; j < 256; ++j )
      {
        v7 = v3[j];
        v5 = (v8[v6] + v7 + 2 * v5) % 0x100;
        v3[j] = v3[v5];
        v3[v5] = v7;
        if ( ++v6 >= 0xA )
          v6 = 0;
      }
      v6 = 0;
      v5 = 0;
      for ( j = 0; ; ++j )
      {
        result = v9;
        if ( j >= v9 )
          break;
        v5 = (v6 + v5) % 0x100;
        v6 = (v3[v5] + v6) % 0x100;
        v7 = v3[v5];
        v3[v5] = v3[v6];
        v3[v6] = v7;
        v11 = v3[(v3[v5] + v6 + v3[v6]) % 0x100];
        a1[j] ^= v11;
        v12 = j;
        a1[j] += j % 0xD;
      }
      return result;
    }
    
    • 很明显的魔改RC4代码

    • 这里我们找到起始key就是v8

    • 同时flag的检验在程序的另一个子进程中

    • checkflag伪代码如下:

    • void __fastcall __noreturn StartAddress_0(__int64 a1)
      {
        char *v1; // rdi
        __int64 i; // rcx
        char v3; // [rsp+20h] [rbp+0h] BYREF
        char v4[76]; // [rsp+28h] [rbp+8h]
        int j; // [rsp+74h] [rbp+54h]
      
        v1 = &v3;
        for ( i = 30i64; i; --i )
        {
          *(_DWORD *)v1 = -858993460;
          v1 += 4;
        }
        sub_1400012A8((__int64)&unk_1400140F4);
        v4[0] = 0xF7;
        v4[1] = 46;
        v4[2] = 52;
        v4[3] = -16;
        v4[4] = 114;
        v4[5] = -49;
        v4[6] = 94;
        v4[7] = 10;
        v4[8] = -69;
        v4[9] = -20;
        v4[10] = -79;
        v4[11] = 43;
        v4[12] = 112;
        v4[13] = -120;
        v4[14] = -120;
        v4[15] = -19;
        v4[16] = 70;
        v4[17] = 56;
        v4[18] = -37;
        v4[19] = -38;
        v4[20] = 108;
        v4[21] = -67;
        v4[22] = -44;
        v4[23] = 6;
        v4[24] = 119;
        v4[25] = -14;
        v4[26] = -49;
        v4[27] = 86;
        v4[28] = -120;
        v4[29] = -58;
        v4[30] = 49;
        v4[31] = -46;
        v4[32] = -73;
        v4[33] = 90;
        v4[34] = -63;
        v4[35] = 66;
        v4[36] = -80;
        v4[37] = -12;
        v4[38] = 72;
        v4[39] = 55;
        v4[40] = -11;
        v4[41] = 44;
        v4[42] = -11;
        v4[43] = 88;
        puts(" ");
        for ( j = 0; j < 44; ++j )
        {
          if ( *(char *)(a1 + j) != v4[j] )
          {
            sub_14000114A("error!\n");
            exit(0);
          }
        }
        sub_14000114A("get flag!");
        exit(0);
      }
      
    • exp如下:

    • class RC4:
          def __init__(self, key) -> None:
              self.key = key
              self.S = 0
      
              self.__rc4_init__()
      
          def __rc4_init__(self):
              S = [i for i in range(256)]
              j = 0
              for i in range(256):
                  j = (2 * j + S[i] + key[i % len(key)]) % 256
                  S[i], S[j] = S[j], S[i]
              self.S = S
      
          def rc4_encrypt(self, plain) -> list:
              i = 0
              j = 0
              cipher = []
              cnt = 0
              for p in plain:
                  p = (p + 256 - cnt % 0xd) % 256
                  cnt += 1
                  i = (i + j) % 256
                  j = (j + self.S[i]) % 256
                  self.S[i], self.S[j] = self.S[j], self.S[i]
                  tmp = self.S[(self.S[i] + self.S[j] + j) % 256]
                  k = p ^ tmp
                  cipher.append(k)
              return cipher
      
      key = [0x5D , 0x42 , 0x62 , 0x29 , 0x3, 0x36 , 0x47 , 0x41 , 0x15, 0x36]
      data = [0xF7, 0x2E, 0x34, 0xF0, 0x72, 0xCF, 0x5E, 0x0A, 0xBB, 0xEC, 0xB1, 0x2B, 0x70, 0x88, 0x88, 0xED,
      0x46, 0x38, 0xDB, 0xDA, 0x6C, 0xBD, 0xD4, 0x06, 0x77, 0xF2, 0xCF, 0x56, 0x88, 0xC6, 0x31, 0xD2,
      0xB7, 0x5A, 0xC1, 0x42, 0xB0, 0xF4, 0x48, 0x37, 0xF5, 0x2C, 0xF5, 0x58]
      
      rc4 = RC4(key)
      plain = rc4.rc4_encrypt(data)
      print(''.join(map(chr,plain)))
      
      

三. ez_exe

  • 这里我们查壳发现是pyinstaller打包的exe

  • 首先用pyinstxtractor进行解包

  • 然后用uncompyle6进行反编译

  • 这里有修改magic number的问题没有解决

  • 找到:https://github.com/google/pytype/blob/main/pytype/pyc/magic.py(不同版本python对应的magic number

  • 以及magic number详解:http://t.csdn.cn/Lxf0T

  • 然而解决不了,那么我们不妨用在线反编译网站进行反编译:在线Python pyc文件编译与反编译 (lddgo.net)

  • 得到python代码:

    # Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
    # Version : Python 3.11
    
    import ctypes
    from time import *
    from ctypes import *
    from ctypes import wintypes
    from hashlib import md5
    
    class _STARTUPINFO(Structure):
        _fields_ = [
            ('cb', c_ulong),
            ('lpReserved', c_char_p),
            ('lpDesktop', c_char_p),
            ('lpTitle', c_char_p),
            ('dwX', c_ulong),
            ('dwY', c_ulong),
            ('dwXSize', c_ulong),
            ('dwYSize', c_ulong),
            ('dwXCountChars', c_ulong),
            ('dwYCountChars', c_ulong),
            ('dwFillAttribute', c_ulong),
            ('dwFlags', c_ulong),
            ('wShowWindow', c_ushort),
            ('cbReserved2', c_ushort),
            ('lpReserved2', c_char_p),
            ('hStdInput', c_ulong),
            ('hStdOutput', c_ulong),
            ('hStdError', c_ulong)]
    
    
    class _PROCESS_INFORMATION(Structure):
        _fields_ = [
            ('hProcess', c_void_p),
            ('hThread', c_void_p),
            ('dwProcessId', c_ulong),
            ('dwThreadId', c_ulong)]
    
    StartupInfo = _STARTUPINFO()
    ProcessInfo = _PROCESS_INFORMATION()
    key1 = bytes(md5(b'bin1bin1bin1').hexdigest().encode())
    file = open('bin1', 'rb').read()
    arr = range(len(file))()
    open('bin1', 'wb').write(bytes(arr))
    sleep(0)
    bet = ctypes.windll.kernel32.CreateProcessA(b'bin1', ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0), byref(StartupInfo), byref(ProcessInfo))
    ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ProcessInfo.hProcess), ctypes.c_int(-1))
    open('bin1', 'wb').write(file)
    
  • 运行ez_exe,发现please use zhe execute file decrypt 'bin2' and your will get flag!

  • 提示我们用这个去解密bin2

  • 我们运行ez_py.pyc,从而解密bin2

  • 这里是xxtea算法

  • 直接写脚本逆向即可

  • #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    
    #include <stdint.h>
    
    //delta changed
    #define DELTA 0x7937B99E
    #define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
    
    void btea(uint32_t* v, int n, uint32_t const key[4]) {
    	uint32_t y, z, sum;
    	unsigned p, rounds, e;
    	if (n > 1) {          /* Coding Part */
    		rounds = 6 + 52 / n;
    		sum = 0;
    		z = v[n - 1];
    		do {
    			sum += DELTA;
    			e = (sum >> 2) & 3;
    			for (p = 0; p < n - 1; p++) {
    				y = v[p + 1];
    				z = v[p] += MX;
    			}
    			y = v[0];
    			z = v[n - 1] += MX;
    		} while (--rounds);
    	}
    	else if (n < -1) {  /* Decoding Part */
    		n = -n;
    		//round changed 
    		rounds =  52 / n;
    		sum = rounds * DELTA;
    		y = v[0];
    		do {
    			e = (sum >> 2) & 3;
    			for (p = n - 1; p > 0; p--) {
    				z = v[p - 1];
    				y = v[p] -= MX;
    			}
    			z = v[n - 1];
    			y = v[0] -= MX;
    		} while ((sum -= DELTA) != 0);
    	}
    }
    
    int main()
    {
    	uint32_t key[4] = { 0 };
    	key[0] = 0x4B5F;
    	key[1] = 0xDEAD;
    	key[2] = 0x11ED;
    	key[3] = 0xB3CC;
    	uint32_t v5[11] = { 0 };
    	v5[0] = 0xCC45699D;
    	v5[1] = 0x683D5352;
    	v5[2] = 0xB8BB71A0;
    	v5[3] = 0xD3817AD;
    	v5[4] = 0x7547E79E;
    	v5[5] = 0x4BDD8C7C;
    	v5[6] = 0x95E25A81;
    	v5[7] = 0xC4525103;
    	v5[8] = 0x7049B46F;
    	v5[9] = 0x5417F77C;
    	v5[10] = 0x65567138;
    	btea(v5, -11, key);
    	for (int i = 0; i < 44; i++)
    	{
    		printf("%c",*((char *)v5 +i) & 0xff);
    	}
    	return 0;
    }
    
    • 注意加密的轮数与delta都改了
    • DASCTF{7eb20cb2-deac-11ed-ae42-94085339ce84}

四. cap

  • main函数如下:

  • __int64 __fastcall sub_140001030(HWND hWnd)
    {
      HBITMAP v2; // r14
      HDC hdcSrc; // r13
      HDC DC; // rsi
      HDC CompatibleDC; // r15
      int hSrc; // ebx
      int wSrc; // eax
      HBITMAP CompatibleBitmap; // rax
      signed int v9; // ebx
      HANDLE FileW; // rax
      void *v11; // r12
      signed int v12; // r10d
      _BYTE *v13; // r9
      int v14; // ecx
      int v15; // edx
      void *lpBuffer; // [rsp+60h] [rbp-59h]
      HGLOBAL hMem; // [rsp+68h] [rbp-51h]
      struct tagRECT Rect; // [rsp+70h] [rbp-49h] BYREF
      struct tagBITMAPINFO bmi; // [rsp+80h] [rbp-39h] BYREF
      char v21; // [rsp+ACh] [rbp-Dh]
      char v22; // [rsp+ADh] [rbp-Ch]
      char v23; // [rsp+AEh] [rbp-Bh]
      char v24; // [rsp+AFh] [rbp-Ah]
      char v25; // [rsp+B0h] [rbp-9h]
      char v26; // [rsp+B1h] [rbp-8h]
      int v27; // [rsp+B2h] [rbp-7h]
      DWORD NumberOfBytesWritten; // [rsp+B8h] [rbp-1h] BYREF
      char pv[4]; // [rsp+C0h] [rbp+7h] BYREF
      LONG v30; // [rsp+C4h] [rbp+Bh]
      UINT cLines; // [rsp+C8h] [rbp+Fh]
    
      NumberOfBytesWritten = 0;
      v2 = 0i64;
      hdcSrc = GetDC(0i64);
      DC = GetDC(hWnd);
      CompatibleDC = CreateCompatibleDC(DC);
      if ( CompatibleDC )
      {
        GetClientRect(hWnd, &Rect);                 // 检索用户坐标
        SetStretchBltMode(DC, 4);                   // 设置位图拉伸模式。
        hSrc = GetSystemMetrics(1);
        wSrc = GetSystemMetrics(0);
        if ( StretchBlt(DC, 0, 0, Rect.right, Rect.bottom, hdcSrc, 0, 0, wSrc, hSrc, 0xCC0020u) )
        {
          CompatibleBitmap = CreateCompatibleBitmap(DC, Rect.right - Rect.left, Rect.bottom - Rect.top);
          v2 = CompatibleBitmap;
          if ( CompatibleBitmap )
          {
            SelectObject(CompatibleDC, CompatibleBitmap);
            if ( BitBlt(CompatibleDC, 0, 0, Rect.right - Rect.left, Rect.bottom - Rect.top, DC, 0, 0, 0xCC0020u) )
            {
              GetObjectW(v2, 32, pv);
              bmi.bmiHeader.biWidth = v30;
              bmi.bmiHeader.biHeight = cLines;
              bmi.bmiHeader.biSize = 40;
              *(_QWORD *)&bmi.bmiHeader.biPlanes = 2097153i64;
              memset(&bmi.bmiHeader.biSizeImage, 0, 20);
              v9 = 4 * cLines * ((32 * v30 + 31) / 32);
              hMem = GlobalAlloc(0x42u, (unsigned int)v9);
              lpBuffer = GlobalLock(hMem);
              GetDIBits(DC, v2, 0, cLines, lpBuffer, &bmi, 0);
              FileW = CreateFileW(L"cap.bin", 0x40000000u, 0, 0i64, 2u, 0x80u, 0i64);
              v23 ^= 0x64u;
              v24 ^= 0x61u;
              v11 = FileW;
              v25 ^= 0x73u;
              v26 ^= 0x63u;
              bmi.bmiHeader.biSize ^= 'yb_c';
              bmi.bmiHeader.biWidth ^= 'sad_';
              bmi.bmiHeader.biHeight ^= 'eftc';
              *(_QWORD *)&bmi.bmiHeader.biPlanes ^= 'ad_yb_cn';
              bmi.bmiColors[0].rgbReserved = ((unsigned __int16)(v9 + 54) >> 8) ^ 0x62;
              v21 = ((unsigned int)(v9 + 54) >> 16) ^ 0x79;
              v22 = ((unsigned int)(v9 + 54) >> 24) ^ 0x5F;
              v27 = 'nefB';
              bmi.bmiColors[0].rgbGreen = 46;
              bmi.bmiColors[0].rgbBlue = 44;
              bmi.bmiColors[0].rgbRed = (v9 + 54) ^ 0x5F;
              v12 = 0;
              bmi.bmiHeader.biSizeImage ^= 'ftcs';
              bmi.bmiHeader.biXPelsPerMeter ^= '_cne';
              bmi.bmiHeader.biYPelsPerMeter ^= 'd_yb';
              bmi.bmiHeader.biClrUsed ^= 'tcsa';
              bmi.bmiHeader.biClrImportant ^= 'cnef';
              if ( v9 > 0 )
              {
                v13 = lpBuffer;
                do
                {
                  v14 = v12 + 3;
                  v15 = (unsigned __int64)(1321528399i64 * (v12 + 3)) >> 32;
                  ++v12;
                  *v13++ ^= aEncByDasctf[v14 - 13 * (((unsigned int)v15 >> 31) + (v15 >> 2))];
                }
                while ( v12 < v9 );
              }
              WriteFile(FileW, bmi.bmiColors, 0xEu, &NumberOfBytesWritten, 0i64);
              WriteFile(v11, &bmi, 0x28u, &NumberOfBytesWritten, 0i64);
              WriteFile(v11, lpBuffer, v9, &NumberOfBytesWritten, 0i64);
              GlobalUnlock(hMem);
              GlobalFree(hMem);
              CloseHandle(v11);
            }
            else
            {
              MessageBoxW(hWnd, L"BitBlt has failed", L"Failed", 0);
            }
          }
          else
          {
            MessageBoxW(hWnd, L"CreateCompatibleBitmap Failed", L"Failed", 0);
          }
        }
        else
        {
          MessageBoxW(hWnd, L"StretchBlt has failed", L"Failed", 0);
        }
      }
      else
      {
        MessageBoxW(hWnd, L"CreateCompatibleDC has failed", L"Failed", 0);
      }
      DeleteObject(v2);
      DeleteObject(CompatibleDC);
      ReleaseDC(0i64, hdcSrc);
      ReleaseDC(hWnd, DC);
      return 0i64;
    }
    
  • 如果在网络上查询相关的API的话可以很清楚的了解到这些API函数在一起调用最终会实现屏幕图像截取的功能

  • 在这里动调

  • 可以发现数组的下标在0~12之间循环

  • 我们随便打开一个BMP类型的文件,用010看看。

  • 对于BMP类型的文件前两个字节必定是43 4D。既然这个加密的bmp的每一个字节进行的都是异或,那我们可以将前两个字节异或看看。

  • n和c是密钥enc_by_dasctf的第2个和第3个字符,按照这个序列,我们向后将密钥向后延申看看后面的情况如何。

  • key = "enc_by_dasctf"
    with open('cap.bin', 'rb') as f:
        s = bytearray(f.read())
    for i in range(len(s)):
        s[i] ^= ord(key[(i+1) % len(key)])
    with open('flag.bmp', 'wb') as f:
        f.write(s)
    
    • 得到flag。
    • image-20230804123426234

五. unsym

  • go语言逆向

  • golang插件恢复函数符号

  • 看看main_main函数

  • __int64 __fastcall main_main()
    {
      __int64 v0; // r14
      __int128 v1; // xmm15
      __int64 v2; // rax
      __int64 v3; // rbx
      __int64 v4; // rcx
      __int64 v5; // rdi
      __int64 v6; // rax
      __int64 v7; // rax
      __int64 v8; // rcx
      __int64 v9; // rdi
      __int64 v10; // rsi
      __int64 v11; // rax
      __int64 v12; // rbx
      __int64 v13; // rbx
      __int64 v14; // rax
      unsigned __int64 v15; // rcx
      __int64 i; // rdx
      unsigned __int64 v17; // rbx
      __int64 v18; // rax
      __int64 v19; // rax
      unsigned __int64 v20; // rcx
      __int64 File; // rax
      __int64 v22; // rax
      __int64 v23; // rcx
      __int64 v24; // rax
      __int64 v25; // rax
      __int64 j; // rcx
      __int64 v27; // rbx
      __int64 v28; // rax
      __int64 v30; // rax
      __int64 v31; // [rsp-38h] [rbp-230h]
      __int64 v32; // [rsp-38h] [rbp-230h]
      __int64 v33; // [rsp-38h] [rbp-230h]
      __int64 v34; // [rsp-30h] [rbp-228h]
      __int64 v35; // [rsp+18h] [rbp-1E0h]
      __int64 v36; // [rsp+28h] [rbp-1D0h]
      unsigned __int64 v37; // [rsp+38h] [rbp-1C0h]
      unsigned __int64 v38; // [rsp+38h] [rbp-1C0h]
      __int64 v39; // [rsp+48h] [rbp-1B0h] BYREF
      __int64 v40; // [rsp+50h] [rbp-1A8h]
      __int64 v41; // [rsp+58h] [rbp-1A0h] BYREF
      _QWORD v42[2]; // [rsp+62h] [rbp-196h]
      int v43; // [rsp+72h] [rbp-186h]
      __int16 v44; // [rsp+76h] [rbp-182h]
      __int64 v45; // [rsp+B8h] [rbp-140h]
      __int64 v46; // [rsp+C0h] [rbp-138h]
      __int64 v47; // [rsp+C8h] [rbp-130h]
      __int64 v48; // [rsp+D0h] [rbp-128h]
      __int64 v49; // [rsp+D8h] [rbp-120h]
      __int64 v50; // [rsp+E0h] [rbp-118h]
      __int64 v51; // [rsp+E8h] [rbp-110h]
      __int64 v52; // [rsp+F0h] [rbp-108h]
      __int64 v53; // [rsp+F8h] [rbp-100h]
      __int64 v54; // [rsp+100h] [rbp-F8h]
      _QWORD *v55; // [rsp+108h] [rbp-F0h]
      const char *v56; // [rsp+110h] [rbp-E8h]
      _QWORD *v57; // [rsp+118h] [rbp-E0h]
      void *v58; // [rsp+120h] [rbp-D8h]
      char **v59; // [rsp+128h] [rbp-D0h]
      __int128 v60; // [rsp+130h] [rbp-C8h]
      void *v61; // [rsp+140h] [rbp-B8h]
      char **v62; // [rsp+148h] [rbp-B0h]
      void *v63; // [rsp+150h] [rbp-A8h]
      char **v64; // [rsp+158h] [rbp-A0h]
      __int128 v65; // [rsp+160h] [rbp-98h]
      char v66; // [rsp+170h] [rbp-88h]
      __int64 v67; // [rsp+178h] [rbp-80h]
      __int128 v68; // [rsp+180h] [rbp-78h]
      char v69; // [rsp+190h] [rbp-68h]
      __int64 v70; // [rsp+198h] [rbp-60h]
      __int128 v71; // [rsp+1A0h] [rbp-58h]
      unsigned __int8 v72; // [rsp+1B0h] [rbp-48h]
      __int64 v73; // [rsp+1B8h] [rbp-40h]
      __int128 v74; // [rsp+1C0h] [rbp-38h]
      char v75; // [rsp+1D0h] [rbp-28h]
      __int64 *v76; // [rsp+1D8h] [rbp-20h]
      __int64 v77; // [rsp+1E0h] [rbp-18h]
      __int64 v78; // [rsp+1E8h] [rbp-10h]
    
      if ( (unsigned __int64)&v39 <= *(_QWORD *)(v0 + 16) )
        runtime_morestack_noctxt();
      v66 = 0;
      v67 = 0LL;
      v68 = v1;
      math_big__ptr_Int_SetString();
      v55 = (_QWORD *)runtime_newobject();
      *v55 = 0LL;
      v58 = &unk_4C9780;
      v59 = &off_506CD0;
      fmt_Fprint();
      v56 = "\b";
      v57 = v55;
      fmt_Fscanln();
      v2 = *v55;
      v54 = *v55;
      v3 = v55[1];
      v40 = v3;
      v4 = 0LL;
      v5 = 0LL;
      while ( v4 < v3 )
      {
        v50 = v5;
        if ( *(unsigned __int8 *)(v2 + v4) >= 0x80u )
        {
          runtime_decoderune();
          v8 = v3;
        }
        else
        {
          v8 = v4 + 1;
        }
        v39 = v8;
        v60 = v1;
        v6 = runtime_convT64();
        *(_QWORD *)&v60 = "\b";
        *((_QWORD *)&v60 + 1) = v6;
        fmt_Sprintf();
        v7 = runtime_concatstring2();
        v4 = v39;
        v5 = v7;
        v2 = v54;
        v3 = v40;
      }
      v41 = 65537LL;
      v75 = 0;
      v76 = &v41;
      v77 = 1LL;
      v78 = 1LL;
      v72 = 0;
      v73 = 0LL;
      v74 = v1;
      v69 = 0;
      v70 = 0LL;
      v71 = v1;
      math_big__ptr_Int_SetString();
      math_big__ptr_Int_exp();
      v9 = v72;
      v10 = 16LL;
      v31 = math_big_nat_itoa();
      v12 = v11;
      v47 = runtime_slicebytetostring();
      runtime_makeslice();
      if ( v12 == 57 && (unsigned __int8)runtime_memequal() )
      {
        v13 = *v55;
        v14 = runtime_stringtoslicebyte();
        v42[0] = 0x504D5404501D282FLL;
        v42[1] = 0x3D5B2A485C5917LL;
        v43 = 54333973;
        v44 = 4888;
        for ( i = 0LL; i < 22; ++i )
          *((_BYTE *)v42 + i) ^= aVghpc19pc19hx2[i];
        v38 = v15;
        v49 = v14;
        v65 = v1;
        runtime_slicebytetostring();
        v30 = runtime_convTstring();
        *(_QWORD *)&v65 = &unk_4C9780;
        *((_QWORD *)&v65 + 1) = v30;
        v9 = 1LL;
        v10 = 1LL;
        fmt_Fprintln();
        v20 = v38;
        v19 = v49;
      }
      else
      {
        v17 = encoding_base64__ptr_Encoding_DecodeString();
        v18 = runtime_slicebytetostring();
        if ( v17 < 0x10 )
          runtime_panicSliceAlen(v31);
        v13 = v18;
        v19 = runtime_stringtoslicebyte();
      }
      v37 = v20;
      v49 = v19;
      File = os_ReadFile();
      if ( v9 )
      {
    LABEL_26:
        v45 = v10;
        v63 = &unk_4C9780;
        v64 = &off_506CE0;
        fmt_Fprintln();
        while ( 1 )
          runtime_gopanic(v31);
      }
      v46 = File;
      v22 = crypto_aes_NewCipher();
      if ( v23 )
      {
        runtime_gopanic(v31);
        goto LABEL_26;
      }
      v51 = v13;
      v54 = v22;
      v24 = (*(__int64 (**)(void))(v22 + 24))();
      if ( !v24 )
        runtime_panicdivide();
      v35 = v24 - 7 % v24;
      v34 = runtime_makeslicecopy(v31);
      for ( j = 7LL; j < v35 + 7; ++j )
        *(_BYTE *)(v25 + j) = v35;
      v53 = v25;
      if ( (*(__int64 (**)(void))(v54 + 24))() > v37 )
    LABEL_23:
        runtime_panicSliceAcap(v32, v34);
      v27 = v51;
      crypto_cipher_NewCBCEncrypter(v32, v34);
      v36 = v28;
      v48 = v27;
      v52 = runtime_makeslice();
      (*(void (**)(void))(v36 + 32))();
      if ( os_WriteFile() )
      {
        v34 = runtime_gopanic(v33);
        goto LABEL_23;
      }
      v61 = &unk_4C9780;
      v62 = &off_506CF0;
      return fmt_Fprintln();
    }
    
  • 发现是个RSA加密与一个AES解密

  • 首先写一个脚本将AES的密钥解出来

  • n = 0x1d884d54d21694ccd120f145c8344b729b301e782c69a8f3073325b9c5
    p = 37636318457745167234140808130156739
    q = 21154904887215748949280410616478423
    c = 0xfad53ce897d2c26f8cad910417fbdd1f0f9a18f6c1748faca10299dc8
    e = 0x10001
    phi=(p-1)*(q-1)
    d=inverse(e,phi)
    print(long_to_bytes(pow(c,d,n)))
    
  • 而且AES的密钥与偏移是一样的

  • 直接写exp将bin文件解密

  • from Crypto.Cipher import AES
     
    password = b'E@sy_RSA_enc7ypt'  
    iv = b'E@sy_RSA_enc7ypt' 
    with open('encrypted.bin','rb') as f:
        en_text = f.read()
    aes = AES.new(password, AES.MODE_CBC, iv)  
    de_text = aes.decrypt(en_text)
    with open('decrypt.exe','wb') as f:
        f.write(de_text)
    
  • 运行解密后的exe即有flag