拿到先查壳,发现没加壳,放进IDA中。
Shift + F12 查询字符串,通过字符串找到函数。
找到主函数。
signed __int64 sub_4009C6()
{
__int64 v0; // rax
signed __int64 result; // rax
unsigned __int64 v2; // rax
__int64 v3; // rax
const __m128i *v4; // ST10_8
const __m128i *v5; // ST18_8
const __m128i *v6; // ST20_8
const __m128i *v7; // ST28_8
const __m128i *v8; // ST30_8
const __m128i *v9; // ST38_8
const __m128i *v10; // ST40_8
const __m128i *v11; // ST48_8
const __m128i *v12; // ST50_8
__int64 final; // ST58_8
int i; // [rsp+Ch] [rbp-114h]
char v15; // [rsp+60h] [rbp-C0h] 数组
char v16; // [rsp+61h] [rbp-BFh]
char v17; // [rsp+62h] [rbp-BEh]
char v18; // [rsp+63h] [rbp-BDh]
char v19; // [rsp+64h] [rbp-BCh]
char v20; // [rsp+65h] [rbp-BBh]
char v21; // [rsp+66h] [rbp-BAh]
char v22; // [rsp+67h] [rbp-B9h]
char v23; // [rsp+68h] [rbp-B8h]
char v24; // [rsp+69h] [rbp-B7h]
char v25; // [rsp+6Ah] [rbp-B6h]
char v26; // [rsp+6Bh] [rbp-B5h]
char v27; // [rsp+6Ch] [rbp-B4h]
char v28; // [rsp+6Dh] [rbp-B3h]
char v29; // [rsp+6Eh] [rbp-B2h]
char v30; // [rsp+6Fh] [rbp-B1h]
char v31; // [rsp+70h] [rbp-B0h]
char v32; // [rsp+71h] [rbp-AFh]
char v33; // [rsp+72h] [rbp-AEh]
char v34; // [rsp+73h] [rbp-ADh]
char v35; // [rsp+74h] [rbp-ACh]
char v36; // [rsp+75h] [rbp-ABh]
char v37; // [rsp+76h] [rbp-AAh]
char v38; // [rsp+77h] [rbp-A9h]
char v39; // [rsp+78h] [rbp-A8h]
char v40; // [rsp+79h] [rbp-A7h]
char v41; // [rsp+7Ah] [rbp-A6h]
char v42; // [rsp+7Bh] [rbp-A5h]
char v43; // [rsp+7Ch] [rbp-A4h]
char v44; // [rsp+7Dh] [rbp-A3h]
char v45; // [rsp+7Eh] [rbp-A2h]
char v46; // [rsp+7Fh] [rbp-A1h]
char v47; // [rsp+80h] [rbp-A0h]
char v48; // [rsp+81h] [rbp-9Fh]
char v49; // [rsp+82h] [rbp-9Eh]
char v50; // [rsp+83h] [rbp-9Dh]
char input[32]; // [rsp+90h] [rbp-90h]
int v52; // [rsp+B0h] [rbp-70h] 数组
char v53; // [rsp+B4h] [rbp-6Ch]
char v54; // [rsp+C0h] [rbp-60h]
char v55; // [rsp+E7h] [rbp-39h]
char v56; // [rsp+100h] [rbp-20h]
unsigned __int64 v57; // [rsp+108h] [rbp-18h]
v57 = __readfsqword(0x28u);
v15 = 73;
v16 = 111;
v17 = 100;
v18 = 108;
v19 = 62;
v20 = 81;
v21 = 110;
v22 = 98;
v23 = 40;
v24 = 111;
v25 = 99;
v26 = 121;
v27 = 127;
v28 = 121;
v29 = 46;
v30 = 105;
v31 = 127;
v32 = 100;
v33 = 96;
v34 = 51;
v35 = 119;
v36 = 125;
v37 = 119;
v38 = 101;
v39 = 107;
v40 = 57;
v41 = 123;
v42 = 105;
v43 = 121;
v44 = 61;
v45 = 126;
v46 = 121;
v47 = 76;
v48 = 64;
v49 = 69;
v50 = 67;
memset(input, 0, sizeof(input));
v52 = 0;
v53 = 0;
sub_4406E0(0LL, (__int64)input);
v53 = 0;
LODWORD(v0) = sub_424BA0((const __m128i *)input);
if ( v0 == 36 )
{
for ( i = 0; ; ++i )
{
LODWORD(v2) = sub_424BA0((const __m128i *)input);
if ( i >= v2 )
break;
if ( (unsigned __int8)(input[i] ^ i) != *(&v15 + i) )// input[i]^i = v15[i]
{
result = 4294967294LL;
goto LABEL_13;
}
}
printf("continue!");
memset(&v54, 0, 0x40uLL);
v56 = 0;
sub_4406E0(0LL, (__int64)&v54);
v55 = 0;
LODWORD(v3) = sub_424BA0((const __m128i *)&v54);
if ( v3 == 39 )
{
v4 = (const __m128i *)base_64((const __m128i *)&v54);
v5 = (const __m128i *)base_64(v4);
v6 = (const __m128i *)base_64(v5);
v7 = (const __m128i *)base_64(v6);
v8 = (const __m128i *)base_64(v7);
v9 = (const __m128i *)base_64(v8);
v10 = (const __m128i *)base_64(v9);
v11 = (const __m128i *)base_64(v10);
v12 = (const __m128i *)base_64(v11);
final = base_64(v12); // 进行10次base64加密
if ( !(unsigned int)sub_400360(final, (__int64)off_6CC090) )// final = Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJ
{
printf("You found me!!!");
printf("bye bye~");
}
result = 0LL;
}
else
{
result = 4294967293LL;
}
}
else
{
result = 0xFFFFFFFFLL;
}
LABEL_13:
if ( __readfsqword(0x28u) != v57 )
sub_444020();
return result;
}
首先看这里,v15是初始化过的数组,要求输入的字符串经过抑或处理等于v15。
写脚本
a=[73,111,100,108,62,81,110,98,40,111,99,121,127,121,46,105,127,100,96,51,119,125,119,101,107,57,123,105,121,61,126,121,76,64,69,67]
input = ''
for i in range(len(a)):
input += chr(a[i]^i)
print(input)
Info:The first four chars are `flag`
知道了前四个字符是flag。
然后再看下面这段,进去看过后发现是base64加密,并且加密10次。加密后的结果在off_6CC090里。写脚本解密。
import base64
a = 'Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xVmpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWxob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZSR1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1dsWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1ExWlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGSnJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSllUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnRlRXRXTVZaSFVsUnNVVlZVTURrPQ=='
for i in range(10):
a = base64.b64decode(a).decode("utf-8") #必须先转码成byte型,因为python3中字符都为unicode编码,但是b64encode函数的参数为byte类型
print(a)
https://bbs.pediy.com/thread-254172.htm
解出来是个网站。进去是啥都不懂。。。就看wp,发现被骗了。。回到刚才的地方,下面仍有些数据。查看调用这段数据的函数。
unsigned __int64 __fastcall sub_400D35(__int64 a1, __int64 a2)
{
__int64 v2; // rdx
__int64 v3; // rdx
__int64 v4; // rdx
unsigned __int64 result; // rax
unsigned __int64 v6; // rt1
unsigned int v7; // [rsp+Ch] [rbp-24h]
signed int i; // [rsp+10h] [rbp-20h]
signed int j; // [rsp+14h] [rbp-1Ch]
unsigned int key; // [rsp+24h] [rbp-Ch]
unsigned __int64 v11; // [rsp+28h] [rbp-8h]
v11 = __readfsqword(0x28u);
v7 = sub_43FD20() - qword_6CEE38; // v7 = 201(D) -
for ( i = 0; i <= 1233; ++i )
{
sub_40F790(v7);
sub_40FE60(v7, a2, v2);
sub_40FE60(v7, a2, v3);
v7 = (unsigned __int64)sub_40FE60(v7, a2, v4) ^ 0x98765432;
}
key = v7; // 猜测v4的前四位和这玩意儿抑或就是flag
if ( ((unsigned __int8)v7 ^ byte_6CC0A0[0]) == 'f' && (HIBYTE(key) ^ (unsigned __int8)byte_6CC0A3) == 'g' )
{
for ( j = 0; j <= 24; ++j )
sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&key + j % 4)));
}
v6 = __readfsqword(0x28u);
result = v6 ^ v11;
if ( v6 != v11 )
sub_444020();
return result;
}
查看调用,是在fini段调用了这个函数,程序结束的时候会运行。
问题就在这个函数了。。。而关键程序段是这个。
故猜测,v7和byte_6CC0A0数组前四位抑或=‘flag’。正好验证了开始第一步的结果。同时,发现for循环中只调用了v7的前四位,所以只需求出v7的前四位即可,其他的不用管。
同时将for循环里面代码复现一下。
arr = [0x40, 0x35, 0x20, 0x56]
v7 = ''
res = 'flag'
for i in range(4):
v7 += chr(ord(res[i])^arr[i])
a = [0x40,
0x35,
0x20,
0x56,
0x5D,
0x18,
0x22,
0x45,
0x17,
0x2F,
0x24,
0x6E,
0x62,
0x3C,
0x27,
0x54,
0x48,
0x6C,
0x24,
0x6E,
0x72,
0x3C,
0x32,
0x45,
0x5B,]
flag = ''
for i in range(25):
flag += chr(a[i]^ord(v7[i%4]))
print(flag)
flag{Act1ve_Defen5e_Test}
就得到flag了。