[Pwnable.kr] uaf
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
#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


Use After Free 취약점은 Heap 영역의 Allocation/Free에서 발생할 수 있는 취약점입니다. 컴퓨터는 보통 실행 시간을 위해 객체를 Free하고 나더라도 메모리 상에서 객체가 점유하고있던 공간의 값을 없애버리지는 않습니다. 거기에 접근할 수 있는 포인터만 지웁니다. 즉 지워졌다고 생각한 정보가 사실은 지워졌지 않을 수 있습니다. 이것만으로도 안 좋은 상황을 만들어낼 수 있는데 한 술 더 떠 Reallocation을 할 때 만약 이전의 객체와 동일한 크기를 요구한다면 컴퓨터는 실행 시간을 위해 이전의 객체가 점유하던 메모리 영역을 그대로 넘겨줍니다. 즉 새로운 객체는 이전의 영역을 마음대로 조작할 수 있게 되고, 그 상황에서 새로운 객체가 동일한 메모리에 접근했음을 모르는 선량한 사용자가 메모리 값을 참조해 무언가를 실행할 경우 해킹의 가능성이 존재합니다.


위의 코드에서 저희는 introduce() 함수를 실행하거나, 내가 만든 임의의 파일의 값을 새로 생성한 data 객체에 쓰거나, m, w 객체를 제거하는 세 가지 행동을 할 수 있습니다. 공격 시나리오는 아래와 같을 것입니다.


1. free를 이용해 m, w 객체를 Free 시킨다. 이게 선행되지 않으면 객체 내의 값들을 마음대로 바꿀 수 없습니다.


2. after를 이용해 introduce() 함수를 실행할 때 give_shell() 함수가 실행되게끔 한다. 이를 위해서는 코드를 바꾸거나 introduce()를 가리키는 포인터의 값을 바꿔야하는데 딱 봐도 후자가 더 쉬울 것 같네요.


3. use를 통해 introduce() 함수(로 위장된 give_shell() 함수)를 실행한다.


그러면 이제 객체의 크기는 얼마인지, introduce()를 가리키는 포인터의 값은 어떻게 바꿀지 일단 readelf로 싹 긁어서 최대한 뽑을 수 있는 정보를 다 뽑고 부족한게 있다면 동적 분석을 해보겠습니다.



