[Frida-Lab] level 1~8 Write-Up

두비니

·

2021. 1. 10. 06:54

 

 

0. 연결하기

 

 

우선 adb connect 127.0.0.1:62001로 Nox와 서버로 연결을 해줍니다. 주소인 127.0.0.1:62001은 고정되어있는 주소라고 하네요.

그리고 adb shell로 연결해 안드로이드 시스템에 연결해줍시다.

 

또 frida-server도 확인해줘야합니다

 

 

다음처럼 하게되면 frida-server를 실행할 수 있습니다.

ps는 현재 프로세스를 확인하는 작업이니 확인하면 될거같습니다.

 

그다음에는 Nox에서 Frida-Lab을 실행합시다.

 

 

 

그럼 다음과 같은 창이 뜨는데, 각 숫자는 레벨을 뜻합니다. 따라서 우리는 level1을 풀고 싶은거니깐 1번 내용인 Change class challenge_01's variable 'chall01' to: 1 부분을 잘 보면 되겠졍?

 

 

1. Level1 문제풀이

 

그럼 소스코드가 필요할 테니 소스코드 파일을 열어봅시다.

저는 jadx를 이용했습니다. 단순히 실행시킨 뒤, 열고 싶은 apk 파일을 열어서 확인하였습니다.

 

 

challenge_01번을 보면, 딱히 chall01에 아무런 동작도 하지 않고 프로그램이 끝나고 있습니다. 추가로 MainActivity를 봐도 challenge_01을 통해서 하는것 또한 없구요.

 

따라서 저희는 단순히 frida를 통해서 chall01의 값을 변조시켜주면 되겠습니다.

 

 

저도 frida를 처음 공부하면서 하는 입장이라 함수들이 낯서네요

chall01이라는 스크립트를 작성해서 그걸 보내는 작업입니다.

이때, 스크립트는 challenge_01이라는 클래스를 불러와서 chall01의 변수값을 변경하도록 하고 있습니다.

해당 파일을 실행시킨 뒤, nox로 돌아가 값을 확인하면?

+) 참고로 저는 visual studio code사용해서 했습니다.

 

 

굳굳

 

 

2. Level2 문제풀이

 

2번문제는 chall02()함수를 실행시켜야 합니다.

chall02()함수를 확인할 경우, static형으로 선언되어있지 않고 단순히 private형으로 선언된 것을 볼 수 있습니다.

 

 

이런 경우에는 java.choose()를 이용해야 합니다. level1에서 이용했던 java.use()의 경우 static으로 이용되는 경우에만 해당됩니다.

둘의 차이점은 아래 글 참고합시다.

 

rootable.tistory.com/entry/Frida-%EC%83%81%EC%84%B8-%EC%BD%94%EB%93%9C-%EB%B6%84%EC%84%9D

 

Java.use VS Java.choose In Frida Hooking Code

1. Java.use  - Method가 다음과 같이 static으로 되어 있을 경우 프로그램 실행 시 메모리에 올라오기 때문에 instance가 필요없다. 이럴 경우 java.use를 이용한다.  - 위 클래스의 chall01 변수 값을 1로..

rootable.tistory.com

 

 

따라서 다음과 같이 페이로드를 작성하면 됩니다.

 

추가로 java.choose에 대해서 이야기하자면,

Java.choose함수는 힙에서 인스턴스화 된 객체를 찾아주는 기능입니다.

따라서 다음의 코드는 fridalab속의 MainActivity속에서 실시간으로 인스턴스에 대해 호출(onMatch)하도록 되어있습니다. onMatch는 실시간으로 인스턴스에 대해 호출하는 것이고, 이외에 function()의 인스턴스가 모두 열거될 때는onComplete함수를 이용합니다. 이때는 인스턴스가 모두 열거될 때 사용할 필요가 없기 때문에 onComplete함수는 공란으로 비워져 있는 것을 확인할 수 있습니다.

 

아무튼 이 경우에는 onMatch를 통해 실행시 실시간으로 실행중인 MainActivity를 받아 직접 chall02를 실행시키면 됩니다.

 

이후에는 Level1과 동일하게 스크립트를 load하면 됩니다.

 

 

좋아여

 

 

3. Level3 문제풀이

 

Level3의 경우 chall03()의 리턴값이 true가 되도록 하는 것이 목적입니다.

chall03의 내용을 확인해 보면, 

 

 

mainactivity 내부에 chall03이 선언되어있고, 기본적으로 false를 리턴하는 것을 볼 수 있습니다.

static 메서드가 아니기 때문에 choose를 이용하였습니다.

다른 글을 봤는데 use를 써도 된다는데 왜 그런지는 모르겠습니다. 제가 아는 상식 안에서는 static 변수/메서드만 use가 가능한 걸로 알고있거든요,,

 

그래서 아무튼 코드는 다음과 같이 작성하면 됩니다.

 

 

윗부분은 똑같고 빨간색 네모 부분만 새로 추가되었습니다. 내용을 보면 overload().implementation을 통해 true를 리턴하는 것을 볼 수 있습니다. 우선 frida에서 overload를 하는 이유는 java에서의 overload와 비슷합니다. 다음 코드와 같이 chall03을 overload하게 되면 우리가 작성한 새로운 코드가 실행되는 것입니다. 이 경우에는 return true가 실행되겠죠.

 

 

