Self-Improvement

[FridaLab] Challenge 1 ~ 8 WriteUp 본문

AOS/FridaLab

[FridaLab] Challenge 1 ~ 8 WriteUp

JoGeun 2021. 12. 12. 01:12

FridaLab

 

Challenge 1

Change class challenge_01's variable 'chall01' to:1

MainActivity 에서 challenge_01 클래스의 getChall01Int() 메소드를 호출하여 chall01 변수의 값이 1이면 해결된다.

 

Frida

Java.perform(function() {
        var challenge1 = Java.use('uk.rossmarks.fridalab.challenge_01');
        challenge1.chall01.value = 1;
});

 


 

Challenge 2

Run chall02()

chall02() 메소드는 MainActivity에 존재하지만 사용하지 않고 있다. 임의로 chall02() 메소드를 호출해준다.

 

Frida

chall02() 메소드를 사용하는 로직이 존재하지 않음으로 Java.Choose()로 힙에서 인스턴스화 된 MainActivity 객체를 찾아호출해준다.

Java.perform(function() {
        Java.choose("uk.rossmarks.fridalab.MainActivity",
        {
            onMatch: function(instance)
            {
                console.log(instance.toString());
                instance.chall02();
            },
            onComplete: function()
            {
            }
        });
});

 


 

Challenge 3

Make chall03() reutrn true

MainActivity에서 chall03() 메소드를 호출하여 true이면 되지만 chall03() 메소드의 기본 리턴값은 false로 이 부분을 변경해주자

Frida

Java.perform(function() {
        var challenge3 = Java.use('uk.rossmarks.fridalab.MainActivity');
        challenge3.chall03.overload().implementation = function(){
            var ret = this.chall03();
            console.log("[*] chall03() Original ret = "+ret);
            return true;
        }
});

 


 

Challenge 4

Send "frida" to chall04()

MainActivity 에서 chall04() 메소드는 존재하지만 요청하는 로직이 없음으로 chall04() 메소드를 호출해주고 인자로 받은 str을 "frida"로 후킹해주자

 

Frida

Challenge 2 에서 사용했던 방식으로 chall04()을 요청할 때 "frida" 인자와 함께 작성하면 된다.

Java.perform(function() {
        Java.choose("uk.rossmarks.fridalab.MainActivity",
        {
            onMatch: function(instance)
            {
                console.log(instance);
                instance.chall04("frida");
            },
            onComplete: function()
            {
            }
        });
});

 


 

Challenge 5

Always send "frida" to chall05()

MainActivity 에서 "notfrida!" 인자와 함께 chall05() 메소드를 호출하고 있으며 chall05() 메소드는 인자로 받아온 값이 "frida"이면 해결이 된다.

 

Frida

chall05() 메소드를 실행하여 다시 'frida' 인자값을 가지고 재호출을 하는 방식으로 작성한다.

Java.perform(function() {
        var challenge5 = Java.use('uk.rossmarks.fridalab.MainActivity');
        challenge5.chall05.overload('java.lang.String').implementation = function(arg1){
            console.log("[*] original arg1 = "+arg1);
            this.chall05('frida');
        }
});

 


 

Challenge 6

Run chall06() after 10 seconds with correct value

MainActivity에서 chall06() 메소드를 호출하는 로직은 존재하지 않으며 challenge_06 클래스의 confirmChall06() 메소드가 참이면 해결된다.

 

challenge_06 클래스의 confirmChall06() 메소드를 보면 인자로 받아온 i와 chall06의 값이 같아야 하며 10초가 경과되어야 True를 반환하게 된다.

 

다시 MainActivity 의 onCreate() 메소드를 확인해보면 1초마다 addChall06() 메소드를 호출하여 50까지의 랜덤한 값을 더해주게 된다.

위 challenge_06 클래스의 addChall06() 메소드를 보면 계속 더하면서 9000을 넘어가지는 않는다.

 

 

Frida

매초마다 정말 더하는지를 확인하기 위해 아래의 코드로 확인하였다.

Java.perform(function() {
            var challenge6 = Java.use('uk.rossmarks.fridalab.challenge_06');
            challenge6.addChall06.overload('int').implementation = function(arg1){
                console.log(challenge6.chall06.value);
                this.addChall06(arg1);
            }
})

 

