首页
社区
课程
招聘
[参赛]第一题——看雪论坛.腾讯公司2008软件安全竞赛
发表于: 2008-10-3 12:46 2346

[参赛]第一题——看雪论坛.腾讯公司2008软件安全竞赛

2008-10-3 12:46
2346
试着做了一下,基本要求都达到了。

1.为DLL文件新增输出表,同时增加输出函数OpenUrlA; OK
2.OpenUrlA函数功能是调用IE浏览器打开http://bbs.pediy.com,打开后无其他操作;OK 调用ShellExecuteA 后只有个ret指令
3.不得改变pediy.dll的ImageBase的值400000h;OK 没有动这个
4. 最终提交的程序,必须可运行在Windows 2000/XP系统上;大概OK  手头没有Win2K,不过用的是PEB获取Kernel32基址,WinXP SP2/SP3 测试都没有问题
5. 将修改好了的程序,与修改步骤(将整个过程用文字简单描述一下),一起上传到答案提交区。


5. 改造过程说明:
在003F10CA处加入如下代码:
003F10CA   .  E8 31000000   CALL pediy.003F1100                      ;  Start of OpenUrlA
003F10CF   .  C3            RETN


003F10D0   .  4C 6F 61 64 4>ASCII "LoadLibraryA",0

003F10E0   .  53 68 65 6C 6>ASCII "Shell32.dll",0

003F10F0   .  53 68 65 6C 6>ASCII "ShellExecuteA",0

003F1100  /$  64:A1 3000000>MOV EAX,DWORD PTR FS:[30]                ;  搜索 Kernell32 基址
003F1106  |.  8B40 0C       MOV EAX,DWORD PTR DS:[EAX+C]
003F1109  |.  8B70 1C       MOV ESI,DWORD PTR DS:[EAX+1C]
003F110C  |.  AD            LODS DWORD PTR DS:[ESI]
003F110D  |.  8B40 08       MOV EAX,DWORD PTR DS:[EAX+8]
003F1110  |.  95            XCHG EAX,EBP                             ;  将基址存到 EBP 备用
003F1111  |.  8B45 3C       MOV EAX,DWORD PTR SS:[EBP+3C]            ;  指向PE头
003F1114  |.  8B5428 78     MOV EDX,DWORD PTR DS:[EAX+EBP+78]
003F1118  |.  03D5          ADD EDX,EBP                              ;  EDX = 引出表地址
003F111A  |.  8B4A 18       MOV ECX,DWORD PTR DS:[EDX+18]
003F111D  |.  8B5A 20       MOV EBX,DWORD PTR DS:[EDX+20]
003F1120  |.  03DD          ADD EBX,EBP                              ;  EBX = AddressOfName
003F1122  |>  49            /DEC ECX                                 ;  开始搜索 GetProcAddress
003F1123  |.  8B348B        |MOV ESI,DWORD PTR DS:[EBX+ECX*4]
003F1126  |.  03F5          |ADD ESI,EBP
003F1128  |.  B8 726F6341   |MOV EAX,41636F72                        ;  特征字符 'Acor'
003F112D  |.  3946 04       |CMP DWORD PTR DS:[ESI+4],EAX            ;  这里省掉了比较头部 'PteG',直接比较+4位置
003F1130  |.^ 75 F0         \JNZ SHORT pediy.003F1122
003F1132  |.  8B5A 24       MOV EBX,DWORD PTR DS:[EDX+24]
003F1135  |.  03DD          ADD EBX,EBP
003F1137  |.  66:8B0C4B     MOV CX,WORD PTR DS:[EBX+ECX*2]           ;  计算函数的序号
003F113B  |.  8B5A 1C       MOV EBX,DWORD PTR DS:[EDX+1C]
003F113E  |.  03DD          ADD EBX,EBP                              ;  EBX = AddressOfFunction
003F1140  |.  8B048B        MOV EAX,DWORD PTR DS:[EBX+ECX*4]
003F1143  |.  03C5          ADD EAX,EBP                              ;  此时 EAX = GetProcAddress地址
003F1145  |.  8B3C24        MOV EDI,DWORD PTR SS:[ESP]               ;  由ret地址计算确定字符串的位置
003F1148  |.  47            INC EDI                                  ;  跳过 ret 的1字节,此时EDX = 003F10D0| ASCII "LoadLibraryA",0
003F1149  |.  50            PUSH EAX                                 ;  保存 GetProcAddress 地址备用
003F114A  |.  57            PUSH EDI                                 ;  arg2 = ASCII "LoadLibraryA",0
003F114B  |.  55            PUSH EBP                                 ;  arg1 = kernel32.基址
003F114C  |.  FFD0          CALL EAX                                 ;  GetProcAddress()
003F114E  |.  83C7 10       ADD EDI,10
003F1151  |.  57            PUSH EDI                                 ;  arg = ASCII "Shell32.dll",0
003F1152  |.  FFD0          CALL EAX                                 ;  LoadLibraryA()
003F1154  |.  8BD8          MOV EBX,EAX                              ;  EBX = Shell32.基址
003F1156  |.  58            POP EAX                                  ;  EAX = GetProcAddress地址
003F1157  |.  83C7 10       ADD EDI,10
003F115A  |.  57            PUSH EDI                                 ;  arg2 = ASCII "ShellExecuteA",0
003F115B  |.  53            PUSH EBX                                 ;  arg1 = Shell32.基址
003F115C  |.  FFD0          CALL EAX                                 ;  GetProcAddress()
003F115E  |.  81C7 B8000000 ADD EDI,0B8                              ;  EDI指向后面的 003F11A8| ASCII "http://bbs.pediy"
003F1164  |.  6A 01         PUSH 1                                   ;  nShowCmd = 1 (SW_SHOWNORMAL)
003F1166  |.  6A 00         PUSH 0                                   ;  lpDirectory = NULL
003F1168  |.  6A 00         PUSH 0                                   ;  lpParameters = NULL
003F116A  |.  57            PUSH EDI                                 ;  lpFile = "http://bbs.pediy.com"
003F116B  |.  83EF 08       SUB EDI,8
003F116E  |.  57            PUSH EDI                                 ;  lpOperation = "open"
003F116F  |.  6A 00         PUSH 0                                   ;  hWnd = 0
003F1171  |.  FFD0          CALL EAX                                 ;  ShellExecuteA()
003F1173  \.  C3            RETN