Symbol table '.symtab' contains 119 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     5: 00000000004002d8     0 SECTION LOCAL  DEFAULT    5
     6: 00000000004005f0     0 SECTION LOCAL  DEFAULT    6
     7: 00000000004008a6     0 SECTION LOCAL  DEFAULT    7
     8: 00000000004008e8     0 SECTION LOCAL  DEFAULT    8
     9: 0000000000400958     0 SECTION LOCAL  DEFAULT    9
    10: 00000000004009d0     0 SECTION LOCAL  DEFAULT   10
    11: 0000000000400c28     0 SECTION LOCAL  DEFAULT   11
    12: 0000000000400c40     0 SECTION LOCAL  DEFAULT   12
    13: 0000000000400de0     0 SECTION LOCAL  DEFAULT   13
    14: 0000000000401488     0 SECTION LOCAL  DEFAULT   14
    15: 00000000004014a0     0 SECTION LOCAL  DEFAULT   15
    16: 0000000000401600     0 SECTION LOCAL  DEFAULT   16
    17: 0000000000401680     0 SECTION LOCAL  DEFAULT   17
    18: 00000000004018a4     0 SECTION LOCAL  DEFAULT   18
    19: 0000000000601de0     0 SECTION LOCAL  DEFAULT   19
    20: 0000000000601de8     0 SECTION LOCAL  DEFAULT   20
    21: 0000000000601df8     0 SECTION LOCAL  DEFAULT   21
    22: 0000000000601e08     0 SECTION LOCAL  DEFAULT   22
    23: 0000000000601e10     0 SECTION LOCAL  DEFAULT   23
    24: 0000000000601fe0     0 SECTION LOCAL  DEFAULT   24
    25: 0000000000601fe8     0 SECTION LOCAL  DEFAULT   25
    26: 00000000006020c8     0 SECTION LOCAL  DEFAULT   26
    27: 00000000006020e0     0 SECTION LOCAL  DEFAULT   27
    28: 0000000000000000     0 SECTION LOCAL  DEFAULT   28
    29: 0000000000400e0c     0 FUNC    LOCAL  DEFAULT   13 call_gmon_start
    30: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    31: 0000000000601de8     0 OBJECT  LOCAL  DEFAULT   20 __CTOR_LIST__
    32: 0000000000601df8     0 OBJECT  LOCAL  DEFAULT   21 __DTOR_LIST__
    33: 0000000000601e08     0 OBJECT  LOCAL  DEFAULT   22 __JCR_LIST__
    34: 0000000000400e30     0 FUNC    LOCAL  DEFAULT   13 __do_global_dtors_aux
    35: 00000000006023d8     1 OBJECT  LOCAL  DEFAULT   27 completed.6531
    36: 00000000006023e0     8 OBJECT  LOCAL  DEFAULT   27 dtor_idx.6533
    37: 0000000000400ea0     0 FUNC    LOCAL  DEFAULT   13 frame_dummy
    38: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    39: 0000000000601df0     0 OBJECT  LOCAL  DEFAULT   20 __CTOR_END__
    40: 00000000004018a0     0 OBJECT  LOCAL  DEFAULT   17 __FRAME_END__
    41: 0000000000601e08     0 OBJECT  LOCAL  DEFAULT   22 __JCR_END__
    42: 0000000000401450     0 FUNC    LOCAL  DEFAULT   13 __do_global_ctors_aux
    43: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS uaf.cpp
    44: 00000000006023e8     1 OBJECT  LOCAL  DEFAULT   27 _ZStL8__ioinit
    45: 0000000000401124    64 FUNC    LOCAL  DEFAULT   13 _Z41__static_initializati
    46: 0000000000401164    21 FUNC    LOCAL  DEFAULT   13 _GLOBAL__sub_I_main
    47: 0000000000401530     8 OBJECT  LOCAL  DEFAULT   15 _ZZL18__gthread_active_pv
    48: 0000000000601fe8     0 OBJECT  LOCAL  DEFAULT   25 _GLOBAL_OFFSET_TABLE_
    49: 0000000000601de8     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_end
    50: 0000000000601de0     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_start
    51: 0000000000601e10     0 OBJECT  LOCAL  DEFAULT   23 _DYNAMIC
    52: 00000000006020c8     0 NOTYPE  WEAK   DEFAULT   26 data_start
    53: 00000000006020e0   280 OBJECT  GLOBAL DEFAULT   27 _ZSt3cin@@GLIBCXX_3.4
    54: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSsC1Ev@@GLIBCXX_3.4
    55: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSolsEi@@GLIBCXX_3.4
    56: 0000000000401440     2 FUNC    GLOBAL DEFAULT   13 __libc_csu_fini
    57: 00000000004015d0    24 OBJECT  WEAK   DEFAULT   15 _ZTI3Man
    58: 0000000000400de0     0 FUNC    GLOBAL DEFAULT   13 _start
    59: 0000000000401580    32 OBJECT  WEAK   DEFAULT   15 _ZTV5Human
    60: 0000000000401192   125 FUNC    WEAK   DEFAULT   13 _ZN5Human9introduceEv
    61: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    62: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
    63: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _Znam@@GLIBCXX_3.4
    64: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZdlPv@@GLIBCXX_3.4
    65: 0000000000401488     0 FUNC    GLOBAL DEFAULT   14 _fini
    66: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSt8ios_base4InitC1Ev@@
    67: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND read@@GLIBC_2.2.5
    68: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    69: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND system@@GLIBC_2.2.5
    70: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_atexit@@GLIBC_2.2.5
    71: 000000000040123a    41 FUNC    WEAK   DEFAULT   13 _ZN5HumanD1Ev
    72: 0000000000400ce0     0 FUNC    GLOBAL DEFAULT  UND _ZNSt8ios_base4InitD1Ev@@
    73: 00000000004015e8     7 OBJECT  WEAK   DEFAULT   15 _ZTS5Human
    74: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZStlsISt11char_traitsIcE
    75: 0000000000401308   109 FUNC    WEAK   DEFAULT   13 _ZN5WomanC1ESsi
    76: 00000000004014a0     4 OBJECT  GLOBAL DEFAULT   15 _IO_stdin_used
    77: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSsD1Ev@@GLIBCXX_3.4
    78: 00000000004015c8     5 OBJECT  WEAK   DEFAULT   15 _ZTS3Man
    79: 00000000006020c8     0 NOTYPE  GLOBAL DEFAULT   26 __data_start
    80: 0000000000602200    88 OBJECT  WEAK   DEFAULT   27 _ZTVN10__cxxabiv117__clas
    81: 00000000004015b0    24 OBJECT  WEAK   DEFAULT   15 _ZTI5Woman
    82: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSsC1EPKcRKSaIcE@@GLIBC
    83: 0000000000401560    32 OBJECT  WEAK   DEFAULT   15 _ZTV3Man
    84: 0000000000602260   272 OBJECT  GLOBAL DEFAULT   27 _ZSt4cout@@GLIBCXX_3.4
    85: 000000000040117a    24 FUNC    WEAK   DEFAULT   13 _ZN5Human10give_shellEv
    86: 00000000006020d0     0 OBJECT  GLOBAL HIDDEN    26 __dso_handle
    87: 0000000000401376    54 FUNC    WEAK   DEFAULT   13 _ZN5Woman9introduceEv
    88: 0000000000601e00     0 OBJECT  GLOBAL HIDDEN    21 __DTOR_END__
    89: 00000000004013b0   137 FUNC    GLOBAL DEFAULT   13 __libc_csu_init
    90: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND atoi@@GLIBC_2.2.5
    91: 0000000000401210    41 FUNC    WEAK   DEFAULT   13 _ZN5HumanC2Ev
    92: 0000000000401210    41 FUNC    WEAK   DEFAULT   13 _ZN5HumanC1Ev
    93: 0000000000401540    32 OBJECT  WEAK   DEFAULT   15 _ZTV5Woman
    94: 0000000000401264   109 FUNC    WEAK   DEFAULT   13 _ZN3ManC1ESsi
    95: 00000000006020d8     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    96: 0000000000602380    88 OBJECT  WEAK   DEFAULT   27 _ZTVN10__cxxabiv120__si_c
    97: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZStlsIcSt11char_traitsIc
    98: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSaIcED1Ev@@GLIBCXX_3.4
    99: 0000000000401308   109 FUNC    WEAK   DEFAULT   13 _ZN5WomanC2ESsi
   100: 0000000000401264   109 FUNC    WEAK   DEFAULT   13 _ZN3ManC2ESsi
   101: 00000000004015f0    16 OBJECT  WEAK   DEFAULT   15 _ZTI5Human
   102: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND pthread_cancel
   103: 00000000006023f0     0 NOTYPE  GLOBAL DEFAULT  ABS _end
   104: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSolsEPFRSoS_E@@GLIBCXX
   105: 00000000004015a0     7 OBJECT  WEAK   DEFAULT   15 _ZTS5Woman
   106: 0000000000400d60     0 FUNC    GLOBAL DEFAULT  UND _ZSt4endlIcSt11char_trait
   107: 00000000006020d8     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
   108: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSaIcEC1Ev@@GLIBCXX_3.4
   109: 0000000000400d80     0 FUNC    GLOBAL DEFAULT  UND __gxx_personality_v0@@CXX
   110: 00000000004012d2    54 FUNC    WEAK   DEFAULT   13 _ZN3Man9introduceEv
   111: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _Znwm@@GLIBCXX_3.4
   112: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _Unwind_Resume@@GCC_3.0
   113: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSsaSERKSs@@GLIBCXX_3.4
   114: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND open@@GLIBC_2.2.5
   115: 0000000000400ec4   608 FUNC    GLOBAL DEFAULT   13 main
   116: 0000000000400c28     0 FUNC    GLOBAL DEFAULT   11 _init
   117: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSirsERj@@GLIBCXX_3.4
   118: 000000000040123a    41 FUNC    WEAK   DEFAULT   13 _ZN5HumanD2Ev



보고싶은 주소값들이 얼추 다 들어있네요. symbol이 제거가 안되서 편하네요.



이제 Woman->introduce()의 값이 어떻게 저장되는지만 확인하면 될 것 같습니다.  gdb로 따라가면서 확인해보겠습니다.



disas main을 해보면 switch문 분기점으로 추정되는 부분을 알 수 있습니다. 이제 저희는 write하는 부분을 보고싶으니  case 2에 해당하는 *main+316에 breakpoint를 걸고 after를 선택해 진행해보겠습니다.



ing


'워게임 > Pwnable.kr' 카테고리의 다른 글

[Pwnable.kr] cmd2  (0) 2018.01.15
[Pwnable.kr] cmd1  (0) 2018.01.15
[Pwnable.kr] lotto  (0) 2018.01.15
[Pwnable.kr] blackjack  (0) 2018.01.15
[Pwnable.kr] coin1  (3) 2018.01.15
[Pwnable.kr] shellshock  (0) 2018.01.15
  Comments