首页
社区
课程
招聘
[原创]KCTF 2019 Q2 Writeup
发表于: 2019-6-27 06:56 5927

[原创]KCTF 2019 Q2 Writeup

2019-6-27 06:56
5927
1、通过MessageBox提示字符串可以定位到关键代码,需要注意的是真正的校验代码是通过 0x00401F8A 处的指令    rep movsd  拷贝到0x4010E0的
.text:00401EEB 8D 85 F0 FC FF FF                       lea     eax, [ebp+String]
.text:00401EF1 50                                      push    eax             ; lpString
.text:00401EF2 68 E8 03 00 00                          push    3E8h            ; nIDDlgItem
.text:00401EF7 8B CE                                   mov     ecx, esi        ; this
.text:00401EF9 E8 17 75 00 00                          call    ?GetDlgItemTextW@CWnd@@QBEHHPA_WH@Z ; CWnd::GetDlgItemTextW(int,wchar_t *,int)
.text:00401EFE 8D 85 F0 FC FF FF                       lea     eax, [ebp+String]
.text:00401F04 8D 50 02                                lea     edx, [eax+2]
.text:00401F07
.text:00401F07                         loc_401F07:                             ; CODE XREF: onButtonCliked+70j
.text:00401F07 66 8B 08                                mov     cx, [eax]
.text:00401F0A 83 C0 02                                add     eax, 2
.text:00401F0D 66 85 C9                                test    cx, cx
.text:00401F10 75 F5                                   jnz     short loc_401F07
.text:00401F12 2B C2                                   sub     eax, edx
.text:00401F14 D1 F8                                   sar     eax, 1
.text:00401F16 83 F8 10                                cmp     eax, 10h
.text:00401F19 0F 85 BB 00 00 00                       jnz     loc_401FDA      ; 长度要等于0x10
.text:00401F1F 33 C0                                   xor     eax, eax
.text:00401F21
.text:00401F21                         loc_401F21:                             ; CODE XREF: onButtonCliked+A6j
.text:00401F21 B9 00 FF 00 00                          mov     ecx, 0FF00h
.text:00401F26 66 85 8C 45 F0 FC FF FF                 test    [ebp+eax*2+String], cx
.text:00401F2E 0F 85 A6 00 00 00                       jnz     loc_401FDA
.text:00401F34 8A 94 45 F0 FC FF FF                    mov     dl, byte ptr [ebp+eax*2+String]
.text:00401F3B 88 94 05 F0 FE FF FF                    mov     [ebp+eax+var_110], dl
.text:00401F42 40                                      inc     eax
.text:00401F43 83 F8 10                                cmp     eax, 10h
.text:00401F46 7C D9                                   jl      short loc_401F21
.text:00401F48 8B 1D 10 D2 51 00                       mov     ebx, ds:VirtualProtect
.text:00401F4E 8D 45 FC                                lea     eax, [ebp+flOldProtect]
.text:00401F51 50                                      push    eax             ; lpflOldProtect
.text:00401F52 6A 40                                   push    40h             ; flNewProtect
.text:00401F54 68 17 0D 00 00                          push    0D17h           ; dwSize
.text:00401F59 68 E0 10 40 00                          push    offset sub_4010E0 ; lpAddress
.text:00401F5E C7 45 F0 40 00 00 00                    mov     [ebp+var_10], 40h
.text:00401F65 C7 45 FC 00 00 00 00                    mov     [ebp+flOldProtect], 0
.text:00401F6C FF D3                                   call    ebx ; VirtualProtect
.text:00401F6E FF 15 08 D4 51 00                       call    ds:GetLastError
.text:00401F74 85 C0                                   test    eax, eax
.text:00401F76 75 62                                   jnz     short loc_401FDA
.text:00401F78 8B 55 FC                                mov     edx, [ebp+flOldProtect]
.text:00401F7B B9 CC 00 00 00                          mov     ecx, 0CCh
.text:00401F80 BE B8 47 56 00                          mov     esi, offset byte_5647B8
.text:00401F85 BF E0 10 40 00                          mov     edi, offset sub_4010E0
.text:00401F8A F3 A5                                   rep movsd                                           拷贝真正的校验代码到0x4010E0
.text:00401F8C 8D 4D F0                                lea     ecx, [ebp+var_10]
.text:00401F8F 51                                      push    ecx             ; lpflOldProtect
.text:00401F90 52                                      push    edx             ; flNewProtect
.text:00401F91 68 17 0D 00 00                          push    0D17h           ; dwSize
.text:00401F96 68 E0 10 40 00                          push    offset sub_4010E0 ; lpAddress
.text:00401F9B FF D3                                   call    ebx ; VirtualProtect
.text:00401F9D FF 15 08 D4 51 00                       call    ds:GetLastError
.text:00401FA3 85 C0                                   test    eax, eax
.text:00401FA5 75 30                                   jnz     short loc_401FD7
.text:00401FA7 89 45 F8                                mov     [ebp+var_8], eax
.text:00401FAA 8D 85 F0 FE FF FF                       lea     eax, [ebp+var_110]
.text:00401FB0 50                                      push    eax
.text:00401FB1 E8 2A F1 FF FF                          call    sub_4010E0                       进入校验
.text:00401FB6 89 45 F8                                mov     [ebp+var_8], eax
.text:00401FB9 83 7D F8 01                             cmp     [ebp+var_8], 1
.text:00401FBD 75 18                                   jnz     short loc_401FD7
.text:00401FBF 8B 4D F4                                mov     ecx, [ebp+var_C] ; this
.text:00401FC2 6A 00                                   push    0               ; unsigned int
.text:00401FC4 6A 00                                   push    0               ; lpCaption
.text:00401FC6 68 10 57 54 00                          push    offset Text     ; "Congratulations! You are right!"
.text:00401FCB E8 55 92 00 00                          call    ?MessageBoxW@CWnd@@QAEHPB_W0I@Z ; CWnd::MessageBoxW(wchar_t const *,wchar_t const *,uint)
.text:00401FD0 5F                                      pop     edi

