notsequence
打开是EIF文件,直接拖进IDA查看字符串
在这里插入图片描述
反汇编找到main函数

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
int __cdecl main()
{
_DWORD *v0; // eax
int v2; // [esp+14h] [ebp-Ch]
_DWORD *v3; // [esp+1Ch] [ebp-4h]

memset(&unk_8049BE0, 0, 0x4000u);
puts("input raw_flag please:");
v3 = &unk_8049BE0;
do
{
v0 = v3++;
scanf("%d", v0);
}
while ( *(v3 - 1) );
v2 = sub_80486CD(&unk_8049BE0);
if ( v2 == -1 )
{
printf("check1 not pass");
system("pause");
}
if ( (unsigned __int8)sub_8048783(&unk_8049BE0, v2) != 1 )
{
printf("check2 not pass!");
exit(0);
}
if ( v2 == 20 )
{
puts("Congratulations! fl4g is :\nRCTF{md5(/*what you input without space or \\n~*/)}");
exit(0);
}
return 0;
}

首先要满足check1check2sub_80486CDsub_80486CD
最后满足v2 == 20

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
int __cdecl main()
{
_DWORD *v0; // eax
int v2; // [esp+14h] [ebp-Ch]
_DWORD *v3; // [esp+1Ch] [ebp-4h]

memset(&unk_8049BE0, 0, 0x4000u);
puts("input raw_flag please:");
v3 = &unk_8049BE0;
do
{
v0 = v3++;
scanf("%d", v0);
}
while ( *(v3 - 1) );
v2 = sub_80486CD(&unk_8049BE0);
if ( v2 == -1 )
{
printf("check1 not pass");
system("pause");
}
if ( (unsigned __int8)sub_8048783(&unk_8049BE0, v2) != 1 )
{
printf("check2 not pass!");
exit(0);
}
if ( v2 == 20 )
{
puts("Congratulations! fl4g is :\nRCTF{md5(/*what you input without space or \\n~*/)}");
exit(0);
}
return 0;
}

sub_80486CD:第一个for循环,i是求和递增,就是i=0,1,3,6,10….
第二个for循环首先将数组进行分隔,根据上面的i分成a[1],a[2],a[4],a[7]….
再将分隔中间的数字进行相加,v5=0,1,2,3,4…..代表着每一次相加的个数即每个隔间的个数
if判断语句1往左移动0001=1,0010=2,0100=4,1000=8依次类推,v3就代表着每个隔间的和

1
2
3
4
5
6
7
8
9
10
11
v5 = 0;
for ( i = 0; i <= 1024 && *(_DWORD *)(4 * i + a1); i = v5 * (v5 + 1) / 2 )
{
v3 = 0;
for ( j = 0; j <= v5; ++j )
v3 += *(_DWORD *)(4 * (j + i) + a1);
if ( 1 << v5 != v3 )
return -1;
++v5;
}
return v5;

sub_80486CD:a2即上面的v5,a2-1就是去除最后一行把每一列的数字进行相加,if判断是与后一列的最后一个数字相等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
v6 = 0;
for ( i = 1; i < a2; ++i )
{
v4 = 0;
v3 = i - 1;
if ( !*(_DWORD *)(4 * i + a1) )
return 0;
while ( a2 - 1 > v3 )
{
v4 += *(_DWORD *)(4 * (v3 * (v3 + 1) / 2 + v6) + a1);
++v3;
}
if ( *(_DWORD *)(4 * (v3 * (v3 + 1) / 2 + i) + a1) != v4 )
return 0;
++v6;
}
return 1;

杨辉三角简图:
在这里插入图片描述
通过main函数中的v2 == 20可得到需要20层的杨辉三角
写脚本:

1
2
3
4
5
6
7
8
9
10
11
def yanghui(max):
L = [1]
print(L)
n = 0
while n < max:
L.append(0)
L = [L[i-1] + L[i] for i in range(len(L))]
print(L)
n += 1
for l in yanghui(19):
print(l)

运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]
[1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1]
[1, 12, 66, 220, 495, 792, 924, 792, 495, 220, 66, 12, 1]
[1, 13, 78, 286, 715, 1287, 1716, 1716, 1287, 715, 286, 78, 13, 1]
[1, 14, 91, 364, 1001, 2002, 3003, 3432, 3003, 2002, 1001, 364, 91, 14, 1]
[1, 15, 105, 455, 1365, 3003, 5005, 6435, 6435, 5005, 3003, 1365, 455, 105, 15, 1]
[1, 16, 120, 560, 1820, 4368, 8008, 11440, 12870, 11440, 8008, 4368, 1820, 560, 120, 16, 1]
[1, 17, 136, 680, 2380, 6188, 12376, 19448, 24310, 24310, 19448, 12376, 6188, 2380, 680, 136, 17, 1]
[1, 18, 153, 816, 3060, 8568, 18564, 31824, 43758, 48620, 43758, 31824, 18564, 8568, 3060, 816, 153, 18, 1]
[1, 19, 171, 969, 3876, 11628, 27132, 50388, 75582, 92378, 92378, 75582, 50388, 27132, 11628, 3876, 969, 171, 19, 1]

将数字连在一起,进行MD5加密,就得到最终flag
在这里插入图片描述

1
37894beff1c632010dd6d524aa9604db