True를 반환하기 위한 조건 중 10초가 지나야 하는 조건은 setTimeout()으로 만족을 하며 chall06() 메소드를 호출하는 로직이 존재하지 않음으로 chall06() 메소드를 호출할 때 10초가 경과된 값의 결과도 함께 인자로 전송하면 해결된다.

setTimeout(function () {
        Java.perform(function() {
        
            var challenge6 = Java.use('uk.rossmarks.fridalab.challenge_06');
            challenge6.addChall06.overload('int').implementation = function(arg1){
                Java.choose("uk.rossmarks.fridalab.MainActivity", {
                    onMatch: function(instance) {
                        instance.chall06(challenge6.chall06.value);
                    },
                    onComplete: function() {
                    
                    }
                })
            }
        })
}, 10000);

 


 

Challenge 7

Bruteforce check07Pin() then confirm with chall07()

MainActivity 에서 chall07() 메소드 로직은 존재하지만 호출하는 부분은 존재하지 않는다.

chall07() 메소드는 인자로 받은 str 값을 challenge_07 클래스의 check07Pin() 메소드의 인자로 전달하여 참이면 해결된다.

 

challenge_07 클래스의 check07Pin() 메소드에서 받은 인자를 chall07 변수에 저장된 값과 비교하여 같으면 True을 반환하게 된다.

chall07 값은 setChall07() 메소드에 의해 랜덤한 값이 정해지며 setChall07() 메소드는 MainActivity의 onCreate() 메소드에서 호출되어 진다.

 

Frida

Bruteforce 조건이 아니였을 경우에는 사전에 chall07에 저장된 값을 가져와 MainActivity 에서 chall07() 메소드를 호출하면서 인자로 값을 넘겨주면 된다.

Java.perform(function() {
        var challenge7 = Java.use('uk.rossmarks.fridalab.challenge_07');
        Java.choose("uk.rossmarks.fridalab.MainActivity", {
            onMatch: function(instance) {
                instance.chall07(challenge7.chall07.value);
            },
            onComplete: function() {
                        
            }
        })
})

 

Bruteforce 조건일 경우 MainActivity의 클래스들을 변수에 저장한 후 for문으로 변수 i을 증가시키면서 임의로 check07Pin() 메소드를 호출하면서 인자로 주어 참일 경우 그때서야 MainActivity 클래스들이 담긴 변수를 이용하여 변수 i 값과 함께 chall07() 메소드를 호출해준다.

이때 인자는 'java.lang.String' 임으로 toString()을 통해 문자열로 변환해주면서 전달한다.

Java.perform(function() {
        var MainIns;
        Java.choose("uk.rossmarks.fridalab.MainActivity", {
            onMatch: function(instance) {
                MainIns = instance;
            },
            onComplete: function() {
                            
            }
        })
        var challenge7 = Java.use('uk.rossmarks.fridalab.challenge_07');
        
        console.log("[*] chall07 setting = "+challenge7.chall07.value);
        for( var i = 1000; i<10000; i++){
            if(challenge7.check07Pin(i.toString())){
                console.log("[*] i match = "+i);
                MainIns.chall07(i.toString());
                break;
            }
        }
})

 


 

Challenge 8

Change 'check' button's text value to 'Confirm'

MainActivity의 onCreate()에서 chall08() 메소드를 호출하여 참이면 해결된다.

chall08() 메소드에는 check 버튼 ID값의 문자열이 "Confirm"이면 True을 반환하게 된다.

 

Frida

MainActivity 클래스의 인스턴스를 가져와서 check 버튼의 ID값을 이용하여 "Confirm" 문자열로 변경한다.

Java.perform(function() {
        var MainIns;
        Java.choose("uk.rossmarks.fridalab.MainActivity", {
            onMatch: function(instance) {
                MainIns = instance;
            },
            onComplete: function() {
                            
            }
        })
        var id = MainIns.findViewById(2131165231);
        var bt = Java.use('android.widget.Button');
        var ckbt = Java.cast(id, bt);
        var string = Java.use('java.lang.String');
        ckbt.setText(string.$new("Confirm"));
    })