查壳后你会发现有壳,去壳的时候你会发现去不了壳,所以这里是有个overlay_offset变量被修改了
所以用010Editor打开,修改最后
可以参考吾爱上面的见解
然后我们用ida打开

int __fastcall main(int argc, const char **argv, const char **envp)
{
size_t v4; // rbx
unsigned __int8 rright[18]; // [rsp+0h] [rbp-C0h] BYREF
unsigned __int8 nss_array[40]; // [rsp+20h] [rbp-A0h]
unsigned __int8 BUU[41]; // [rsp+50h] [rbp-70h] BYREF
unsigned __int8 crypt[13]; // [rsp+83h] [rbp-3Dh] BYREF
unsigned __int8 *encrypt; // [rsp+90h] [rbp-30h]
int flag; // [rsp+9Ch] [rbp-24h]
unsigned __int64 k_len; // [rsp+A0h] [rbp-20h]
int i; // [rsp+ACh] [rbp-14h]
puts("UPX shell is really fun, fun to play with");
puts("Can you unpack?");
memset(crypt, 0, sizeof(crypt));
memset(BUU, 0, sizeof(BUU));
k_len = 0LL;
flag = 1;
*(_QWORD *)nss_array = 0x364A65466C271216LL;
*(_QWORD *)&nss_array[8] = 0x2447243568082139LL;
*(_QWORD *)&nss_array[16] = 0x29323C0F5A1A7D60LL;
*(_QWORD *)&nss_array[24] = 0x4D647C3C45531544LL;
*(_QWORD *)&nss_array[32] = 0x74152339130F7024LL;
strcpy((char *)rright, "BQ3SDnTj7vaKkMvur");
if ( ptrace(__ptrace_request::PTRACE_TRACEME, 0LL, 1LL, 0LL) == -1 )
{
puts("nononono!!!");
puts("plz close debugger");
}
else
{
puts("What is the key for unpacking:");
scanf("%12s");
encrypt = enc_obsfucate(crypt);
if ( !strcmp((const char *)encrypt, (const char *)rright) )
{
puts("Unpacking successful!!!");
puts("then, plz input your flag:");
scanf(" %40s");
if ( strlen((const char *)BUU) == 40 )
{
k_len = strlen((const char *)crypt);
strlen((const char *)BUU);
c4(BUU, crypt, k_len);
for ( i = 0; ; ++i )
{
v4 = i;
if ( v4 >= strlen((const char *)BUU) )
break;
if ( nss_array[i] != BUU[i] )
{
puts("Practice again!!!");
flag = 0;
return -1;
}
}
if ( flag == 1 )
printf("GOOD!");
}
else
{
puts("flag length wrong!!!!!");
}
}
else
{
puts("cai-jiu-duo-lian!!!");
}
free(encrypt);
}
return 0;
}
发现主要就是个C4函数进行加密,加密后的数组BUU和已知数组相同,注意我们是小端存储。还原数组是反着来,所以是:
data=[0x16, 0x12, 0x27, 0x6c, 0x46, 0x65, 0x4a, 0x36, 0x39, 0x21,
0x08, 0x68, 0x35, 0x24, 0x47, 0x24, 0x60, 0x7d, 0x1a, 0x5a,
0x0f, 0x3c, 0x32, 0x29, 0x44, 0x15, 0x53, 0x45, 0x3c, 0x7c,
0x64, 0x4d, 0x24, 0x70, 0xf, 0x13, 0x39, 0x23, 0x15, 0x74]
其实这这有一段rright,这段进行了base58加密
![]()
加密完它的位数是13位,(包括‘\0’)

这句代码其实就是要获取字符串的长度,就是12,当然你也可以点进去,就知道它 的位数了

接下来点开c4,发现就是RC4加密,解密的逻辑网上脚本一大堆,注意256换成了128
所以脚本非常简单的写出来
EXP
s=[0x16, 0x12, 0x27, 0x6c, 0x46, 0x65, 0x4a, 0x36, 0x39, 0x21,
0x08, 0x68, 0x35, 0x24, 0x47, 0x24, 0x60, 0x7d, 0x1a, 0x5a,
0x0f, 0x3c, 0x32, 0x29, 0x44, 0x15, 0x53, 0x45, 0x3c, 0x7c,
0x64, 0x4d, 0x24, 0x70, 0xf, 0x13, 0x39, 0x23, 0x15, 0x74]
s1=[0]*129
i=0
k=[0]*129
for i in range(0,128):
s1[i]=i
k[i]= k[i % 12]
j=0
for i in range(0,128):
j = (k[i] + j + s1[i]) % 128
tmp = s1[i]
s1[i] = s1[j]
s1[j] = tmp
i=0
j=0
t=0
for k in range(0,40):
i = (i + 1) % 128
j = (j + s1[i]) % 128
tmp = s1[i]
s1[i] = s1[j]
s1[j] = tmp
t = (s1[i] + s1[j]) & 0x7F
s[k] ^= s1[t]
for i in range(len(s)):
print(chr(s[i]),end='')
#BaseCTF{Rc4_1$_@_G0od_3nCrypt!on_MethOd}
949

被折叠的 条评论
为什么被折叠?



