首页
社区
课程
招聘
[原创]看雪CTF.TSRC 2018 团队赛 第二题 半加器 write up
2018-12-3 19:46 2648

[原创]看雪CTF.TSRC 2018 团队赛 第二题 半加器 write up

2018-12-3 19:46
2648

环境配置

系统 : Windows 7
程序 : 半加器
要求 : 输入口令
使用工具 :od

开始分析

我们运行程序,发现弹出提示字符串Please Input:,od中搜索字符串,发现具体信息如下:

中文搜索引擎, 条目 35
 地址=004319D8
 反汇编=push Exam.005425BC
 文本字符串=Please Input:

定位到相关代码段:

004319B0  /> \55            push ebp
004319B1  |.  8BEC          mov ebp,esp
004319B3  |.  81EC CC000000 sub esp,0xCC
004319B9  |.  53            push ebx
004319BA  |.  56            push esi
004319BB  |.  57            push edi
004319BC  |.  8DBD 34FFFFFF lea edi,[local.51]
004319C2  |.  B9 33000000   mov ecx,0x33
004319C7  |.  B8 CCCCCCCC   mov eax,0xCCCCCCCC
004319CC  |.  F3:AB         rep stos dword ptr es:[edi]
004319CE  |.  B9 07605800   mov ecx,Exam.00586007
004319D3  |.  E8 DCBDFEFF   call Exam.0041D7B4
004319D8  |.  68 BC255400   push Exam.005425BC                       ;  Please Input:
004319DD  |.  68 E0315800   push Exam.005831E0
004319E2  |.  E8 5FB3FEFF   call Exam.0041CD46
004319E7  |.  83C4 08       add esp,0x8
004319EA  |.  6A 1E         push 0x1E
004319EC  |.  68 68305800   push Exam.00583068                       ;  1234567A90
004319F1  |.  68 9C225400   push Exam.0054229C                       ;  %s
004319F6  |.  E8 F3A6FEFF   call Exam.0041C0EE
004319FB  |.  83C4 0C       add esp,0xC
004319FE  |.  68 68305800   push Exam.00583068                       ;  1234567A90
00431A03  |.  E8 9E8FFEFF   call Exam.0041A9A6                       ;  get_len
00431A08  |.  83C4 04       add esp,0x4
00431A0B  |.  8945 F8       mov [local.2],eax
00431A0E  |.  837D F8 1E    cmp [local.2],0x1E                       ;  > 30
00431A12  |.  7F 06         jg XExam.00431A1A
00431A14  |.  837D F8 0A    cmp [local.2],0xA                        ;  >= 10
00431A18  |.  7D 16         jge XExam.00431A30
00431A1A  |>  68 CC255400   push Exam.005425CC                       ;  输入错误;
00431A1F  |.  E8 B78CFEFF   call Exam.0041A6DB
00431A24  |.  83C4 04       add esp,0x4
00431A27  |.  6A 00         push 0x0
00431A29  |.  E8 46A8FEFF   call Exam.0041C274
00431A2E  |.  EB 4E         jmp XExam.00431A7E
00431A30  |>  68 68305800   push Exam.00583068                       ;  1234567A90
00431A35  |.  6A 1E         push 0x1E
00431A37  |.  A1 88305800   mov eax,dword ptr ds:[0x583088]
00431A3C  |.  50            push eax
00431A3D  |.  E8 7DCBFEFF   call Exam.0041E5BF                       ;  ready to inti
00431A42  |.  83C4 0C       add esp,0xC
00431A45  |.  B8 01000000   mov eax,0x1
00431A4A  |.  6BC8 07       imul ecx,eax,0x7
00431A4D  |.  8B15 88305800 mov edx,dword ptr ds:[0x583088]
00431A53  |.  0FBE040A      movsx eax,byte ptr ds:[edx+ecx]
00431A57  |.  83F8 41       cmp eax,0x41                             ;  position 8 is 'A'?
00431A5A  |.  74 14         je XExam.00431A70
00431A5C  |.  68 CC255400   push Exam.005425CC                       ;  输入错误;
00431A61  |.  E8 758CFEFF   call Exam.0041A6DB
00431A66  |.  83C4 04       add esp,0x4
00431A69  |.  6A 00         push 0x0
00431A6B  |.  E8 04A8FEFF   call Exam.0041C274
00431A70  |>  A1 88305800   mov eax,dword ptr ds:[0x583088]
00431A75  |.  50            push eax
00431A76  |.  E8 29B9FEFF   call Exam.0041D3A4                       ;  process my_str
00431A7B  |.  83C4 04       add esp,0x4
00431A7E  |>  33C0          xor eax,eax
00431A80  |.  5F            pop edi
00431A81  |.  5E            pop esi
00431A82  |.  5B            pop ebx
00431A83  |.  81C4 CC000000 add esp,0xCC
00431A89  |.  3BEC          cmp ebp,esp
00431A8B  |.  E8 A5BEFEFF   call Exam.0041D935
00431A90  |.  8BE5          mov esp,ebp
00431A92  |.  5D            pop ebp
00431A93  \.  C3            retn

