본문 바로가기

카테고리 없음

OWASP UnCrackable-Level3

SMALL

OWASP UnCrackable Level3 풀이

공개되어 있는 많은 풀이가 있지만, 내가 풀때는 뭔가 잘되지 않았다. 아래와 같은 부분에서 차이가 있었다.
+ nox에서 libc 후킹등.. 뭔가 잘 안되어서, 루팅된 폰으로 수행하였다.

1. ststr 우회, foo.so가 너무 빨리 로드되서 계속 후킹 시점이 문제가 되었다.
   그래서 foo.so 로드되기 전, 내 훅 코드가 설치될수 있게, Sleep을 사용하였다.

2. code hooking, 다른 풀이에서 baseAddress + offset으로 소개되어 있는데, 안되었다.
   분석해 보니, arm thumb모드였는데 어떻게 가능했는지 잘 모르겠지만.. 그래서 해당 부분 후킹할때 주소 값부분을
   처리하였다.

분석 내용 정리는 너무 다른데 잘되어 있어서.. 그래도 시간남으면 정리삼아 나중에 올려보려한다.

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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    //hook flag 
    var hFlag = false;
 
    function hookCode(){
 
        //Get The library of libfoo.so BaseAddress
        var barPtr = Module.findBaseAddress('libfoo.so');
        console.log("[*] BaseAddress libfoo.so", barPtr);
 
        //Arm Thumb mode hook Addr + 1
        //Calc targetAddress using BaseAddress and offset
        var targetCheckLen = barPtr.add(0x25f8 +1);
        var getValue = barPtr.add(0x260C + 1);
 
        /*
            Debug Code
            Is it right addr and data??
        */
        //console.log(hexdump(targetCheckLen));
        
        
        Interceptor.attach(targetCheckLen, {
            onEnter: function(args) {
              //console.log('Context  : ' + JSON.stringify(this.context));
              //bypass len check
              this.context.r0=0x18;
                
            },
            onLeave: function(retval) {
 
                
            }
        });
    
 
        Interceptor.attach(getValue, {
            onEnter: function(args) {
              //console.log('Context  : ' + JSON.stringify(this.context));
              //change r1 value to bypass check routine
              this.context.r1 = this.context.r2
              console.log(this.context.r1.toString())
                
            },
            onLeave: function(retval) {
 
                
            }
        });      
 
    }
 
 
    //dlopen function hooking
    Interceptor.attach(Module.findExportByName(null"dlopen"), {
    onEnter: function(args) {
        this.arg0 = Memory.readUtf8String(args[0]);
        this.fooFlag = false;
        //Check target Library
        if (this.arg0.indexOf("foo.so"!== -1){
 
            console.log('[*] Load Target Library')
            console.log(">>",this.arg0);
            //To take a time to install my hook code, spend time to sleep
            Thread.sleep(5);
            this.fooFlag = true;
        }
    },
    onLeave: function(retval) {
        // if target library and just once time check rounte
        if (hFlag == false && this.fooFlag){
 
            hookCode();
            hFlag = true;
        }
    }
    });
 
    var modRet = 0;
    //ststr function hooking
    Interceptor.attach(Module.findExportByName('libc.so'"strstr"), {
    onEnter: function(args) {
       
        this.arg0 = Memory.readUtf8String(args[0]);
    
        modRet = 0
        //check frida or xposed string to detect attacker
        if(this.arg0.indexOf('frida'!= -1 || this.arg0.indexOf('xposed'!= -1){
            
            modRet =1;
        }
    
    },
    onLeave: function(retval) {
        if(modRet == 1){
 
            /*
                Natvive Function hook example code [example]
            */
            /*
            retval.replace(ptr("0x1234")) to replace with a pointer
            ptr(retval.toString()).
            this.fileDescriptor = args[0].toInt32();
            
                    console.log('Context information:');
                    console.log('Context  : ' + JSON.stringify(this.context));
                    console.log('Return   : ' + this.returnAddress);
                    console.log('ThreadId : ' + this.threadId);
                    console.log('Depth    : ' + this.depth);
                    console.log('Errornr  : ' + this.err);
                    context: object with the keys pc and sp, which are NativePointer objects specifying EIP/RIP/PC and ESP/RSP/SP, respectively, for ia32/x64/arm. Other processor-specific keys are also available,
                        e.g. eax, rax, r0, x0, etc. You may also update
            */
            //console.log('Context  : ' + JSON.stringify(this.context));
            retval.replace(0);
        }
        return retval;
    }
    });
 
 
 
 
 
/*
    function change Example from frida
 
    const openPtr = Module.getExportByName('libc.so', 'open');
    const open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
    Interceptor.replace(openPtr, new NativeCallback((pathPtr, flags) => {
        const path = pathPtr.readUtf8String();
        log('Opening "' + path + '"');
        const fd = open(pathPtr, flags);
        log('Got fd: ' + fd);
        return fd;
    }, 'int', ['pointer', 'int']));
*/
    Java.perform(function () {
 
        var systemClass = Java.use('java.lang.System');
 
        console.log("[*] Uncrackable3 Solve");
        systemClass.exit.overload('int').implementation = function(a){
            console.log('[*] hooking system class exit');
            //systemClass.exit.overload('int').call(this, a);
            return ;
        }
 
});
 
cs

 

위 스크립트 실행 결과
아스키로 바꾼 값

 

LIST