首先找到关键字符串
交叉引用到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键将二进制数据转换成汇编代码
下面开始去花
直接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)))
这里我们查壳发现是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
#include
using namespace std;
#include
//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;
}
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)
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