Tags: pwn 

Rating: 5.0

Ghost in the heap - Write up

Program

  • New heap
    • Allocate a 168 bytes heap.
    • You can only have three heap.
  • Delete heap
    • Delete heap by index.
  • Add ghost
    • Add a ghost with magic
    • You can only have one ghost.
struct Ghost {
    char desc[0x48] ;
    long magic ;
};
  • Watch ghost
    • Show the information of ghost if magic is matched.
  • Remove ghost
    • Remove the ghost.

Vulnerability

  • off-by-one NULL byte in new_heap

    void new_heap(){
    int i ;
    size_t size = 0;
    for(i = 0 ; i < MAX ; i++){
        if(!heap[i]){
            heap[i] = malloc(HEAPSIZE);
            if(!heap[i]){
                puts("Alloacte error !");
                _exit(-1);
            }
            printf("Data :");
            scanf("%168s",heap[i]);
            return ;
        }
    }
    puts("Too many heap !");
    

} ```

+ The size of heap is 168 bytes, but it use `scanf("%168s",heap[i[)` to read input. It will puts a null byte in the end of input. If your length of input is equal to 168 byte, it would lead to off-byte one overflow.
  • Information leak

    • It use read() to read input without NULL byte which leads to information leak.
    void read_input(char *buf,unsigned int size){
        int ret ;
        ret = read(0,buf,size);
        if(ret <= 0){
         puts("read error");
            _exit(1);
        }
    }
    
  • Exploitation

    • Idea
      • [Fail] Fastbin dup
        • It only allocate a fastbin chunk.
      • [Fail] Unsorted bin attack to overwrite _IO_list_all.
        • Because there are some vtable vertify in lastet libc.
      • [Success] Unsoted bin attack to corrupt stdin buffer
        • It's using scanf and it would use stdin buffer. So we can overwrite the _IO_buf_end,you will have a stdin buffer in libc. After do that you can control the flow.
+ Information leak
    + Heap address
        + It a little hard to get heap address. Because we only have three smallbin and one fastbin chunk. 
            1. Add a ghost and three heap
            2. Remove the first heap and ghost
                ![](img/2.png)
            3. Remove the last heap, it would merge with top and trigger `malloc_cosolidate`. The fastbin chunk would merge with unsorted chunk.
                ![](img/3.png)
            4. Add two heap
                ![](img/4.png)
            5. Remove `Heap 1` so that it can merge with free chunk and return to unsorted bin.
                ![](img/5.png)
            6. Add one heap, and remove `heap 0`. We can see that we have two chunk in unsoted bin, so we have heap address in the heap.
                ![](img/6.png)
            7. Add ghost and we can get heap address by watching ghost
            
    + Libc address
        + It's easier than heap address. Just use unsorted chunk.


+ Create a overlap chunk
    1. Remove ghost and all of heap
    2. Add a heap, ghost and two heap
    3. Remove `heap 0` and ghost
        ![](img/7.png)
    4. Remove `heap 2` and it would trigger `malloc_consolidate`
        ![](img/8.png)
    5. Add 2 heap
        ![](img/9.png)
    6. Remove `heap 0` and `heap 1`
        ![](img/10.png)
    7. Trigger the vulnerability
        ![](img/11.png)
    8. Add 1 heap
        ![](img/12.png)
    9. Remove `heap 1` (Let it can remove `heap 0`)
        ![](img/13.png)
    10. Remove `heap 0`
        ![](img/14.png)
    11. Add a ghost
        ![](img/15.png)
    12. Add a new heap and forge fake chunk
        ![](img/16.png)
    13. Add a new heap and remove `heap 2`, then you can unlink success and create overlap chunk.
        ![](img/17.png)
    14. More detail you can see my [exploit](./exp.py)

+ Unsorted bin attack
    + Use unsorted bin attak to overwrite `_IO_buf_end` 
        ![](img/18.png) 
    + Trigger `scanf()`
        + It will read data to stdin buffer. You can use it to overwrite `malloc_hook` with one gadget
    + Trigger `malloc` and you will get shell.
    + More detail about FILE structure
        + [Play with FILE Structure](http://4ngelboy.blogspot.tw/2017/11/play-with-file-structure-yet-another.html)
+ Exploit
    + [exp.py](./exp.py) 
Original writeup (https://github.com/scwuaptx/CTF/tree/master/2017-writeup/hitcon/ghost_in_the_heap).