보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

pwnable.kr - wtf (100pt)

2016. 1. 15. 09:39

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.



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이다.



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

'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
블로그 이미지

__미니__

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

,

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

pwnable.kr - tiny_easy (30pt)

2015. 11. 26. 01:56

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

pwnable.kr - brain fuck (150pt)

2015. 11. 26. 01:45

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.




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

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

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

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에 들어가게 된다.

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

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

LOB Redhat : zombie_assassin > succubus  (0) 2015.12.24
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
블로그 이미지

__미니__

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 : 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 : 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 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,