在输入字符串后的返回地址下断:
004319FB |. 83C4 0C add esp,0xC
然后按F8单步走,简单的就能猜出call Exam.0041A9A6是在计算字符串长度,接着对字符串长度进行控制:

00431A0E  |.  837D F8 1E    cmp [local.2],0x1E                       ;  > 30
00431A12  |.  7F 06         jg XExam.00431A1A
00431A14  |.  837D F8 0A    cmp [local.2],0xA                        ;  >= 10
00431A18  |.  7D 16         jge XExam.00431A30

这代表输入一个长度10的字符串就可以,我们用1234567A90代替输入,因为有以下检测代码:

00431A45  |.  B8 01000000   mov eax,0x1
00431A4A  |.  6BC8 07       imul ecx,eax,0x7
00431A4D  |.  8B15 88305800 mov edx,dword ptr ds:[0x583088]
00431A53  |.  0FBE040A      movsx eax,byte ptr ds:[edx+ecx]
00431A57  |.  83F8 41       cmp eax,0x41                             ;  position 8 is 'A'?
00431A5A  |.  74 14         je XExam.00431A70

F8执行到这一步,发现我们的字符串有了明显的变化:

00431A70  |> \A1 88305800   mov eax,dword ptr ds:[0x583088]
00431A75  |.  50            push eax
00431A76  |.  E8 29B9FEFF   call Exam.0041D3A4                       ;  process my_str

我们查看调用子函数后的字符串:

