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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
        The Lord of the BOF : The Fellowship of the BOF
        - succubus
        - calling functions continuously
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <dumpcode.h>
 
// the inspector
int check = 0;
 
void MO(char *cmd)
{
        if(check != 4)
                exit(0);
 
        printf("welcome to the MO!\n");
 
        // olleh!
        system(cmd);
}
 
void YUT(void)
{
        if(check != 3)
                exit(0);
 
        printf("welcome to the YUT!\n");
        check = 4;
}
 
void GUL(void)
{
        if(check != 2)
                exit(0);
 
        printf("welcome to the GUL!\n");
        check = 3;
}
 
void GYE(void)
{
        if(check != 1)
                exit(0);
 
        printf("welcome to the GYE!\n");
        check = 2;
}
 
void DO(void)
{
        printf("welcome to the DO!\n");
        check = 1;
}
 
main(int argc, char *argv[])
{
        char buffer[40];
        char *addr;
 
        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }
 
        // you cannot use library
        if(strchr(argv[1], '\x40')){
                printf("You cannot use library\n");
                exit(0);
        }
 
        // check address
        addr = (char *)&DO;
        if(memcmp(argv[1]+44&addr, 4!= 0){
                printf("You must fall in love with DO\n");
                exit(0);
        }
 
        // overflow!
        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);
 
        // stack destroyer
        // 100 : extra space for copied argv[1]
        memset(buffer, 044);
        memset(buffer+48+10000xbfffffff - (int)(buffer+48+100));
 
        // LD_* eraser
        // 40 : extra space for memset function
        memset(buffer-300003000-40);
}
cs


소스가 너무 길어서 캡처하기 힘들어 긁어왔다.

딱봐도 함수 Chaining을 이용해 

DO - GYE - GUL - YUT - MO 순서로 함수를 실행시킨 뒤

MO 함수의 인자로 "/bin/sh"를 집어넣으라는 의미인 것 같다.



우선 GDB로 함수의 주소를 각각 구했고


(클릭하면 커집니다)

인자로 아무 값이나 주고 뒤에 /bin/sh 문자열을 넣어 주었다.



덤프된 코어 파일을 확인해 보니 /bin/sh 문자열의 주소는 0xbffffaac이다.



그대로 바꿔 주면 정상적으로 들어가고, 쉘을 딸 수 있다.

블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요




스택과 라이브러리로 점프하는 것이 불가능하다.

또 바이너리를 활용해야 한다.

우선 쉘코드를 올리고 해당 주소를 찾았다.

gdb로 돌리면서 argv[1]의 주소를 알아냈다. (어차피 코어 분석할거라 의미는 없다)

RET에 leave-ret을 집어넣는 것으로 Fake EBP 기법을 이용해 공격하기 위해 leave-ret 가젯을 구했다.

처음에 구한 주소는 되지 않았기에 core파일을 분석하여 내부에서 buffer의 주소를 찾고,

해당 주소-4를 SFP 자리에 집어넣어야 한다.

맨 처음 일어나는 leave로 인해 SFP에 집어넣은 주소에 EBP가 옮겨가고,

두 번째로 집어넣은 leave-ret 가젯으로 인해 한 번 더 leave가 실행되어 ESP가 buffer를 가리키게 되고

따라서 ret이 실행되면서 buffer의 첫 4바이트가 EIP에 들어가게 된다.

이를 이용해 공격에 성공했다.

블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요




문제에 딱히 어려운 개념은 없고 매우 간단한데 왜인지 잘 풀리지 않는 문제가 있었다.


SFP까지를 0으로 채워버리고 변조 가능한 것은 RET뿐인데 이 주소는 스택도, 라이브러리도 아니어야 한다고 한다.

그럼 바이너리 내에서 해답을 찾아야 하는데, RET에 ret명령을 집어넣으면 pop eip가 한번 더 실행되면서 뒤에 있는 값이 eip에 들어가게 된다.

이를 이용해 RET에 ret을, 이후는 shellcode의 주소를 집어넣어서 쉘을 따는데 성공했다.

블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요


자세한 건 생략하고, 이런 부분이 있다.

system 함수를 사용할 수 없고, 무조건 execve만을 사용해야 한다.

system 함수는 문자열 인자 하나만을 받았지만, execve는 다르다.

execve("/bin/sh", ["/bin/sh", 0], 0) 형식으로 실행해 주어야 하는데, 가장 귀찮은 것이 바로 두 번째 인자이다.

char형 이중 포인터인데다 배열의 첫 번째 값으로는 "/bin/sh" 첫번째 인자와 같은 값이 든 주소가 있어야 한다. 왜냐하면 execve 함수의 두번째 인자는 실행할 파일의 인자로, "/bin/sh"를 실행하면 argv[0]이 당연히 "/bin/sh"가 되어야 하기 때문이다.


조금 귀찮긴 하지만 findsh를 이용해 일단 라이브러리 내부의 "/bin/sh"의 주소를 구하고, 파일에 심볼릭 링크로 해당 주소를 넣어 주었다. 그리고 gdb를 이용해 분석하여 스택 끝부분에 들어 있는 파일명+NULL을 가져와 각각의 인자로 주었다.

