首页 -> 安全研究
安全研究
绿盟月刊
绿盟安全月刊->第43期->技术专题
作者:czy <czy82@elong.com>
主页:http://www.nsfocus.com
日期:2003-08-06
win2000溢出1
czy 03.07.29
方便自已,也方便初学者哈,由于没有找到在2k下用VC语言编写最简单程序的办法
所以例子是用WIN32汇编来写的,编绎器是masm6.14,调试工具是softice 2.6
程序说明:为了方便下断点,程序一开始用了MessageBoxA,所以在ICE中你用
bpx messageboxa就可以拦到程序了.然后是一个testov子程序,里面的代码我是照着
C语言里面函数的代码来写的.所以就可以简单的通过覆盖压入栈的EIP来达到执行我们
在SHELLCODE.
shellcode说明:其实这个算不上是shellcode哈,我只想熟悉一下2K下SHELLCODE的
编码. 它的作用是给messageboxa API传四个参数然后跳到一个call messageboxa的地方
去执行.
另外数据段中的shellcode的最后一句JMP 0040100E的地址是00403018,怎么把它搞
成机器码,这儿是高地址向低址跳位移量计算:40101E-403018-5然后取后32位就可以了.
附:jmp长跳转的机器码规则是:E9+位移量
如何从指令到shellcode:指令-->机器码(16进制)-->shellcode(10进制)
push 01 6A01 106 01
-------------------------one.asm----------------
.386
.model flat,stdcall
option casemap:none
include ../include/windows.inc
include ../include/user32.inc
includelib ../lib/user32.lib
include ../include/kernel32.inc
includelib ../lib/kernel32.lib
include ../include/Advapi32.inc
includelib ../lib/Advapi32.lib
.data
szcaption db 'hello',0
sztext1 db 'one',0
shellcode db 106,01, \ ;push 01
104,06,48,64,00,\;push 00403006
104,00,48,64,00,\;push 00403000
106,00,\ ;push 00
233,241,223,255,255,0;JMP 0040100E
.code
ms proc
push 1
push offset sztext1
push offset szcaption
push NULL
call MessageBoxA ;JMP 0040100E就是跳到这儿来执行了.
call ExitProcess
ms endp
testov proc
PUSH EBP ;把以前的栈顶的地址保留到堆栈中
MOV EBP,ESP ;把当前的ESP给EBP
SUB ESP,08H ;ESP的值减了8个
MOV DWORD PTR [EBP-08],41h ;A
MOV DWORD PTR [EBP-04],40h ;B
;---------
;mov dword ptr [ebp+4],401000h
mov dword ptr [ebp+4],40300Ah ;testov返回后就跳到数据段去执行shellcode了:)
;---------
MOV ESP,EBP ;重新把ESP值指向原来的地址
POP EBP ;弹出EBP,但是由于ESP把向它,所以两个变量也就清空了
RET ;等同于POP EIP(把栈顶的值赋给EIP)
testov endp
start:
push 1
push offset sztext1
push offset szcaption
push NULL
call MessageBoxA ;用softice下断点
call testov
call ExitProcess
end start
Win2k溢出2
czy 03.07.29
上一篇简单的介绍了2k下溢出执行shellcode的一个办法.现在解决如何在
shellcode中直接执行API函数.
还是以MessageBoxA来当例子.首先明白这个API是在USER32.DLL中,如何在
内存中找到USER32.DLL的起始地址呢http://www.dependencywalker.com/depends21_x86.zip
是一个不错的工具.从工具的Prdferred Base一栏可以看到起始地址是0x77DF0000(base),同样
函数MessageBoxA的入口地址为0x00033D68(entry),所以MessageBoxA的虚拟地址应该是
Base+Entry=0x77E23D68.
CALL 77E23D68的机器码形式是其实这儿等于一道填空题:
指令地址 指令机器码 汇编语句
00403018 E8_ _ _ _ JMP 77E23D68
方法再重复一遍:77E23D68-00403018-5(指令长度)=77A20D4B
然后就成了:E8 4B 0D A2 77 再换为十进制
232,75,13,162,119
但是这样能弹出对话框然后程序出错,原来是没有正常退出看来还得再shellcode
里加上ExitProcess,这个函数是在kernel32.dll里..方法和上面的一样.
完整的shellcode代码如下:
shellcode db 106,01, \;push 01
104,06,48,64,00, \;push 00403006
104,00,48,64,00, \;push 00403000
106,00, \;push 00
232,75,13,162,119, \;call 77E23D68 = call MessageBoxA
232,153,128,167,119,0 ;call 77A78099 = call ExitProcess
没VC管他的俺就写汇编版的WIN2K溢出教程了呵呵.
版权所有,未经许可,不得转载