00799710  2E 2D 2C 2B 2A 29 28 3C 26 2F 00 FE FE FE FE FE  .-,+*)(<&/.?
00799720  FE FE FE FE FE FE FE FE FE FE FE FE FE FE FD FD  

我们在内存窗口中选择前四个字节,右击->断点->内存访问。完成后F9让程序继续执行,看看是什么代码访问了操作后的字符串:

01147DF2    3A01            cmp al,byte ptr ds:[ecx]
01147DF4    75 32           jnz XExam.01147E28
01147DF6    84C0            test al,al
01147DF8    74 26           je XExam.01147E20
01147DFA    3A61 01         cmp ah,byte ptr ds:[ecx+0x1]
01147DFD    75 29           jnz XExam.01147E28
01147DFF    84E4            test ah,ah
01147E01    74 1D           je XExam.01147E20
01147E03    C1E8 10         shr eax,0x10
01147E06    3A41 02         cmp al,byte ptr ds:[ecx+0x2]
01147E09    75 1D           jnz XExam.01147E28
01147E0B    84C0            test al,al
01147E0D    74 11           je XExam.01147E20
01147E0F    3A61 03         cmp ah,byte ptr ds:[ecx+0x3]

发现是一段比较字符串是否相等的汇编代码,我们查看程序内的用于比对的固定数据:

011F1000  75 72 6A 7D 70 75 78 3C 7D 6E 7B 69 71 79 72 68  urj}pux<}n{iqyrh
011F1010  00

做到这里,有经验的朋友都知道。程序对输入的字符串做操作,作比较之后,就会输出成功与否的提示了。我们不妨直接将内存断点先删除,将以上数据的值直接复制给我们的字符串,看看输出如何。

验证可行性

我们直接在内存窗口中定位我们的字符串,双击第一个字节,出现编辑窗口。此时,取消掉保持大小的单选框,然后将以上数据的hex值直接黏贴(包括00结束值)。完成后,直接F9运行程序:
Please Input:1234567A90 ok
发现程序提示成功,如果程序一闪而过,可以在od里按Alt+k查看调用栈,在退出之前对相关代码段下断。

分析操作字符的函数

此时,我们再回头定位分析操作字符的函数,按Ctrl+F2重新调试:

00221A75  |.  50            push eax
00221A76  |.  E8 29B9FEFF   call Exam.0020D3A4                       ;  process my_str

进行函数前,用之前的方式对我们的字符串下内存访问断点,然后直接F9运行程序,第二断下时到达关键算法:

0089DBD0  /> \55            push ebp
0089DBD1  |.  8BEC          mov ebp,esp
0089DBD3  |.  81EC CC000000 sub esp,0xCC
0089DBD9  |.  53            push ebx
0089DBDA  |.  56            push esi
0089DBDB  |.  57            push edi
0089DBDC  |.  8DBD 34FFFFFF lea edi,[local.51]
0089DBE2  |.  B9 33000000   mov ecx,0x33
0089DBE7  |.  B8 CCCCCCCC   mov eax,0xCCCCCCCC
0089DBEC  |.  F3:AB         rep stos dword ptr es:[edi]
0089DBEE  |.  B9 07609F00   mov ecx,Exam.009F6007
0089DBF3  |.  E8 BCFBFEFF   call Exam.0088D7B4
0089DBF8  |.  B8 01000000   mov eax,0x1
0089DBFD  |.  6BC8 07       imul ecx,eax,0x7
0089DC00  |.  8B55 08       mov edx,[arg.1]
0089DC03  |.  C6040A 23     mov byte ptr ds:[edx+ecx],0x23           ;  mystr[7] = '#'
0089DC07  |.  C745 F8 00000>mov [local.2],0x0
0089DC0E  |.  EB 09         jmp XExam.0089DC19
0089DC10  |>  8B45 F8       /mov eax,[local.2]
0089DC13  |.  83C0 01       |add eax,0x1
0089DC16  |.  8945 F8       |mov [local.2],eax
0089DC19  |>  8B45 08        mov eax,[arg.1]
0089DC1C  |.  50            |push eax
0089DC1D  |.  E8 84CDFEFF   |call Exam.0088A9A6
0089DC22  |.  83C4 04       |add esp,0x4
0089DC25  |.  3945 F8       |cmp [local.2],eax
0089DC28  |.  73 16         |jnb XExam.0089DC40
0089DC2A  |.  8B45 08       |mov eax,[arg.1]
0089DC2D  |.  0345 F8       |add eax,[local.2]
0089DC30  |.  0FBE08        |movsx ecx,byte ptr ds:[eax]
0089DC33  |.  83F1 1F       |xor ecx,0x1F
0089DC36  |.  8B55 08       |mov edx,[arg.1]
0089DC39  |.  0355 F8       |add edx,[local.2]
0089DC3C  |.  880A          |mov byte ptr ds:[edx],cl
0089DC3E  |.^ EB D0         \jmp XExam.0089DC10
0089DC40  |>  8B45 08       mov eax,[arg.1]

这是把字符串的第八位置赋值#,然后整个字符串和0x1F异或。

逻辑推理

程序首先对字符串进行格式检查,然后检查第八位是否为A,接着,在异或操作之前对第八位赋值#,字符串整体与0x1F异或。最后,与字符串urj}pux<}n{iqyrh对比,相同则成功。

 

我们不妨用urj}pux<}n{iqyrh作为输入,当然,第八位要改为#,也就是urj}pux#}n{iqyrh直接传入xor循环,然后让其帮我们输出password。最后,因为输入要求的关系,将结果的第八位改成A,就ok了。

夺旗成功

将xor函数的输入改成:

00639710  75 72 6A 7D 70 75 78 23 7D 6E 7B 69 71 79 72 68  urj}pux#}n{iqyrh
00639720  00 FE FE FE FE FE FE FE FE FE FE FE FE FE FD FD  .?

然后在循环的结束位置0x00BADC40下断点:

00BADC3C  |.  880A          |mov byte ptr ds:[edx],cl
00BADC3E  |.^ EB D0         \jmp XExam.00BADC10
00BADC40  |>  8B45 08       mov eax,[arg.1]

结果为:

00639710  6A 6D 75 62 6F 6A 67 3C 62 71 64 76 6E 66 6D 77  jmubojg<bqdvnfmw

将字符串第八位改成A:jmubojgAbqdvnfmw。单独运行程序,输入flag提示成功:

Please Input:jmubojgAbqdvnfmw
ok

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

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