이는 전에 skeleton을 공략할 때(http://5kyc1ad.tistory.com/44) 사용했던 스택 레이아웃을 보면 알 수 있다.

이는 다음과 같은데, 프로그램명 다음에 NULL이 기본으로 붙는 것을 볼 수 있다.


'Wargame > Lord of Buffer overflow' 카테고리의 다른 글

LOB Redhat : assassin > zombie_assassin  (0) 2015.11.16
LOB Redhat : giant > assassin  (0) 2015.11.03
LOB Redhat : bugbear > giant  (0) 2015.11.03
LOB Redhat : darkknight > bugbear  (0) 2015.11.02
LOB Redhat : golem > darkknight  (0) 2015.10.17
LOB Redhat : skeleton > golem  (0) 2015.10.15
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요


이번엔 스택에서 공격할 수 없게 된 모양이다.

드디어 RTL 공격 기법을 사용하는 문제가 나타났다.


아무 실행 파일이나 만들어서 system 함수의 라이브러리 주소를 찾은 후, 이를 이용해 내부의 "/bin/sh" 문자열을 찾아 주었다.


Dummy 44개 이후 System 함수 주소 + Dummy (4) + &"/bin/sh"를 넣어 주었다.

쉘을 획득했고 이를 이용해 패스워드를 얻을 수 있었다.

RTL 공격에 대해서는 직접 작성한 문서(http://5kyc1ad.tistory.com/3)가 있다.

이해가 안 되는 분들은 읽어보는 것도 좋을 듯 하다.


'Wargame > Lord of Buffer overflow' 카테고리의 다른 글

LOB Redhat : giant > assassin  (0) 2015.11.03
LOB Redhat : bugbear > giant  (0) 2015.11.03
LOB Redhat : darkknight > bugbear  (0) 2015.11.02
LOB Redhat : golem > darkknight  (0) 2015.10.17
LOB Redhat : skeleton > golem  (0) 2015.10.15
LOB Redhat : vampire > skeleton  (0) 2015.10.15
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요


해커스쿨 문제를 푸는 중 가장 마음에 들면서도 감명받은 문제.

FPO의 개념을 여기서 처음 알았고, 가장 처음 공부할 때 혼자 어떻게 공격할지 엄청 고민하면서 며칠을 보냈고

결국 이해하면서 큰 전율을 느꼈었다.

BoB 면접 때도 이걸로 발표했을 만큼 꽤 좋아하는 공격 방식이다.

이 문제에서는 problem_child라는 다른 함수가 이미 존재하고, 그 안의 버퍼를 넘치게 하는 방식이므로 어려울 것도 없다.

흔히 말하는 1바이트 오버플로우 문제인데, 더미가 없는 관계로 저부분은 바로 SFP이다.

SFP 1바이트를 덮어쓸 수 있고, main 외의 다른 함수 내의 버퍼를 오버플로우 할 수 있다는 말은 FPO의 위험을 가지고 있다는 것이다.

해당 함수의 에필로그 + 메인 함수의 에필로그로 총 두 번의 leave와 ret이 일어나기 때문에 SFP의 변조는 곧 EIP의 변조로 이어질 수 있다.


환경변수에 쉘코드를 올리고 해당 주소를 구한 후 EIP에 들어갈 값인 BUF의 첫 4바이트를 해당 쉘코드의 주소로 주었다.

그리고 마지막 1바이트를 오버플로우 할 때 BUF주소의 -4바이트를 준다.

이 이유는 leave-ret이 한 번 일어나면서 EBP가 변조된 EBP로 이동된 후, 한번 더 leave-ret을 할 때 leave에서 pop ebp를 진행해 버리기 때문에 ret에서 pop을 할 경우 BUF의 첫 4바이트를 참조하게 하기 위함이다.

따라서 마지막 1바이트에서 BUF 주소를 그대로 집어넣으면 BUF의 처음에 4바이트 더미를 주고 쉘코드의 주소를 넣어야 한다.

간단하게 주소를 찾고 공격에 성공하였다.

'Wargame > Lord of Buffer overflow' 카테고리의 다른 글

LOB Redhat : bugbear > giant  (0) 2015.11.03
LOB Redhat : darkknight > bugbear  (0) 2015.11.02
LOB Redhat : golem > darkknight  (0) 2015.10.17
LOB Redhat : skeleton > golem  (0) 2015.10.15
LOB Redhat : vampire > skeleton  (0) 2015.10.15
LOB Redhat : troll > vampire  (0) 2015.10.15
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요



이번엔 skeleton에서 사용했던 방식을 사용할 수 없도록 버퍼에서부터 스택 끝부분까지를 전부 0으로 초기화한다.

이럴 때는 공유 라이브러리에 원하는 코드를 올려서 사용하면 된다.



스택 영역 바로 아랫부분에 공유 라이브러리 영역이 있는 것을 확인할 수 있다.

(이미지 출처 : http://lapislazull.tistory.com/61)

문제에서 0으로 초기화하는 부분은 스택에서 윗부분이므로 아랫부분인 공유 라이브러리 부분은 그대로이다.

아무 컴파일 가능한 c 파일을 하나 만들어서 컴파일을 하는데,

옵션으로 shared와 fPIC를 준다.

shared는 말 그대로 공유 라이브러리를 먼저 참조하라는 의미이고, fPIC는 심볼이 어느 위치에 있건 동작이 가능하도록 컴파일하라는 옵션이라고 한다.

만들어질 파일 명을 NOP와 쉘코드를 포함하여 만들고,

LD_PRELOAD 환경변수에 등록한다.

LD_PRELOAD는 파일 실행 시 Dynamic Linker가 선택된 파일을 무조건 선적재한다.

따라서 이렇게 환경변수에 올려주면 공유 라이브러리로 무조건 해당 파일이 올라온다.

메모리상에서 NOP+SHELLCODE의 주소를 찾아냈고,

해당 주소를 넣어주어 공격에 성공했다.

'Wargame > Lord of Buffer overflow' 카테고리의 다른 글

LOB Redhat : darkknight > bugbear  (0) 2015.11.02
LOB Redhat : golem > darkknight  (0) 2015.10.17
LOB Redhat : skeleton > golem  (0) 2015.10.15
LOB Redhat : vampire > skeleton  (0) 2015.10.15
LOB Redhat : troll > vampire  (0) 2015.10.15
LOB Redhat : orge > troll  (0) 2015.10.13
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요



argv[0]부터 입력한 argv를 모두 0으로 초기화시키는 부분이 붙었다.

심볼릭 링크를 걸어 파일명에 쉘코드를 넣어 주었는데,

실제로 디버깅하며 확인해 본 결과 메모리에 argv[0]은 전부 0으로 초기화된 것을 볼 수 있었다.

하지만 스택의 더 윗부분을 확인하면 이렇게 파일명이 그대로 들어있는 부분을 볼 수 있다.

이는 스택 레이아웃이 argv[0] 말고도 구조상 파일명을 포함하고 있기 때문이다.

https://www.win.tue.nl/~aeb/linux/hh/stack-layout.html

여기에 자세히 나와 있다.

어쨌든 찾은 위치로 리턴시켜 공격에 성공하였다.

'Wargame > Lord of Buffer overflow' 카테고리의 다른 글

LOB Redhat : golem > darkknight  (0) 2015.10.17
LOB Redhat : skeleton > golem  (0) 2015.10.15
LOB Redhat : vampire > skeleton  (0) 2015.10.15
LOB Redhat : troll > vampire  (0) 2015.10.15
LOB Redhat : orge > troll  (0) 2015.10.13
LOB Redhat : darkelf > orge  (0) 2015.10.13
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요


이번엔 RET을 덮어씌우는 주소값의 첫 바이트가 '\xbf' 이면서도

두 번째 바이트가 '\xff'일 경우 프로그램을 종료시켜 버린다.

argv[2]를 엄청 많은 값으로 집어넣고 거기로 리턴시켜 공격하기로 했다.

NOP를 대략 10만 개 정도를 주었고,

거기에 집어넣어서 공격에 성공하였다.



'Wargame > Lord of Buffer overflow' 카테고리의 다른 글

LOB Redhat : skeleton > golem  (0) 2015.10.15
LOB Redhat : vampire > skeleton  (0) 2015.10.15
LOB Redhat : troll > vampire  (0) 2015.10.15
LOB Redhat : orge > troll  (0) 2015.10.13
LOB Redhat : darkelf > orge  (0) 2015.10.13
LOB Redhat : wolfman > darkelf  (0) 2015.10.13
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요



쉘코드에 \x2f가 들어갈 경우 '/' 로 취급해버려 원래 좀 힘든 문제였지만,

이쯤 되니 슬슬 쉘코드를 제작하게 되어 \x2f가 없는 쉘코드를 직접 만들었다.


argv[0]에 집어넣고 거기로 리턴하여 공격하기 위해 NOP+SHELLCODE로 심볼릭 링크를 걸었고,

거기로 리턴하기 위해 몇 번 시도하여 결국 성공하였다.


만들어서 사용한 쉘코드는 다음과 같다.

사용할 사람은 사용하시길.

하지만 setreuid같은 것 없이 간단하게 execve만 하는 소스다 보니 다른 버전의 문제에서는 먹히지 않을 수도 있다.


\x6a\x0b\x58\x99\x52\xbe\x21\x21\x73\x68\x66\x81\xc6\x0e\x0e\x56

\xbe\x2e\x62\x69\x6e\x46\x56\x89\xe3\x52\x53\x89\xe1\xcd\x80

'Wargame > Lord of Buffer overflow' 카테고리의 다른 글

LOB Redhat : vampire > skeleton  (0) 2015.10.15
LOB Redhat : troll > vampire  (0) 2015.10.15
LOB Redhat : orge > troll  (0) 2015.10.13
LOB Redhat : darkelf > orge  (0) 2015.10.13
LOB Redhat : wolfman > darkelf  (0) 2015.10.13
LOB Redhat : orc > wolfman  (0) 2015.10.13
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요