.text:00401EEB 8D 85 F0 FC FF FF                       lea     eax, [ebp+String]
.text:00401EF1 50                                      push    eax             ; lpString
.text:00401EF2 68 E8 03 00 00                          push    3E8h            ; nIDDlgItem
.text:00401EF7 8B CE                                   mov     ecx, esi        ; this
.text:00401EF9 E8 17 75 00 00                          call    ?GetDlgItemTextW@CWnd@@QBEHHPA_WH@Z ; CWnd::GetDlgItemTextW(int,wchar_t *,int)
.text:00401EFE 8D 85 F0 FC FF FF                       lea     eax, [ebp+String]
.text:00401F04 8D 50 02                                lea     edx, [eax+2]
.text:00401F07
.text:00401F07                         loc_401F07:                             ; CODE XREF: onButtonCliked+70j
.text:00401F07 66 8B 08                                mov     cx, [eax]
.text:00401F0A 83 C0 02                                add     eax, 2
.text:00401F0D 66 85 C9                                test    cx, cx
.text:00401F10 75 F5                                   jnz     short loc_401F07
.text:00401F12 2B C2                                   sub     eax, edx
.text:00401F14 D1 F8                                   sar     eax, 1
.text:00401F16 83 F8 10                                cmp     eax, 10h
.text:00401F19 0F 85 BB 00 00 00                       jnz     loc_401FDA      ; 长度要等于0x10
.text:00401F1F 33 C0                                   xor     eax, eax
.text:00401F21
.text:00401F21                         loc_401F21:                             ; CODE XREF: onButtonCliked+A6j
.text:00401F21 B9 00 FF 00 00                          mov     ecx, 0FF00h
.text:00401F26 66 85 8C 45 F0 FC FF FF                 test    [ebp+eax*2+String], cx
.text:00401F2E 0F 85 A6 00 00 00                       jnz     loc_401FDA
.text:00401F34 8A 94 45 F0 FC FF FF                    mov     dl, byte ptr [ebp+eax*2+String]
.text:00401F3B 88 94 05 F0 FE FF FF                    mov     [ebp+eax+var_110], dl
.text:00401F42 40                                      inc     eax
.text:00401F43 83 F8 10                                cmp     eax, 10h
.text:00401F46 7C D9                                   jl      short loc_401F21
.text:00401F48 8B 1D 10 D2 51 00                       mov     ebx, ds:VirtualProtect
.text:00401F4E 8D 45 FC                                lea     eax, [ebp+flOldProtect]
.text:00401F51 50                                      push    eax             ; lpflOldProtect
.text:00401F52 6A 40                                   push    40h             ; flNewProtect
.text:00401F54 68 17 0D 00 00                          push    0D17h           ; dwSize
.text:00401F59 68 E0 10 40 00                          push    offset sub_4010E0 ; lpAddress
.text:00401F5E C7 45 F0 40 00 00 00                    mov     [ebp+var_10], 40h
.text:00401F65 C7 45 FC 00 00 00 00                    mov     [ebp+flOldProtect], 0
.text:00401F6C FF D3                                   call    ebx ; VirtualProtect
.text:00401F6E FF 15 08 D4 51 00                       call    ds:GetLastError
.text:00401F74 85 C0                                   test    eax, eax
.text:00401F76 75 62                                   jnz     short loc_401FDA
.text:00401F78 8B 55 FC                                mov     edx, [ebp+flOldProtect]
.text:00401F7B B9 CC 00 00 00                          mov     ecx, 0CCh
.text:00401F80 BE B8 47 56 00                          mov     esi, offset byte_5647B8
.text:00401F85 BF E0 10 40 00                          mov     edi, offset sub_4010E0
.text:00401F8A F3 A5                                   rep movsd                                           拷贝真正的校验代码到0x4010E0
.text:00401F8C 8D 4D F0                                lea     ecx, [ebp+var_10]
.text:00401F8F 51                                      push    ecx             ; lpflOldProtect
.text:00401F90 52                                      push    edx             ; flNewProtect
.text:00401F91 68 17 0D 00 00                          push    0D17h           ; dwSize
.text:00401F96 68 E0 10 40 00                          push    offset sub_4010E0 ; lpAddress
.text:00401F9B FF D3                                   call    ebx ; VirtualProtect
.text:00401F9D FF 15 08 D4 51 00                       call    ds:GetLastError
.text:00401FA3 85 C0                                   test    eax, eax
.text:00401FA5 75 30                                   jnz     short loc_401FD7
.text:00401FA7 89 45 F8                                mov     [ebp+var_8], eax
.text:00401FAA 8D 85 F0 FE FF FF                       lea     eax, [ebp+var_110]
.text:00401FB0 50                                      push    eax
.text:00401FB1 E8 2A F1 FF FF                          call    sub_4010E0                       进入校验
.text:00401FB6 89 45 F8                                mov     [ebp+var_8], eax
.text:00401FB9 83 7D F8 01                             cmp     [ebp+var_8], 1
.text:00401FBD 75 18                                   jnz     short loc_401FD7
.text:00401FBF 8B 4D F4                                mov     ecx, [ebp+var_C] ; this
.text:00401FC2 6A 00                                   push    0               ; unsigned int
.text:00401FC4 6A 00                                   push    0               ; lpCaption
.text:00401FC6 68 10 57 54 00                          push    offset Text     ; "Congratulations! You are right!"
.text:00401FCB E8 55 92 00 00                          call    ?MessageBoxW@CWnd@@QAEHPB_W0I@Z ; CWnd::MessageBoxW(wchar_t const *,wchar_t const *,uint)
.text:00401FD0 5F                                      pop     edi

