ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Heap Exploit - House of Force
    Hack/Pwnable 2016. 10. 11. 19:31

    House of Force는, 우리가 원하는 사이즈를 malloc시킬수 있어야하며, top chunk를 덮을수있어야한다. 또 추가적으로 malloc이 한번 더 호출되어야 House of Force 공격을 할 수 있다.


    대충 살펴보자면, 아래와같다.


    1.  top chunk는 다음 malloc을 할당 할 수 있는 크기를 지정해놓는데, 이를 0xffffffff로바꾸면 이만큼 할당을 할 수 있다.

    2. 다음 malloc size를 컨트롤 할 수 있다면 계산해서 우리가 원하는곳에 할당시켜 다음 malloc이 호출되면 그곳에 할당해준다.

    3. 그리고 새로 malloc된, 우리가 원하는곳에 malloc된곳에 user data를 쓸수있다면 컨트롤이 가능하다.



    House Of Force 기법은 다음과 같은 코드가 있기에 정의될 수 있다.


    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
    static void* _int_malloc(mstate av, size_t bytes)
    {
      INTERNAL_SIZE_T nb;             /* normalized request size */
      mchunkptr       victim;         /* inspected/selected chunk */
      INTERNAL_SIZE_T size;           /* its size */
      mchunkptr       remainder;      /* remainder from a split */
      unsigned long   remainder_size; /* its size */
     
      checked_request2size(bytes, nb);
     
      [...]
     
      victim = av->top;
      size = chunksize(victim);
      if ((unsigned long)(size>= (unsigned long)(nb + MINSIZE))
      {
        remainder_size = size - nb;
        remainder = chunk_at_offset(victim, nb);
        av->top = remainder;
        set_head(victim, nb | PREV_INUSE | (av!=&main_arena ? NON_MAIN_ARENA : 0));
        set_head(remainder, remainder_size | PREV_INUSE);
     
        check_malloced_chunk(av, victim, nb);
        void *= chunk2mem(victim);
        if (__builtin_expect (perturb_byte, 0))
          alloc_perturb (p, bytes);
        return p;
      }
     
      [...]
    }
    cs



    victim이란 변수가 존재하는데, av->top을 덮어쓸 수 있다면 size는 topchunk 사이즈를 가진다.
    0xffffffff로 준다면 malloc은 충분한 사이즈로 원하는곳에 할당 할 수 있다.



    익스플로잇을 할 코드를 보자


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    int main(int argc, char *argv[])
    {
            char *buf1, *buf2, *buf3;
            if (argc != 4return;
     
            buf1 = malloc(256);
            strcpy(buf1, argv[1]);
     
            buf2 = malloc(strtoul(argv[2], NULL16));
     
            buf3 = malloc(256);
            strcpy(buf3, argv[3]);
     
            free(buf3);
            free(buf2);
            free(buf1);
     
            return 0;
    }
    cs



    해당 코드는 위 조건을 모두 만족한다.

    argv[2]를 이용해서 두번째 malloc의 사이즈를 조절이 가능하고, 또 malloc을 해준후, malloc해준곳에 strcpy로 값을 복사한다. 그럼 우린 어떠한 함수의 got에다가 할당한다면, User Input을 통해 GOT를 덮을 수 있다.

    한번 디버깅을 해보자


    3번째에 User Input이 들어가고나서 실행되는 루틴에다 BreakPoint를 걸고 진행한다.



    3개의 힙이 전부보인다. 256바이트를 넘쳐 8바이트를 더 입력해준다면 top chunk를 조절 할 수있고, top chunk가 생길곳은 0x804b110이며, 이곳은 두번째 malloc 데이터가 쓰이게된다. free@got에 값을 쓰려면 어떻게 계산을 해줘야될지 생각해보자.

    우선 heap이 생성되면 user data전에 8바이트가 할당된다.

    prev_size + size 가 생기는데 이까지 계산을 해보면 아래와 같이 구성이 가능하다.

    free@got - 0x8 - 2rd malloc

    위 바이너리로 계산을 한다면 다음과 같다

    0x804a00c - 0x8 - 0x804b110 계산은 gdb에서 쉽게 가능하다.


    0xffffeef4를 두번쨰 malloc 사이즈에 넣어준다면 이만큼 할당을 해줄것이고, 다음 malloc이 된다면 free@got-4정도에 값을 쓰려할것이다. 




    TOP CHUNK또한 제대로 덮힌것을 확인 할 수 있다.


    이제 2번째 malloc에 우리가 원하는 free@got에 할당하기위해 0xffffeef4를 넣어보도록 하자



    free@got에는  0x8048300이란 값이 들어가있다. 그전에 우리가 할당해준 size값이 보인다. 


    0x109는 256바이트를 할당하면 주어지는 사이즈값이며, 그다음 우리가 써넣는 데이터가 들어가있다.


    free를 해줄경우 free@plt는 0x8048300값을 실행시키다가 죽는다.


    그럼 free@got값을 덮어쓸수있다는것인데, 0x42424242값으로 덮어써보자




    제대로 덮어쓰여진것을 확인 할 수 있다.


    system("/bin/sh")를 실행시켜주는 함수를  덮어준다면 바로 쉘을 획득 할 수 있다.






    'Hack > Pwnable' 카테고리의 다른 글

    [Heap exploit] fastbin unlink  (0) 2016.10.19
    [Heap exploit] unsafe_unlink  (0) 2016.10.18
    ringzer0 pwnx64  (0) 2016.10.02
    Use-After-Free GOT Overwrite  (2) 2016.10.02
    Heap with GDB!  (5) 2016.09.15

    댓글

Designed by Tistory.