sus-accumulator

题目地址

拖进ida 主函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
__int64 v3; // rbx
char v4; // al
signed __int64 result; // rax
__int64 v6; // [rsp+0h] [rbp-458h]
char v7; // [rsp+3Fh] [rbp-419h]
char input; // [rsp+40h] [rbp-418h]
unsigned __int64 v9; // [rsp+448h] [rbp-10h]

v3 = 0LL;
v9 = __readfsqword(0x28u);
__printf_chk(1LL, "What's your flag? ", a3);
do
{
v4 = _IO_getc(stdin);
if ( v4 == '\n' )
break;
if ( v4 == -1 )
break;
*(&v7 + ++v3) = v4;
}
while ( v3 != 1024 );
if ( SHA512((__int64)&input, v3, (__int64)&v6) )// v6=sha512(input)
{
sub_4008C0((unsigned __int8 *)&v6, 64LL);
sub_4008C0((unsigned __int8 *)&input, v3);
puts("Good flag for you.");
result = 0LL;
}
else
{
puts("error");
result = 1LL;
}
return result;

do~while循环里是读取输入,最多读取1024位,遇到回车符或读取完则停止,很明显if条件必成立,v6=sha512(input),进入sub4008c0函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
if ( a2 )
{
v2 = i + *a1; // i,j初始为0
v3 = v2 == dword_601080[j];
v4 = (unsigned int)(j + 1);
i += *a1;
++j;
if ( !v3 )
{
LABEL_8:
puts("Bad flag :(");
exit(1);
}
v5 = a1 + 1;
v6 = &a1[a2];
while ( v5 != v6 )
{
v7 = *v5++;
v2 += v7;
v3 = v2 == dword_601080[v4];
i = v2;
j = v4 + 1;
if ( !v3 )
goto LABEL_8;
v4 = (unsigned int)(v4 + 1);
}
}

一开始没分析出i和j的作用…对应的地址内存值为????一脸懵逼以为是没看见赋值,后知道了i和j是下标的作用,很容易分析出dword601080处的值就是input累加的结果,也就是说flag和dword601080内存值的位数是相等的,直接根据第二次sub4008c0就可以逆运算出flag,不需要管if条件对v6的操作以及第一次此函数对v6值的校验。然而照这样手动逆运算了前几个值,并没有得到类似于flag开头之类的字符,以为是分析错了,又看了好几遍函数,结果只是flag并不是从头开始……前几位是无意义的字符而已,

首次使用了idc脚本dump下了dword601080处内存,逆运算脚本如下:

1
2
3
4
5
6
a=[195,255,493,584,799,929,946,1086,1180,1184,1421,1595,1805,1846,2081,2320,2430,2605,2727,2972,3213,3403,3418,3649,3712,3950,3989,4193,4228,4394,4523,4624,4706,4935,4999,5072,5106,5291,5510,5536,5644,5751,5993,6118,6126,6198,6211,6410,6469,6609,6647,6752,6978,7010,7053,7106,7274,7468,7563,7673,7706,7956,8146,8187,8257,8333,8398,8469,8592,8640,8693,8742,8793,8844,8901,8953,9007,9062,9113,9161,9215,9317,9374,9429,9483,9540,9591,9644,9692,9741,9792,9846,9944,9996,10045,10144,10195,10246,10294,10350,10402,10450,10551,10652,10750,10849,10946,11045,11096,11147,11202,11304,11353,11451,11507,11605,11653,11753,11852,11900,11951,12052,12105,12161,12259,12360,12409,12461,12563,12664,12718,12775,12823,12921,12970,13020,13071,13173,13227,13276,13374,13422,13521,13569,13667,13718,13771,13873,13972,14029,14080,14179,14278,14377,14432,14482,14531,14579,14627,14679,14732,14789,14840,14894,14951,15052,15154,15210,15263,15314,15363,15460,15509,15610,15666,15763,15818,15916,15968,16018,16075,16132,16233,16288,16386,16443,16543,16600,16655,16703,16801,16858,16955,17005,17056,17153,17250,17375]
b=[195]
for i in range(1,len(a)):
b.append(a[i]-a[i-1])
s=''.join([chr(i)for i in b])
print s

忽略掉前几个无意义字符后出现flag{}

1
2
sH1rkEr:desktop macbook$ python 1.py
?;?&i? +5??_n!??)FLAG{051339467306f9769350136b41c330840eebcac337f1b8b0dc03e58be14fe690b123f61b0c0b35fc93ccc72100459369ef8531a1e8a7b4299e7b9d970b9a23aa}

flag get

文章目录
|