然后手工修改引出表,导出自定义函数OpenUrlA:
.rdata:004020E0 s_Pediy_dll     db 'pediy.dll',0

.rdata:004020F0 s_Openurla      db 'OpenUrlA',0

.rdata:00402100 ExportTable     dd 0                    ; Characteristics
.rdata:00402104                 dd 0                    ; TimeDateStamp
.rdata:00402108                 dw 0                    ; MajorVersion
.rdata:0040210A                 dw 0                    ; MinorVersion
.rdata:0040210C My_nName        dd 20E0h                ; nName = "pediy.dll"
.rdata:00402110                 dd 1                    ; nBase
.rdata:00402114                 dd 1                    ; NumberOfFunctions
.rdata:00402118                 dd 1                    ; NumberOfNames
.rdata:0040211C AddrOfFunc      dd 2140h
.rdata:00402120 AddrOfNames     dd 2148h
.rdata:00402124 AddrOfNameOrd   dd 2150h

.rdata:00402140                 dd 10CAh                ; [003F10CA] address of OpenUrlA

.rdata:00402148                 dd 20F0h                ; [004020F0] name of OpenUrlA

.rdata:00402150                 dd 0                    ; Ord 0


最后用16进制编辑器修改0x149和0x14C:
149:        00        21
14C:        00        30

或用PETools自带的PE编辑功能,修改引出表位置:0x0        ->        0x2100      大小:0x0        ->        0x30

其他未注明地址都没有修改,至此改造完成。

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
2
看了一下别人的回复,12字节
我这都不知道多少字节了。并且拿提供的那个测试程序加载,执行后顺利崩掉

算了,等12字节的答案瞻仰一番。
2008-10-3 14:11
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
3
嗯,想到缩短字节的方法了,用的是Kernel32.CreateProcessA吧,怪不得有人说要定位ie的位置。这样就不需要加载Shell32,取ShellExecuteA这种臃肿的办法了。

发现之前提交的这个代码运行后崩掉的原因...忘了恢复寄存器。patch一下:
003F10CA   .  E8 30000000   CALL pediy.003F10FF

003F10FF  /$  60            PUSHAD

