-
-
[原创]看雪CTF2016第二十六题分析
-
发表于: 2016-12-25 10:11 2917
-
验证过程主要是通过两次异或处理对一段代码数据进行解密,然后再跳转到该代码执行,解密正确则成功,不正确则失败
004015E9 . F3:A5 rep movs dword ptr es:[edi], dword ptr [esi] ; SN输入长度超过10B会执行到这里,将SN拷贝到栈中
004015EB . 8BCA mov ecx, edx
004015ED . 33D2 xor edx, edx
004015EF . 83E1 03 and ecx, 3
004015F2 . 85ED test ebp, ebp
004015F4 . F3:A4 rep movs byte ptr es:[edi], byte ptr [esi]
004015F6 . 7E 17 jle short 0040160F
004015F8 > 8A4C14 18 mov cl, byte ptr [esp+edx+18] ; 依次取出SN中1B(共11B)
004015FC . 33C0 xor eax, eax
004015FE > 3088 20304000 xor byte ptr [eax+403020], cl ; 与403020中的20B进行异或
00401604 . 40 inc eax
00401605 . 83F8 14 cmp eax, 14 ; 内循环次数20
00401608 .^ 7C F4 jl short 004015FE
0040160A . 42 inc edx
0040160B . 3BD5 cmp edx, ebp ; 外循环次数11
0040160D .^ 7C E9 jl short 004015F8
异或前403020缓存中的初始状态,注意在00403034的字符串“成功”,在后面求取的时候会用到
00403020 CC AA BD DD CB BA B2 92 AF BA B4 B9 B0 AC CB BA 酞捷撕矑垂艾撕
00403030 CE D0 DF DD B3 C9 B9 A6 00 00 00 00 00 00 00 00 涡咻成功........
0040160F > \C74424 10 000>mov dword ptr [esp+10], 0
00401617 . FF15 08204000 call dword ptr [<&KERNEL32.GetCurrentProcessId>>; [GetCurrentProcessId
0040161D . 50 push eax ; /ProcessId
0040161E . 6A 00 push 0 ; |Inheritable = FALSE
00401620 . 68 FF0F1F00 push 1F0FFF ; |Access = PROCESS_ALL_ACCESS
00401625 . FF15 04204000 call dword ptr [<&KERNEL32.OpenProcess>] ; \打开自身进程
0040162B . 8BF8 mov edi, eax
0040162D . 8D4424 10 lea eax, dword ptr [esp+10]
00401631 . 50 push eax ; /pBytesRead
00401632 . 8D4C24 1C lea ecx, dword ptr [esp+1C] ; |
00401636 . 6A 2C push 2C ; |BytesToRead = 2C (44.)
00401638 . 51 push ecx ; |Buffer
00401639 . 68 40154000 push 00401540 ; |pBaseAddress = 401540
0040163E . 57 push edi ; |hProcess
0040163F . FF15 14204000 call dword ptr [<&KERNEL32.ReadProcessMemory>] ; \读取401540处的0x2C=44B
00401645 . 85C0 test eax, eax
00401647 . 74 4D je short 00401696
00401540中44B:
00401540 AE C5 AC F0 F4 84 C4 AC F0 F4 84 C4 AE C4 3B D1 魟默痿勀;?
00401550 30 E5 84 C4 4F 88 E0 C0 AC 2C C7 C4 C4 2C 4C C7 0鍎腛堗垃,悄?L?
00401560 C4 C4 AE C4 4F 0C 2C BD C7 C4 C4 07 哪O.,角哪悙悙
每次从00403020中取出1B(共20B),与0x5E相乘,再与00401540中的44B依次进行异或,更新结果,并将结果写到00401540处
00401649 . 33F6 xor esi, esi
0040164B > 8A86 20304000 mov al, byte ptr [esi+403020] ; 读取403020中的1B
00401651 . B2 5E mov dl, 5E
00401653 . 33C9 xor ecx, ecx
00401655 . F6EA imul dl ; 与0x5E相乘
00401657 > 8A540C 18 mov dl, byte ptr [esp+ecx+18] ; 与00401540中的44B依次进行异或
0040165B . 32D0 xor dl, al ;
0040165D . 88540C 18 mov byte ptr [esp+ecx+18], dl ; 保存结果
00401661 . 41 inc ecx
00401662 . 83F9 2C cmp ecx, 2C ; 内循环次数44
00401665 .^ 7C F0 jl short 00401657 ;
00401667 . 46 inc esi
00401668 . 83FE 14 cmp esi, 14 ; 外循环次数20
0040166B .^ 7C DE jl short 0040164B
0040166D . 8D4424 10 lea eax, dword ptr [esp+10]
00401671 . 8D4C24 18 lea ecx, dword ptr [esp+18]
00401675 . 50 push eax ; /pBytesWritten
00401676 . 6A 2C push 2C ; |BytesToWrite = 2C (44.)
00401678 . 51 push ecx ; |Buffer
00401679 . 68 40154000 push 00401540 ; |Address = 401540
0040167E . 57 push edi ; |hProcess
0040167F . FF15 00204000 call dword ptr [<&KERNEL32.WriteProcessMem> ; \将异或结果写回到00401540
00401685 . 85C0 test eax, eax
00401687 . 74 0D je short 00401696
00401689 . 8B5424 14 mov edx, dword ptr [esp+14]
0040168D . 52 push edx
0040168E . E8 ADFEFFFF call 00401540 ; 然后执行00401540处的代码
SN的11B自身进行异或得到 A
A与403020的20B进行异或得到序列 SB
SB中20B分别与0x5E相乘后再自身进行异或得到 C
C与00401540中44B进行异或,最终得到正确的执行代码
分析清楚两次异或处理过程后,就是对正确解密代码的求取,首先利用00403034的字符串“成功”,猜想解密正确的代码会用到这个字符串来进行信息提示
可以求出C的取值为0xC4,同时得到正确解密的代码如下:
0012F73C 3468016A jh4
0012F740 68004030 0@.h
0012F744 00403034 40@. 27_Crack.00403034
0012F748 15FF006A j.
0012F74C 004021F4 ?@. <&USER32.MessageBoxA>
0012F750 04244C8B 婰$
0012F754 0003E868 h?.
0012F758 0388E800 .鑸
0012F75C 006A0000 ..j.
0012F760 79E8C88B 嬋鑩
0012F73C 6A 01 push 1
0012F73E 68 34304000 push 403034
0012F743 68 34304000 push 403034
0012F748 6A 00 push 0
0012F74A FF15 F4214000 call dword ptr [<&USER32.MessageBoxA>>; user32.MessageBoxA
0012F750 8B4C24 04 mov ecx, dword ptr [esp+4]
0012F754 68 E8030000 push 3E8
0012F759 E8 88030000 call 0012FAE6
0012F75E 6A 00 push 0
0012F760 8BC8 mov ecx, eax
0012F762 E8 79030000 call 0012FAE0
0012F767 C3 retn
根据C=0xC4可以得到SB并进一步确定A的取值为0x1E,即只需要SN的11B自身异或结果等于0x1E即可得到正确结果,因此该题存在多解,以下是符合条件的一个SN:
“PPOa0000000”
004015E9 . F3:A5 rep movs dword ptr es:[edi], dword ptr [esi] ; SN输入长度超过10B会执行到这里,将SN拷贝到栈中
004015EB . 8BCA mov ecx, edx
004015ED . 33D2 xor edx, edx
004015EF . 83E1 03 and ecx, 3
004015F2 . 85ED test ebp, ebp
004015F4 . F3:A4 rep movs byte ptr es:[edi], byte ptr [esi]
004015F6 . 7E 17 jle short 0040160F
004015F8 > 8A4C14 18 mov cl, byte ptr [esp+edx+18] ; 依次取出SN中1B(共11B)
004015FC . 33C0 xor eax, eax
004015FE > 3088 20304000 xor byte ptr [eax+403020], cl ; 与403020中的20B进行异或
00401604 . 40 inc eax
00401605 . 83F8 14 cmp eax, 14 ; 内循环次数20
00401608 .^ 7C F4 jl short 004015FE
0040160A . 42 inc edx
0040160B . 3BD5 cmp edx, ebp ; 外循环次数11
0040160D .^ 7C E9 jl short 004015F8
异或前403020缓存中的初始状态,注意在00403034的字符串“成功”,在后面求取的时候会用到
00403020 CC AA BD DD CB BA B2 92 AF BA B4 B9 B0 AC CB BA 酞捷撕矑垂艾撕
00403030 CE D0 DF DD B3 C9 B9 A6 00 00 00 00 00 00 00 00 涡咻成功........
0040160F > \C74424 10 000>mov dword ptr [esp+10], 0
00401617 . FF15 08204000 call dword ptr [<&KERNEL32.GetCurrentProcessId>>; [GetCurrentProcessId
0040161D . 50 push eax ; /ProcessId
0040161E . 6A 00 push 0 ; |Inheritable = FALSE
00401620 . 68 FF0F1F00 push 1F0FFF ; |Access = PROCESS_ALL_ACCESS
00401625 . FF15 04204000 call dword ptr [<&KERNEL32.OpenProcess>] ; \打开自身进程
0040162B . 8BF8 mov edi, eax
0040162D . 8D4424 10 lea eax, dword ptr [esp+10]
00401631 . 50 push eax ; /pBytesRead
00401632 . 8D4C24 1C lea ecx, dword ptr [esp+1C] ; |
00401636 . 6A 2C push 2C ; |BytesToRead = 2C (44.)
00401638 . 51 push ecx ; |Buffer
00401639 . 68 40154000 push 00401540 ; |pBaseAddress = 401540
0040163E . 57 push edi ; |hProcess
0040163F . FF15 14204000 call dword ptr [<&KERNEL32.ReadProcessMemory>] ; \读取401540处的0x2C=44B
00401645 . 85C0 test eax, eax
00401647 . 74 4D je short 00401696
00401540中44B:
00401540 AE C5 AC F0 F4 84 C4 AC F0 F4 84 C4 AE C4 3B D1 魟默痿勀;?
00401550 30 E5 84 C4 4F 88 E0 C0 AC 2C C7 C4 C4 2C 4C C7 0鍎腛堗垃,悄?L?
00401560 C4 C4 AE C4 4F 0C 2C BD C7 C4 C4 07 哪O.,角哪悙悙
每次从00403020中取出1B(共20B),与0x5E相乘,再与00401540中的44B依次进行异或,更新结果,并将结果写到00401540处
00401649 . 33F6 xor esi, esi
0040164B > 8A86 20304000 mov al, byte ptr [esi+403020] ; 读取403020中的1B
00401651 . B2 5E mov dl, 5E
00401653 . 33C9 xor ecx, ecx
00401655 . F6EA imul dl ; 与0x5E相乘
00401657 > 8A540C 18 mov dl, byte ptr [esp+ecx+18] ; 与00401540中的44B依次进行异或
0040165B . 32D0 xor dl, al ;
0040165D . 88540C 18 mov byte ptr [esp+ecx+18], dl ; 保存结果
00401661 . 41 inc ecx
00401662 . 83F9 2C cmp ecx, 2C ; 内循环次数44
00401665 .^ 7C F0 jl short 00401657 ;
00401667 . 46 inc esi
00401668 . 83FE 14 cmp esi, 14 ; 外循环次数20
0040166B .^ 7C DE jl short 0040164B
0040166D . 8D4424 10 lea eax, dword ptr [esp+10]
00401671 . 8D4C24 18 lea ecx, dword ptr [esp+18]
00401675 . 50 push eax ; /pBytesWritten
00401676 . 6A 2C push 2C ; |BytesToWrite = 2C (44.)
00401678 . 51 push ecx ; |Buffer
00401679 . 68 40154000 push 00401540 ; |Address = 401540
0040167E . 57 push edi ; |hProcess
0040167F . FF15 00204000 call dword ptr [<&KERNEL32.WriteProcessMem> ; \将异或结果写回到00401540
00401685 . 85C0 test eax, eax
00401687 . 74 0D je short 00401696
00401689 . 8B5424 14 mov edx, dword ptr [esp+14]
0040168D . 52 push edx
0040168E . E8 ADFEFFFF call 00401540 ; 然后执行00401540处的代码
SN的11B自身进行异或得到 A
A与403020的20B进行异或得到序列 SB
SB中20B分别与0x5E相乘后再自身进行异或得到 C
C与00401540中44B进行异或,最终得到正确的执行代码
分析清楚两次异或处理过程后,就是对正确解密代码的求取,首先利用00403034的字符串“成功”,猜想解密正确的代码会用到这个字符串来进行信息提示
可以求出C的取值为0xC4,同时得到正确解密的代码如下:
0012F73C 3468016A jh4
0012F740 68004030 0@.h
0012F744 00403034 40@. 27_Crack.00403034
0012F748 15FF006A j.
0012F74C 004021F4 ?@. <&USER32.MessageBoxA>
0012F750 04244C8B 婰$
0012F754 0003E868 h?.
0012F758 0388E800 .鑸
0012F75C 006A0000 ..j.
0012F760 79E8C88B 嬋鑩
0012F73C 6A 01 push 1
0012F73E 68 34304000 push 403034
0012F743 68 34304000 push 403034
0012F748 6A 00 push 0
0012F74A FF15 F4214000 call dword ptr [<&USER32.MessageBoxA>>; user32.MessageBoxA
0012F750 8B4C24 04 mov ecx, dword ptr [esp+4]
0012F754 68 E8030000 push 3E8
0012F759 E8 88030000 call 0012FAE6
0012F75E 6A 00 push 0
0012F760 8BC8 mov ecx, eax
0012F762 E8 79030000 call 0012FAE0
0012F767 C3 retn
根据C=0xC4可以得到SB并进一步确定A的取值为0x1E,即只需要SN的11B自身异或结果等于0x1E即可得到正确结果,因此该题存在多解,以下是符合条件的一个SN:
“PPOa0000000”
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
- [原创]看雪CTF2017第一题分析 3416
- [原创]看雪CTF2016第二十六题分析 2918
- [原创]看雪CTF2016第二十六题分析 3657
- [原创]看雪CTF2016第十题分析 3163
- [原创]看雪CTF2016第八题分析 2873
看原图
赞赏
雪币:
留言: