solve:
function findPW(){
var myclass = Java.use("uk.rossmarks.fridalab.challenge_07");
var pw;
for(var i=1000;i<=9000;i++){
pw = i + '';
if(pw === myclass.chall07.value){
console.log("chall07 PIN number:", pw);
break;
}
}
return pw;
}
setImmediate(function() {
console.log("[*] Starting script");
Java.perform(function() {
// Challenge 01
var ch01 = Java.use("uk.rossmarks.fridalab.challenge_01")
ch01.chall01.value = 1;
console.log("[*] Challenge 1 Solve! ");
// Challenge 02
Java.choose("uk.rossmarks.fridalab.MainActivity", {
onMatch : function(instance){
instance.chall02();
},
onComplete : function() {
console.log("[*] Challenge 2 Solve! ");
}
})
// Challenge 03
var main = Java.use("uk.rossmarks.fridalab.MainActivity");
main.chall03.implementation = function(){
return true;
}
console.log("[*] Challenge 3 Solve! ");
// Challenge 04
Java.choose("uk.rossmarks.fridalab.MainActivity", {
onMatch : function(instance){
instance.chall04('frida');
},
onComplete : function() {
console.log("[*] Challenge 4 Solve! ");
}
})
// Challenge 05
main.chall05.implementation = function(){
this.chall05('frida');
}
console.log("[*] Challenge 5 Solve! ");
// Challenge 06
var ch06 = Java.use("uk.rossmarks.fridalab.challenge_06");
ch06.timeStart.value = 0;
Java.choose("uk.rossmarks.fridalab.MainActivity", {
onMatch : function(instance){
instance.chall06(ch06.chall06.value);
},
onComplete : function() {
console.log("[*] Challenge 6 Solve! ");
}
})
// Challenge 07
var pw = findPW();
Java.choose("uk.rossmarks.fridalab.MainActivity", {
onMatch : function(instance){
instance.chall07(pw);
},
onComplete : function() {
console.log("[*] Challenge 7 Solve! ");
}
})
// Challenge 08
var bt = Java.use("android.widget.Button");
var str = Java.use("java.lang.String");
Java.choose("uk.rossmarks.fridalab.MainActivity", {
onMatch : function(instance){
var checkID = instance.findViewById(2131165231);
var checkView = Java.cast(checkID, bt);
console.log(checkView);
checkView.setText(str.$new("Confirm"));
},
onComplete : function() {
console.log("[*] Challenge 8 Solve! ");
}
})
})
})
Note:
● 클래스 내 변수 값 바꾸기 위해
클래스.변수명.value = 1
● static method가 아닌, private method를 호출하기 위해서는 인스턴스화 된 객체를 통해 호출해야 함.
● frida -U -l [스크립트] -f [패키지명]
내가 frida 사용하던 방식이다. 그러나 이렇게 하면 2번 문제가 풀리지 않는다.
%reload 후에 문제가 해결되는데, 이 이유는 다음과 같다.
✅ frida의 -f 옵션은 새 프로세스를 생성하고 스크립트를 attach 하는 데 사용된다.
즉, 스크립트가 현재 프로세스의 컨텍스트가 아닌 새 프로세스에서 실행된다. 현재 프로세스에서의 인스턴스에 대한 참조는 새 프로세스에서 사용할 수 없다.
-f 옵션 사용 시, Java.schoose 메서드가 새 프로세스에서 실행되며 해당 프로세스에서 MainActivity 클래스의 인스턴스를 찾을 수 없다. 이로 인해 onMatch 콜백이 호출되지 않아 chall02 메서드가 실행되지 않는 것.
→ 스크립트가 타겟 프로그램과 동일한 프로세스에서 실행되도록 하기 위해. -f 옵션을 사용하지 말자.
→ frida -U -l [스크립트] [어플리케이션 명]
● challenge 6 풀이 방법
// Challenge 06
var myclass3 = Java.use("uk.rossmarks.fridalab.challenge_06");
myclass3.timeStart.value = 0;
Java.choose("uk.rossmarks.fridalab.MainActivity", {
onMatch : function(instance){
instance.chall06(myclass3.chall06.value);
},
onComplete : function() {}
})
[FridaLab 분석]
- MainActivity.scheduleAtFixedRate(run 실행, 0초후 시작, 1000L마다) //1000L = 1초
- run 내용: nextInt라는 1~50랜덤 수 받아서 addChall06()에 전달함.
- challenge_06.addChall06() 내용: chall06에 전달받은 값 더하고, chall0이 9000을 넘지 못하도록 함.
- MainActivity.chall06() 메소드 내용: confirmChall06에 i를 대입
- MainActivity.startTime() 내용: 시스템 현시간 할당. 즉 MainActivity 실행 시간이 timeStart 값으로 할당.
- challenge_06.confirmChall06 메소드 내용: return i==chall06변수값 && 시스템 현시간 > timeStart + 10초
▶ chall06와 i이 같아야 함. 그리고 현 시간이 timeStart(앱 첫 실행) 이후로 10초 이상 지났어야 함.
✅ 해야 하는 것: i==chall06 만들기 AND timeStart.value 값을 시스템 현시간보다 적게 만들기
✅ 참고로 timeStart = fridalab 앱 실행시간. 그렇기에 timeStart = 0; 처리
● Java.cast(jsObject, javaClass)
자바스크립트 객체를 특정 클래스의 자바 객체에 캐스팅(형 변환)할 수 있도록 한다.
(javaClass에는 보통 Java.use의 반환 값이 들어간다)
Java.cast()의 반환 값은 지정된 클래스 또는 인터페이스를 가진 캐스트된 개체
MainActivity의 chall08 메소드의 반환 값처럼 처리해주기 위해 Java.case()를 사용한다.
- findViewById() 반환 값을 Button으로 형 변환 해줘야 한다.
- jsObject에는 findViewById() 반환 값을 넣어주고.
- javaClass에는 Java.use(Button 클래스)
- 그러나 버튼 내용을 변경하기 위해 setText('Confirm') 메소드를 사용하면 에러가 발생한다.
setText()의 매개변수로 전달될 수 있는 값의 타입은 int, java.lang.CharSequence, …
CharSequence는 인터페이스이며, String이 이 인터페이스를 구현했기에 String 생성자 함수를 사용하여
setText()의 매개변수로 전달해야 한다.
setText("Confirm")이 아니라, frida 방식으로 String의 인스턴스 생성하기.
// Challenge 08
var bt = Java.use("android.widget.Button");
var str = Java.use("java.lang.String");
Java.choose("uk.rossmarks.fridalab.MainActivity", {
onMatch : function(instance){
var checkID = instance.findViewById(2131165231);
var checkView = Java.cast(checkID, bt);
console.log(checkView);
checkView.setText(str.$new("Confirm"));
},
onComplete : function() { }
})
'보안 > 웹·모바일' 카테고리의 다른 글
[Android] Android 7.0 Nox 인증서 문제 해결 (0) | 2023.02.24 |
---|---|
[Android] owasp-crackme Uncheckable #1 (0) | 2023.02.22 |
[웹] 불필요한 HTTP Method : REST API 관련 이슈 (2 case) (3) | 2023.01.26 |
[Android] frida 셋팅 도움말 (frida-server, frida-tools) (0) | 2022.11.22 |
[iOS] Native Code Exploit Prevention (2) | 2022.11.18 |