003F1145  |.  8B7C24 20     MOV EDI,DWORD PTR SS:[ESP+20]
003F1149  |.  47            INC EDI
后面代码后移1字节
003F1174  |.  61            POPAD
003F1175  \.  C3            RETN

继续去想CreateProcessA的方法,希望能在结束前想出来
2008-10-3 14:51
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
4
终于赶上了,还有1小时结束

实现方法:
加入CreateProcessA到引入表(插了新节),然后调用CreateProcessA打开IE。
只不过调用CreateProcessA代码太长,没时间仔细琢磨怎么缩减了

改造过程:
1. 手工修改引出表,导出自定义函数OpenUrlA。
2. 用 Stud PE 增加一个新节,用于引入CreateProcessA。(改了一下节大小,默认的0x1000没有必要)
3. 在 OpenUrlA 的开始位置[003F10CA]加入如下代码:
003F10CA   .  60            PUSHAD
003F10CB   .  6A 44         PUSH 44                                  ;  _STARTUPINFO.cb = 44
003F10CD   .  B9 10000000   MOV ECX,10                               ;  压入40字节的0作为缓冲区
003F10D2   >  6A 00         PUSH 0
003F10D4   .^ E2 FC         LOOPD SHORT pediy.003F10D2
003F10D6   .  54            PUSH ESP                                 ; /pProcessInfo
003F10D7   .  54            PUSH ESP                                 ; |pStartupInfo
003F10D8   .  6A 00         PUSH 0                                   ; |CurrentDir = NULL
003F10DA   .  6A 00         PUSH 0                                   ; |pEnvironment = NULL
003F10DC   .  6A 00         PUSH 0                                   ; |CreationFlags = 0
003F10DE   .  6A 00         PUSH 0                                   ; |InheritHandles = FALSE
003F10E0   .  6A 00         PUSH 0                                   ; |pThreadSecurity = NULL
003F10E2   .  6A 00         PUSH 0                                   ; |pProcessSecurity = NULL
003F10E4   .  68 80303F00   PUSH 003F3080                            ; |CommandLine = "-e bbs.pediy.com"
003F10E9   .  68 50303F00   PUSH 003F3050                            ; |ModuleFileName = "C:\Program Files\Internet Explorer\iexplore.exe"
003F10EE   .  FF15 5D503F00 CALL DWORD PTR DS:[<&KERNEL32.CreateProc>; \CreateProcessA
003F10F4   .  83C4 44       ADD ESP,44                               ;  修正之前压入的44字节
003F10F7   .  61            POPAD
003F10F8   .  C3            RETN


4. 修改重定位信息,对003F10E5/ 003F10EA/ 003F10F0 这三个位置进行重定位:
00000A10                            9F 30 BE 30 C5 30 E5 30
00000A20   EA 30 F0 30

5. 用OD载入DLL,修正代码中的对应位置:
003F10E4   .  68 80303F00   PUSH 003F3080
003F10E9   .  68 50303F00   PUSH 003F3050
003F10EE   .  FF15 5D503F00 CALL DWORD PTR DS:[3F505D]

好像没有漏掉的步骤了 ,完成。
上传的附件:
2008-10-4 11:18
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
5
果然想叉了,按照之前的思路,引入ShellExecuteA能缩减为26字节:

003F10CA   .  60            PUSHAD
003F10CB      6A 01         PUSH 1
003F10CD      6A 00         PUSH 0
003F10CF      6A 00         PUSH 0
003F10D1      68 50303F00   PUSH pediy.003F3050                      ;  ASCII "http://bbs.pediy.com"
003F10D6      68 68303F00   PUSH pediy.003F3068                      ;  ASCII "open"
003F10DB      6A 00         PUSH 0
003F10DD      FF15 5C503F00 CALL DWORD PTR DS:[3F505C]               ;  Shell32.ShellExecuteA
003F10E3      61            POPAD
003F10E4      C3            RETN

这个26字节离个位数好遥远啊
2008-10-4 11:44
0
雪    币: 264
活跃值: (30)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
6
开始计算函数长度...
OpenUrlA 函数大小 = 47 字节
附件提交次数 = 1
得分 = min[1.0, 13/47]x100 - (1 -1 )x5 = 27.659574
2008-10-14 17:04
0
游客
登录 | 注册 方可回帖
返回
//