ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • heap2 풀이
    System hacking training/Protostar 2018. 12. 22. 22:30
    [heap2.c]





























































    heap2는 heap overflow, use after free를 이용한 문제인것 같다.



















    코드상에 auth chunk의 데이터가 들어가는 주소를 출력해주는 부분이 있는데,

    이를 이용해서 쉽게 "you have logged in already!"라는 문구를 띄울 수 있다.

    처음 "auth "를 입력하면 auth구조체의 크기 만큼 malloc을 해주는데

    이 위치가 0x804c008이다.

    이후 service를 입력하면 0x804c018의 위치에 메모리를 할당 받고, string을 복사해주는데,

    이는 strdup()의 특성이다.

    strdup()는 malloc() + strcpy()인데,

    malloc()을 호출하여 string의 사본에 대한 기억장치 공간을 예약한다.

    예를 들어 strdup("hello")를 하게 될 경우

    h e l l o => 5 + 1을 하여 malloc(6)을 하고 이렇게 할당된 chunk에 hello라는 문자열을 복사해준다.

    아무튼 두 chunk간의 offset이 0x10 == 16인데

    이는 malloc(sizeof(auth))가 구조체의 크기만큼 heap을 할당하는게 아니라

    구조체 포인터 변수만큼의 크기를 할당받기 때문이다.

    일부러 헷갈리도록 구조체 이름과 포인터 변수 이름을 동일하게 해놓은 것 같다.

    따라서 chunk auth는 header(8byte) + mem(8byte) = 총 16byte의 크기를 갖는다.

    아무튼 이렇게 두 chunk간의 offset이 짧기 때문에 "service" + "16byte이상의 문자열"을 넣어주면

    "you have logged in already!"라는 문자열을 띄울 수 있다.

    위 그림처럼 ㅎ



    하지만 나는 이게 이 문제의 진짜 의도라고 생각을 하지 않는다.

    처음 이 문제의 메뉴를 봤을 때 생각난 취약점은 use-after-free 버그가 생각났다.

    # use
    if(strncmp(line, "auth ", 5) == 0) {
        auth = malloc(sizeof(auth));
        memset(auth, 0, sizeof(auth));
        if(strlen(line + 5) < 31) {
            strcpy(auth->name, line + 5);
        }
    }

    # free
    if(strncmp(line, "reset", 5) == 0) {
        free(auth);
        }

    # reuse
    if(strncmp(line, "service", 6) == 0) {
        service = strdup(line + 7);
        }

    use-after-free bug에 대해 공부한적이 있는데

    간단하게 어떤 버그인지만 알고 있다.

    일정 크기의 chunk를 할당 받고, free를 한 후 다시 똑같은 크기의 chunk를 할당하고자 할때

    이전 free했던 chunk를 재사용하기 때문에 생기는 버그라고 알고 있고,

    이를 이용하면 이 문제의 풀이가 가능하다.

    시나리오는 다음과 같다.

    1. "auth " + "A"*30하여 총 36byte의 chunk를 할당받는다.    // use
    2. "reset" 하여 할당했던 메모리를 free해준다.    // after free
    3. "service" 하여 freed chunk를 재할당 받는다.    // reuse
    4. "service" + "C"*20하여 총 20byte를 할당받으면서 해당 chunk에 값복사를 진행한다.    // auth->auth != 0
    4. "login" 하여 인증한다.

































    gdb로 디버깅을 하면서 해당 시나리오대로 진행을 해보았다.

    처음 바이너리를 실행 시키고, "auth "로 메모리 할당을 받았다.

    이후 heap을 살펴보면 0x10만큼의 크기를 갖은 chunk가 할당된 것을 확인할 수 있다.
























    "reset"으로 free해주면 A가 들어가있던 자리에 0으로 초기화된다.
























    이후 "service BBB"하여 같은 크기의 chunk를 할당 받으면

    이전에 free했던 chunk의 주소와 같은 곳을 가리키는 것을 확인할 수 있다.




























    다음으로 "service"+"C"*20하여 새로운 chunk를 할당 받음과 동시에 해당 chunk의 데이터 부분에 "C"로 도배해준다.

    이후 auth->auth가 아주 큰 수로 초기화 된것을 확인 할 수 있다.

    이상 풀이를 마친다.



    반응형

    'System hacking training > Protostar' 카테고리의 다른 글

    Stack7 풀이  (1) 2019.04.11
    heap1 풀이  (0) 2018.12.21
    heap0 풀이  (0) 2018.12.21
    Stack6 풀이  (0) 2018.02.16
    Stack4 풀이  (3) 2018.02.04
Designed by Tistory.