그리고 마지막에는 raw_input()이나 아무값이나 input()해야합니다. 그 이유는 우리가 FridaLab의 check버튼을 누를 때까지 return값이 true인게 유지되어야하기 때문에 그렇고, 터미널에 input값을 받으면 check를 해봅시다!

 

 

굳굳

 

4. Level4 문제풀이

 

Level4는 chall04()의 매개변수로 "frida"라는 문자열을 보내는 것입니다. 

 

 

우선 다른 함수들과 동일하게 choose함수로 chall04함수를 불러와야 할 것 같고, 이제 매개변수를 보내줘야 합니다.

이건 허무하게도 그냥 java에서 함수를 실행할 때처럼 chall04를 실행시킴과 동시에 매개변수를 넘겨주면 됩니다.

 

 

뭔가 frida를 통해서 넘겨줘야하는줄알고 공식문서 뒤지고있었음...바보

 

 

 

좋습니다

 

5. Level5 문제풀이

 

Level5의 목적은 4번과 동일하지만 항상 매개변수를 보내주고 있어야 한다는 점이 다릅니다.

기존의 Level4는 매개변수를 한번 보내고 끝내기 때문에 항상 보낼 방법을 찾아야 합니다.

 

 

다음 네모친 부분이 바뀐 부분입니다. 전체적으로는 chall05를 overload해서 항상 매개변수의 기본값을 'frida'로 바꿔주도록 하고 있습니다. 조금씩 뜯어보면

65번줄은 마지막 function(arg0)으로 첫 번째 매개변수에 대하여 작성한다는 뜻으로 썼고, 

66번줄 같은 경우에는 String형 매개변수를 받는 chall05함수를 overload하여 해당 매개변수(this)의 값을 'frida'로 하겠다라는 내용으로 바꿉니다.

 

 

chall05같은 경우에도 우리가 check버튼을 누를 때까지 유지되어야 하기 때문에 input이나 raw_input을 통해 이를 유지시켜줍니다.

 

 

 

 

다음ㄱ

 

6. Level6 문제풀이

 

Level6의 목표는 10초뒤에 chall06을 올바를 값과 함께 실행시키는 것입니다.

우선 chall06을 확인해보겠습니다.

 

 

challenge_06의 confirmChall06(i)의 값이 true인 경우 문제가 풀리게 됩니다.

challenge_06의 경우 따로 선언되어있는 클래스입니다.

 

 

확인해보면 랜덤으로 정해지는 chall06의 값이 i와 같고, 10초가 지나있어야 합니다.

따라서 저는 매초 chall06값을 확인하고, 그 값을 계속 confirmChall06에 넣어주도록 하겠습니다.

 

 

우선 MainActivity를 제외한 challenge_06클래스 또한 접근해야하기때문에 use로 접근해주었습니다. (왜냐하면 함수가 static형이니까요) 

그리고 84~89번줄이 새로 추가된 코드인데 설명하자면

 

84번줄 : challenge_06의 addChall06메서드를 overload해서 첫 번째 매개변수(arg0)을 가지고

85번줄 : 현재(this) chall06의 값을 console에 출력시킨다.

86번줄 : 뭔지 잘 모르겠움... 알게되면 서술함

87번줄 : 이 값을 MainACtivity의 chall06 메서드의 매개변수로 넘긴다  

88번줄 : 끝

 

이걸 실행시키고 콘솔창에 10번이상 출력된 뒤 FridaLab을 확인하면?

 

 

 

 

7. Level7 문제풀이

 

Level7은 check07Pin()을 브루트포싱한 뒤에 chall07()로 인증받는 부분입니다. 우선 코드를 확인해봅시다.

 

 

우선 다음은 challenge_07 클래스입니다.

public static형으로 선언된 메서드인 setChall07은 랜덤한 값을 chall07에 저장하네요.

Math.random은 0보다 크고 1보다 작은 값을 가져오기 때문에 1000이상, 9999이하의 값이겠네요.

challenge06처럼 랜덤값을 가져와야겠네요.

 

 

그리고 chall07은 매개변수로 보내진 str이 setChall07에서의 랜덤값과 같은지 확인하네요.

 

저는 브루트포싱하는 부분을 코드로 작성하였습니다.

 

 

1000에서 10000는 충분히 브루트포싱을 할 수 있는 범위인지라 그냥 하나씩 check07Pin함수를 통해 체크해보고, 맞는 경우 chall07을 실행시키는 방식으로 코드를 작성했습니다.

 

 

 

 

 

굳굳 브루트포싱이라 시간이 조금 걸리네요

 

8. Level8 문제풀이

 

마지막 문제네요!

 

Level8의 경우는 'check'버튼의 값을 confirm으로 바꾸라고 하네요.

 

옆에 부분을 보면 R이라는 클래스가 있습니다. 그 안의 id클래스를 확인해주면

 

 

보면 프로그램 내에서 확인할 수 있는 UI들은 여기서 확인할 수 있는 것처럼 보입니다. 코드를 작성할 때도 여기서 아이디를 가져와 부를 것입니다.

 

 

우리는 check버튼의 값을 바꿔야하니깐, 2131165231의 값을 가지고 오겠습니다.

 

 

 

 

 

 

끝!