2、校验代码还原
     1)、对16字节的序列号进行异或运算
char key[16] = { 0x16,0x96,0x8C,0xE3,0x81,0x98,0x6E,0x64,0x84,0x08,0xDC,0x81,0xBE,0x4D,0x48,0x4F };

char* xorSerial(char serial[16])
{
	char *resultSerial = new char[16];

	for (int i = 0; i < 8; i++)
	{
		resultSerial[i] = key[i] ^ serial[i];
		resultSerial[i + 8] = key[i + 8] ^ serial[i + 8];
	}

	return resultSerial;
}

     2)、对异或后的结果进行检查:第7和第15字节不能为0,且第7字节的高4位必须为0
bool check(char *serial)
{
	if (serial[7] == 0 || serial[15] == 0)
	{
		return false;
	}

	if (serial[7] & 0xF0)
	{
		return false;
	}

	return true;
}

       3)、把序列号拆成两段,前8个字节为第一段设为x,后8个字节为第二段设为y;最后可得方程:x^2 - 7y^2 = 8

               不过最后不会解这个方程
char key[16] = { 0x16,0x96,0x8C,0xE3,0x81,0x98,0x6E,0x64,0x84,0x08,0xDC,0x81,0xBE,0x4D,0x48,0x4F };

char* xorSerial(char serial[16])
{
	char *resultSerial = new char[16];

	for (int i = 0; i < 8; i++)
	{
		resultSerial[i] = key[i] ^ serial[i];
		resultSerial[i + 8] = key[i + 8] ^ serial[i + 8];
	}

	return resultSerial;
}

     2)、对异或后的结果进行检查:第7和第15字节不能为0,且第7字节的高4位必须为0
bool check(char *serial)
{
	if (serial[7] == 0 || serial[15] == 0)
	{
		return false;
	}

	if (serial[7] & 0xF0)
	{
		return false;
	}

	return true;
}

