7

[原创]KCTF2021 春季赛 第四题 英雄救美 WP

 3 years ago
source link: https://bbs.pediy.com/thread-267614.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
[原创]KCTF2021 春季赛 第四题 英雄救美 WP-CTF对抗-看雪论坛-安全社区|安全招聘|bbs.pediy.com
[原创]KCTF2021 春季赛 第四题 英雄救美 WP
3天前 695

main函数伪代码如下:

int __cdecl main(int argc, const char **argv, const char **envp)
{
int len; // kr00_4
int v4; // ecx
char *v5; // esi
int v6; // edi
void (*v8)(void); // [esp+Ch] [ebp-2CCh]
int v9[22]; // [esp+10h] [ebp-2C8h] BYREF
int solve[128]; // [esp+68h] [ebp-270h] BYREF
__int128 v11; // [esp+268h] [ebp-70h] BYREF
char serial[92]; // [esp+278h] [ebp-60h] BYREF
printf("\t\t\t看雪CTF大赛\r\n");
printf("\t\t祝愿看雪CTF大赛越办越好\r\n");
printf("Serial: ");
scanf_s("%s", serial);
len = strlen(serial);
// 先检查序列号是否合法,检测合法则转换成数独的解,然后开始填数独
if ( len <= 64 && serial2solve(len, serial, solve) == 1 && sudoku((int)solve, len - 9) == 1 )
{
v11 = 0i64;
memset(v9, 0, sizeof(v9));
v9[5] = 0;
v9[4] = 0;
v9[0] = 0x67452301;
v9[1] = 0xEFCDAB89;
v9[2] = 0x98BADCFE;
v9[3] = 0x10325476;
sub_4014E0((int)serial, (int)v9, len);      // 计算serial的hash,解密shellcode
sub_4015B0((int)&v11, (int)v9);
sub_401ED0(v4, (unsigned __int8 *)&v11);
v8 = (void (*)(void))VirtualAlloc(0, 0x620u, 0x1000u, 0x40u);
v5 = (char *)v8;
v6 = 98;
do
{
*(__m128i *)v5 = _mm_loadu_si128((const __m128i *)&v5[&unk_4181A0 - (_UNKNOWN *)v8]);
sub_4028B0((int)solve, v5);
v5 += 16;
--v6;
}
while ( v6 );
v8();
}
return 0;
}

从sudoku函数内可以提取到数独

0,4,0,7,0,0,0,0,0
9,2,0,0,0,0,6,0,7
8,3,0,0,0,5,4,0,0
0,1,0,0,0,3,0,0,0
0,0,0,2,0,1,0,0,0
0,0,0,5,0,0,0,4,0
0,0,4,9,0,0,0,7,1
3,0,5,0,0,0,0,9,4
0,0,0,0,0,8,0,6,0
//懒得解(不会解)数独,直接求助度娘解出来
5,4,6,7,1,9,2,3,8
9,2,1,8,3,4,6,5,7
8,3,7,6,2,5,4,1,9
7,1,8,4,6,3,9,2,5
4,5,3,2,9,1,7,8,6
6,9,2,5,8,7,1,4,3
2,8,4,9,5,6,3,7,1
3,6,5,1,7,2,8,9,4
1,7,9,3,4,8,5,6,2

sudoku函数只在数值为0处填充解,所以把0处的解提取出来

[(5, 6, 1, 9, 2, 3, 8), (1, 8, 3, 4, 5), (7, 6, 2, 1, 9), (7, 8, 4, 6, 9, 2, 5), (4, 5, 3, 9, 7, 8, 6), (6, 9, 2, 8, 7, 1, 3), (2, 8, 5, 6, 3), (6, 1, 7, 2, 8), (1, 7, 9, 3, 4, 5, 2)]

再看serial2solve函数

int __usercall serial2solve@<eax>(int len@<edx>, char *serial@<ecx>, int *solve)
{
int decnum; // ebx
int v4; // esi
unsigned int y; // edi
char chr; // al
signed int v7; // ecx
int v9; // ecx
char *v10; // [esp+0h] [ebp-64h]
int v11; // [esp+4h] [ebp-60h]
__int128 strtable[5]; // [esp+Ch] [ebp-58h]
char v14; // [esp+5Ch] [ebp-8h]
strtable[0] = (__int128)_mm_load_si128((const __m128i *)&xmmword_416280);
decnum = 0;
strtable[1] = (__int128)_mm_load_si128((const __m128i *)&xmmword_4162A0);
v4 = 0;
v11 = len;
v10 = serial;
v14 = 113;
strtable[2] = (__int128)_mm_load_si128((const __m128i *)&xmmword_416270);
strtable[3] = (__int128)_mm_load_si128((const __m128i *)&xmmword_416290);
strtable[4] = (__int128)_mm_load_si128((const __m128i *)&xmmword_416260);
if ( len <= 0 )
return 1;
y = 0;
while ( 1 )
{
chr = serial[v4];
if ( chr > '0' && chr <= '9' )
break;
v7 = y;                                     // 可以当成strtable的纵坐标
if ( y >= 81 )
return 0;
while ( chr != *((_BYTE *)strtable + v7) )
{
if ( (unsigned int)++v7 >= 81 )
return 0;
}
v9 = v7 % 9 + 1;                            // 将strtable的横坐标+1,写到数独的解
if ( v9 == -1 )
return 0;
*solve = v9;
serial = v10;
++decnum;
++solve;
len = v11;
LABEL_13:
if ( ++v4 >= len )
return 1;
}
if ( decnum + chr == '9' )                    // 猜测serial每填满一行数独后就跟一位数字表示没填到的数独的个数
{
decnum = 0;
y += 9;
goto LABEL_13;
}
return -1;
}

清楚序列号转数独解的过程后,撸一份python解出flag即可

resultarr=[(5, 6, 1, 9, 2, 3, 8), (1, 8, 3, 4, 5), (7, 6, 2, 1, 9), (7, 8, 4, 6, 9, 2, 5), (4, 5, 3, 9, 7, 8, 6), (6, 9, 2, 8, 7, 1, 3), (2, 8, 5, 6, 3), (6, 1, 7, 2, 8), (1, 7, 9, 3, 4, 5, 2)]
table="""$BPV:ubfYp}]DtN>aT^MGmJQ#*Hr`O'wjic0!hdy{oZz-@n+?&%s_/g<e[W)XUxRFSLRA;.l=CEkvK-(q"""
flag=''
for i in range(len(resultarr)):
for j in range(len(resultarr[i])):
flag+=table[9*i+resultarr[i][j]-1]
if len(resultarr[i])-1==j:
flag+=chr(0x39-j-1)
print(flag)

运行得到flag(下面整行都是)

:u$YBPf2pa]Dt4#QM^H4ic'j0`w2y{d-Zzo2%/n_s@+2<UW)e4AR;F.4=-qEkvC2

吐槽:目前的flag都不是KCTF{}格式

第五届安全开发者峰会(SDC 2021)议题征集正式开启!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK