ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • LEVEL 18 nightmare write-up
    System hacking training/Hackerschool LOB 2018. 6. 27. 09:03

    succubus -> nightmare

    nightmare문제를 풀었으니 LOB도 얼마 남지 않았네요 ㅎ

    생각해보면 꽤 오래 끌었군요...!

    FTZ 는 6개월 정도가 걸린것 같은데 LOB도 3개월 정도 걸리겠네요 ㅎㅎ (언제 갓되는지..)

    암튼 문제는 이렇습니다.

    코드 분석부터 하겠습니다.

    1. 인자에 바이너리명 빼고 한개 더 줘야한다.

    2. check address에서 char 형 포인터 변수 addr에 strcpy()의 PLT를 받아와서 argv[1]+44 즉 ret 공간의 주소값과 memcmp()를 통해 비교를 하여 다르다면 예외처리를 하며 바이너리를 종료한다.

    3. overflow! 부분에서 strcpy()를 이용하여 buffer에 argv[1]의 값을 때려박는다.

    4. dangerous waterfall 부분에서 memset()으로 ret + 4 즉 strcpy()가 호출되고 return 할 다음 주소를 AAAA로 세팅하고 종료된다.(check address 부분에서 예외처리 되지 않고 잘 들어왔다면 ret공간에 strcpy()의 plt 주소가 있으므로 strcpy() 다음으로 실행될 주소가 AAAA로 세팅된다.)

    코드를 분석했을 때 bof가 터지는 곳은 주석처리로 되어 쉽게 확인할 수 있고, 먼저 바이너리를 실행시키기 위해서는 strcpy()의 plt 주소를 알아야겠습니다.

    그리하여 tmp 디렉토리를 생성하고 해당 바이너리를 복사한 뒤 gdb로 strcpy()의 plt 주소를 확인하였습니다.

    맞는지 확인해보면 이 처럼 예외처리 되지 않고 segmentation fault가 뜨며 core 파일을 생성해주는 것을 알 수 있습니다.

    이 문제를 풀때 저와 같은 분들이라면 strcpy()의 plt 주소를 찾고 바이너리를 실행시키는 것 까지는 쉽게 할 수 있을 것같습니다.

    하지만 문제가 하나 더 있죠.

    overflow가 일어나서 ret공간에 strcpy()의 plt가 들어가고 그로 인해서 strcpy()가 호출되는데 문제는 저희가 원하는 것은 쉘이죠..? 쉘을 띄울 수 없다는 문제가 생깁니다.

    여기서 생각을 해보면 strcpy()는 string복사를 하는 함수입니다.

    원형을 보면 이러합니다.

    #include <string.h>
    char *strcpy(char *string1, const char *string2);

    string2를 string1에 복사를 합니다.

    그렇다는것은 현재 페이로드

    dummy(44byte) + strcpy@plt(4byte) + AAAA(set) + string1 + string2

    여기서 string1에는 AAAA가 들어가는 위치의 주소를 넣고 string2에는 쉘코드의 주소를 가진 주소를 넣어주면 되겠습니다.

    원형에서도 보았듯이 strcpy()의 인자는 char 형 포인터입니다.

    문자열을 다루기 때문에 당연하다고 생각을 하는데, 만약 string2에 쉘코드의 주소를 넣었다면 어떻게 될까요? 쉘코드의 주소에 있는 값을 복사 시킴으로서 eip에 쉘코드의 주소가 아닌 쉘코드 자체가 들어가게 됩니다.

    위와 같은 이유때문에 쉘코드의 주소를 가리키는? 혹은 쉘코드의 주소를 가진 주소를 string2에 집어넣어야 정확하게 실행 흐름을 조작할 수 있습니다.

    (구글 에드센스 때문에 글이 다소 많네요..그림보다는 글이 많아야한다는....)

    어쨎든 그만 설명하고 보여드리겠습니다.

    저는 쉘코드를 환경변수에 올리고 그 환경변수의 주소를 가진 환경변수2를 만들었는데요.

    fkillrra 라는 환경변수에 NOP code와 쉘코드를 넣고 그 주소를 출력하는 프로그램 하나를 간단히 만들어준 뒤 그 주소를 환경변수2인 fkillrra2에 넣어주고 fkillrra2 즉 쉘코드의 주소를 가진 환경변수의 주소를 구하였습니다. (말이 어렵네요..)

    이렇게 해서 페이로드의 구성 요소중 string2에 해당하는 부분을 구했네요.

    이제 string1에 해당 하는 부분인 바이너리 종료직전 AAAA로 세팅이 되는 그 부분의 주소를 확인해 봅시다.

    crash를 일으켜 core 파일을 생성한 뒤 이 파일을 통해 ret의 주소를 찾을 수 있는데요.

    여기서 0x41414141 이 두개가 있는데 이 중 하나가 strcpy()가 호출된 후 return address가 들어가는 주소입니다.(의식의 흐름으로 풀었을때 뒤의 주소를 사용했는데... 왜 그런지는 잘 모르겠네요ㅠ)

    그리하여 얻은 ret 주소 : 0xbffffa10

    이제 페이로드에 필요한 준비물들이 완성되었으니 익스를 해봅시다~

    tmp 디렉토리에서는 쉘이 뜨지 않지만 원래의 디렉토리로 돌아와서 익스하니 쉘이 뜨네요.ㅎㅎ

    뭔가 찜찜하지만 풀었습니다. ㅇㅅㅇ..;

    반응형

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

    LEVEL 20 death_knight write-up  (0) 2018.10.04
    LEVEL 19 xavius write-up  (0) 2018.08.12
    LEVEL 17 succubus write-up  (1) 2018.05.17
    LEVEL 16 zombie_assassin write-up  (0) 2018.05.13
    LEVEL 15 assassin write-up  (0) 2018.05.13
Designed by Tistory.