bool check(char *serial)
{
	if (serial[7] == 0 || serial[15] == 0)
	{
		return false;
	}

	if (serial[7] & 0xF0)
	{
		return false;
	}

	return true;
}

       3)、把序列号拆成两段,前8个字节为第一段设为x,后8个字节为第二段设为y;最后可得方程:x^2 - 7y^2 = 8

               不过最后不会解这个方程

1、随便输入一个字符串提示:“Please Try Again”,通过字符串搜索找到关键代码
.text:00401622 ; int __cdecl main(int argc, char **argv)
.text:00401622                 public _main
.text:00401622 _main           proc near               ; CODE XREF: ___mingw_CRTStartup+F8p
.text:00401622
.text:00401622 argc            = dword ptr  8
.text:00401622 argv            = dword ptr  0Ch
.text:00401622
.text:00401622                 push    ebp
.text:00401623                 mov     ebp, esp
.text:00401625                 and     esp, 0FFFFFFF0h
.text:00401628                 sub     esp, 50h
.text:0040162B                 call    ___main
.text:00401630                 mov     dword ptr [esp], offset aPleaseEnterSer ; "please enter Serial:"
.text:00401637                 call    _printf
.text:0040163C                 lea     eax, [esp+11h]
.text:00401640                 mov     [esp+4], eax
.text:00401644                 mov     dword ptr [esp], offset aS ; " %s"
.text:0040164B                 call    _scanf                                                   读取输入的字符串
.text:00401650                 lea     eax, [esp+11h]
.text:00401654                 mov     [esp], eax      ; char *
.text:00401657                 call    _strlen
.text:0040165C                 cmp     eax, 31h
.text:0040165F                 jbe     short loc_40166D                                
.text:00401661                 mov     dword ptr [esp], offset aError ; "error"          字符串长度大于0x31,则错误
.text:00401668                 call    _puts
.text:0040166D
.text:0040166D loc_40166D:                             ; CODE XREF: _main+3Dj
.text:0040166D                 mov     dword ptr [esp+4], 400h ; size_t
.text:00401675                 mov     dword ptr [esp], 1 ; size_t
.text:0040167C                 call    _calloc
.text:00401681                 mov     [esp+4Ch], eax
.text:00401685                 lea     eax, [esp+11h]
.text:00401689                 mov     [esp], eax      ; char *
.text:0040168C                 call    _strlen
.text:00401691                 mov     [esp+8], eax    ; binlength
.text:00401695                 mov     eax, [esp+4Ch]
.text:00401699                 mov     [esp+4], eax    ; base64
.text:0040169D                 lea     eax, [esp+11h]
.text:004016A1                 mov     [esp], eax      ; bindata
.text:004016A4                 call    _base64_encode                                         字符串进行base64编码
.text:004016A9                 mov     dword ptr [esp+48h], offset aNgvH1f4s32pHkq ; "!NGV%,$h1f4S3%2P(hkQ94=="
.text:004016B1                 mov     eax, [esp+4Ch]
.text:004016B5                 mov     [esp+4], eax    ; char *
.text:004016B9                 mov     eax, [esp+48h]
.text:004016BD                 mov     [esp], eax      ; char *
.text:004016C0                 call    _strcmp                               编码后的base字符串与!NGV%,$h1f4S3%2P(hkQ94==比较,相等则成功                         
.text:004016C5                 test    eax, eax
.text:004016C7                 jnz     short loc_4016D7
.text:004016C9                 mov     dword ptr [esp], offset aSuccess ; "Success"
.text:004016D0                 call    _puts
.text:004016D5                 jmp     short loc_4016E3
.text:004016D7 ; ---------------------------------------------------------------------------
.text:004016D7
.text:004016D7 loc_4016D7:                             ; CODE XREF: _main+A5j
.text:004016D7                 mov     dword ptr [esp], offset aPleaseTryAgain ; "Please Try Again"
.text:004016DE                 call    _puts
.text:004016E3
.text:004016E3 loc_4016E3:                             ; CODE XREF: _main+B3j
.text:004016E3                 mov     eax, [esp+4Ch]
.text:004016E7                 mov     [esp], eax      ; void *
.text:004016EA                 call    _free
.text:004016EF                 mov     dword ptr [esp], offset aPause ; "pause"
.text:004016F6                 call    _system
.text:004016FB                 mov     eax, 0
.text:00401700                 leave
.text:00401701                 retn


2、还原base64编码代码,编码方法

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

最后于 2019-6-28 11:25 被kanxue编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//