본문으로 바로가기

해커스쿨 FTZ level15

category Wargame/FTZ 2018. 8. 4. 21:52

level15 --- guess what




우선 level15의 디렉터리를 확인한다.



attackme라는 의심스러운 파일이 존재한다. attackme는 level16의 권한을 가지고 있고, setuid가 걸려있는 파일이다.



우리가 공격할 대상이 attackme일 가능성이 크다고 생각하고 hint를 보자.





hint를 보면 check가 가리키는 포인터 변수에 0xdeadbeef가 저장되어 있으면 level16(3096)의 쉘을 띄워준다.

level14는 변수에 0xdeadbeef를 저장시키는 것이고 level15은 변수에 저장된 포인터 변수에 0xdeadbeef을 저장시키는 문제이다.


위와 같이 변수를 선언하면 int crap(4 byte), int *check(4 byte), char buf[20](20byte)를 통해 0x1C(28byte)가 할당된다고 예상할 수 있다.


실제로 gdb를 통해 /home/level15/attackme 파일이 0x1C(28byte)만큼 할당되었는지 확인해보자.



 


실제로 gdb를 통해 확인해보면, 0x38(56 byte)가 할당된 것을 확인할 수 있다.

level14와 마찬가지로 dummy값이 gcc에 의해 삽입된것을 확인할 수 있다.


예제 소스를 통해 dummy가 어디부분에 얼마만큼 삽입되었는지 확인하자.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <unistd.h>
 
int main()
{
        int crap;
        int *check;
        char buf[20];
        fgets(buf,45,stdin);
 
        if(*check == 0xdeadbeef)
        {
                setreuid(30953095);
                system("/bin/sh");
        }
 
        printf(" Input:  %s\n &buf  : %p\n &check: %p\n &crap : %p\n", buf, buf, &check, &crap);
}
 
cs



gcc로 컴파일 하면 아래와 같은 정보를 얻을 수 있다.





위의 정보를 바탕으로 메모리 구조를 그려보면 아래와 같이 그릴 수 있다.



우리는 단순히 check 변수의 값을 바꾸는 것이 아니라 check 포인터 변수가 가리키는 값을 수정해야 한다.

check 포인터 변수가 가리키는 값을 바꾸기 위해서 먼저 메모리에 0xdeadbeef 값을 올리고 이 메모리 주소를 check로 덮어 써야한다.


그렇다면 어느공간에 우리가 0xdeadbeef값을 써야할까?

간단히 말하면 buf[20] 혹은 환경변수가 될 것이다.


지금까지 공부한것을 바탕으로 level15를 분석해보자.


메모리 구조를 바탕으로 확인하면 0xbfffee48은 check의 포인터 변수를 가르킨다.

확인해보면, 0xbffee68을 가리키고 있다.





위를 바탕으로 다시 메모리 구조를 그려보면 아래와 같이 이해할 수 있다.




이제 attackme를 공격해보자.


처음 buf에 입력해서 buf 주소를 check에 덮어 공격하려 했지만 아래와 같이 주소가 계속 변경되어서 공격하기가 어렵다.



조금 더 쉽게 공격하기 위해서 환경변수를 이용하여 공격할 것이다.


환경변수의 주소를 얻기 위한 소스는 아래와 같이 작성하였다.



1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(int argc, char *argv[])
{
        char *ptr;
 
        ptr = getenv(argv[1]);
        ptr += (strlen(argv[0]) - strlen(argv[2])) * 2;
        printf("%s will be at %p\n", argv[1], ptr);
}
 
cs



아래와 같이 환경변수를 check 포인터 변수에 로드하면 쉘을 딸 수 있다.














'Wargame > FTZ' 카테고리의 다른 글

해커스쿨 FTZ level17  (0) 2018.08.04
해커스쿨 FTZ level16  (0) 2018.08.04
해커스쿨 FTZ level14  (0) 2018.08.02
해커스쿨 FTZ level13 (스택 가드)  (0) 2018.08.02
해커스쿨 FTZ level12 (버퍼 오버 플로우)  (0) 2018.08.01