首页
社区
课程
招聘
[原创]2021 KCTF 春季赛 第四题 英雄救美 wp
2021-5-14 18:50 4963

[原创]2021 KCTF 春季赛 第四题 英雄救美 wp

2021-5-14 18:50
4963

0x0 初步观察

windows32位控制台程序.
输入错误时没有回显.
输入成功的提示是段shellcode, 使用VirtualAlloc分配地址解密shellcode再执行.
观察验证逻辑, 不难发现是个9*9的经典数独游戏.

0x1 详细分析逻辑

ida F5, 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
34
35
36
37
38
39
40
41
42
43
44
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int nLen; // kr00_4
  int v4; // ecx
  __m128i *v5; // esi
  int v6; // edi
  void (*v8)(void); // [esp+10h] [ebp-2C8h]
  int v9[22]; // [esp+14h] [ebp-2C4h] BYREF
  char v10[508]; // [esp+6Ch] [ebp-26Ch] BYREF
  __int128 v11; // [esp+26Ch] [ebp-6Ch] BYREF
  char v12[88]; // [esp+27Ch] [ebp-5Ch] BYREF
 
  printf("\t\t\t看雪CTF大赛\r\n");
  printf("\t\t祝愿看雪CTF大赛越办越好\r\n");
  printf("Serial: ");
  scanf_s("%s", (char *)&v11 + 12);
  nLen = strlen((const char *)&v11 + 12);
  if ( nLen <= 64 && fun_convert_input((int)&v11 + 12, nLen, &v9[21]) == 1 && fun_check_game((int)v10, nLen - 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)v12, (int)v9, nLen);
    sub_4015B0((int)&v11, (int)v9);
    sub_401ED0(v4, (unsigned __int8 *)&v11);
    v8 = (void (*)(void))VirtualAlloc(0, 0x620u, 0x1000u, 0x40u);
    v5 = (__m128i *)v8;
    v6 = 0x62;
    do
    {
      *v5 = _mm_loadu_si128((__m128i *)((char *)v5 + &sub_4181A0 - (_UNKNOWN *)v8));
      ((void (__fastcall *)(char *, __m128i *))loc_4028B0)(v10, v5++);
      --v6;
    }
    while ( v6 );
    v8();
  }
  return 0;
}

输入完serial后, 要执行成功的回显, 必须要满足三个条件:
1.输入length不大于64
2.fun_convert_input(sub_401240)验证通过
3.fun_check_game(sub_401000)验证通过

 

分析fun_convert_input和fun_check_game两个函数的逻辑.

fun_convert_input(sub_401240)

将输入的serial每个字符进行转换.
遇到非数字字符, 查表的第n行(n从1开始)转换对应下标.

1
2
3
4
5
6
7
8
9
$BPV:ubfY
p}]DtN>aT
^MGmJQ#*H
r`O'wjic0
!hdy{oZz-
@n+?&%s_/
g<e[W)XUx
RFSLRA;.l
=CEkvK-(q

遇到数字字符, 验证这行转换了的下标个数加上数字字符是不是等于'9'(满足数独一行有9个数字), 并且切换查表的下一行(n++).

fun_check_game(sub_401000)

把转换好的下标(1~9数字)填入游戏格子内.

验证数独是否成立(每行每列每个九宫格都是数字1~9).

0x2 计算serial

先到网页上在线解数独:链接

每行需要填的数字为:

1
2
3
4
5
6
7
8
9
5619238
18345
76219
7846925
4539786
6928713
28563
61728
1793452

根据fun_convert_input里的字符表进行转换:

1
2
3
4
5
6
7
8
9
:u$YBPf
pa]Dt
#QM^H
ic'j0`w
y{d-Zzo
%/n_s@+
<UW)e
AR;F.
=-qEkvC

每行最后加上数字(9-要填写的数字个数), 最后得到:

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

 

验证通过!

0x3 成功的回显

拿到flag后处于好奇瞅了一眼成功提示的MessageBox代码, 和之前猜测的一样, 是段shellcode.

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
void __cdecl fun_start()
{
  void (__stdcall *pfnMessageBoxA)(_DWORD, char *, char *, _DWORD); // [esp+0h] [ebp-ECh]
  int hUser32; // [esp+4h] [ebp-E8h]
  int (__stdcall *pfnLoadLibraryA)(char *); // [esp+8h] [ebp-E4h]
  int (__stdcall *pfnGetProcAddress)(int, char *); // [esp+Ch] [ebp-E0h]
  int hKernel32; // [esp+10h] [ebp-DCh]
  char szMsg[28]; // [esp+90h] [ebp-5Ch] BYREF
  char szGetProcAddress[16]; // [esp+ACh] [ebp-40h] BYREF
  char szLoadLibraryA[16]; // [esp+BCh] [ebp-30h] BYREF
  char szMessageBoxA[12]; // [esp+CCh] [ebp-20h] BYREF
  char szUser32Dll[12]; // [esp+D8h] [ebp-14h] BYREF
  char szTitle[8]; // [esp+E4h] [ebp-8h] BYREF
 
  hKernel32 = fun_GetKernel32Address();
  strcpy(szGetProcAddress, "GetProcAddress");
  strcpy(szLoadLibraryA, "LoadLibraryA");
  strcpy(szUser32Dll, "user32.dll");
  strcpy(szMessageBoxA, "MessageBoxA");
  pfnGetProcAddress = (int (__stdcall *)(int, char *))fun_GetProcAddress(hKernel32, (int)szGetProcAddress);
  pfnLoadLibraryA = (int (__stdcall *)(char *))pfnGetProcAddress(hKernel32, szLoadLibraryA);
  hUser32 = pfnLoadLibraryA(szUser32Dll);
  pfnMessageBoxA = (void (__stdcall *)(_DWORD, char *, char *, _DWORD))pfnGetProcAddress(hUser32, szMessageBoxA);
  strcpy(szTitle, "message");
  strcpy(szMsg, "You Input The Right Key!");
  pfnMessageBoxA(0, szMsg, szTitle, 0);
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回