[pwnable.kr] uaf - 8 pt

2018. 5. 31. 19:28


하늘을 나는 슬라임? 같은 녀석이다.

생각해보니 날개달린 슬라임은 한번도 본적없어...



Use After Free 문제이다. babyuaf라고 해도 될듯... 딱봐도 입문자를 위한 문제의 냄새가 난다.



접속해서 파일들을 보면 이전 문제와 다를게 없다. 차이점이라 할 정도라면 cpp소스라는거?

일단 소스를 보자


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
#include <fcntl.h>
#include <iostream> 
#include <cstring>
#include <cstdlib>
#include <unistd.h>
using namespace std;
 
class Human{
private:
    virtual void give_shell(){
        system("/bin/sh");
    }
protected:
    int age;
    string name;
public:
    virtual void introduce(){
        cout << "My name is " << name << endl;
        cout << "I am " << age << " years old" << endl;
    }
};
 
class Man: public Human{
public:
    Man(string name, int age){
        this->name = name;
        this->age = age;
    }
    virtual void introduce(){
        Human::introduce();
        cout << "I am a nice guy!" << endl;
    }
};
 
class Woman: public Human{
public:
        Woman(string name, int age){
                this->name = name;
                this->age = age;
        }
        virtual void introduce(){
                Human::introduce();
                cout << "I am a cute girl!" << endl;
        }
};
 
int main(int argc, char* argv[]){
    Human* m = new Man("Jack"25);
    Human* w = new Woman("Jill"21);
 
    size_t len;
    char* data;
    unsigned int op;
    while(1){
        cout << "1. use\n2. after\n3. free\n";
        cin >> op;
 
        switch(op){
            case 1:
                m->introduce();
                w->introduce();
                break;
            case 2:
                len = atoi(argv[1]);
                data = new char[len];
                read(open(argv[2], O_RDONLY), data, len);
                cout << "your data is allocated" << endl;
                break;
            case 3:
                delete m;
                delete w;
                break;
            default:
                break;
        }
    }
 
    return 0;    
}
 
cs


위와 같다.

uaf버그는 메모리를 할당하고 free한 후 다시 같은 크기의 메모리를 할당할 때 생기는 버그로 위에서 Man m을 free하고 after메뉴에서 m와 같은 크기로 메모리를 할당하게 되면 Man m이 할당되었던 장소를 재사용하게 되어 m이 free됬음에도 그 주소에 우리가 원하는 값을 새로 써 재사용할 수 있는 버그이다.


일단 void give_shell()이란 함수를 확인할 수 있으니 저걸 호출할 수 있으면 쉘을 딸수있어 Flag를 획득하기 좋을 것 같다. 

gdb-peda로 디버깅하면서 분석해봐야겠다. 그런데 2. after 메뉴가 메로리를 할당할때, 파일로 부터 읽어오므로 현폴더에는 권한이 없어 tmp폴더로 이동하여 진행하였다.



일단 use할 때 어떻게 진행되는지 보았다.  introduce()의 주소를 rdx에 넣어 call하게 되는것 같다. 

rdx에 넣기위해 rax에 먼저 값을 로드하고 거기에 8을 더한 주소에 값을 가져와 호출하게 되는 방식이다.



참고로 여기서 give_shell()함수의 주소를 찾을수 있었다. 0x401550에 주소가 저장되어있다.



일단 저렇게 넣어놓고, free한 후 after 2번을 통해 8바이트를 2번 할당해보았다. 

2번 할당한 이유는 m와 w 둘다 재사용하기 위해서이다. 안그러면 프로그램이 use에서 죽어버려서 ...

(여기서 8바이트로 할당한 이유는 m와 w가 둘다 introduce()라는 함수만 가지고 있어서 8바이트만 할당된것같다.)

(이게 그런데 문제서버말고 내 서버에서 컴파일해서 돌렸을 때는 48정도를 할당하지않으면 안덮여진다 ㅡㅡ;)



보면 알겠지만 rax가 0x41414141...49로 되어있다. 성공적으로 m과 w에 우리가 원하는 값이 재할당된것...

이제 저기에 0x401550-8의 값이 로드되게하면 된다.


1
uaf@ubuntu:/tmp/myria$ (python -'print("\x48\x15\x40\x00"+"\x00"*4)'> data
cs





성공~

'Wargame > Pwnable.kr' 카테고리의 다른 글

[pwnable.kr] leg  (0) 2018.06.08
[pwnable.kr] cmd2  (0) 2018.06.08
[pwnable.kr] passcode - 10 pt  (0) 2018.05.28
[pwnable.kr] echo1 - 25 pt (Only ROP!!)  (0) 2018.05.27
[pwnable.kr] echo1 - 25 pt  (0) 2018.05.26

+ Recent posts