OWASP에서 제공하는 Android 모의 워게임 중,
uncrackable 2를 풀이해보았습니다.
우선 문제 풀이를 위해 에뮬레이터에 앱을 설치한 후 실행시켜보았습니다.
제가 사용중인 에뮬레이터는, Frida 사용을 위해 루팅을 진행한 상태라
앱에 접근하면 곧바로 Root감지 팝업 발생 후 앱이 종료되는 모습을 볼 수 있습니다.
어플리케이션 정적 분석을 위해, JADX를 통해 APK 파일을 디컴파일 해보겠습니다.
디컴파일 후 코드 구조를 확인해보니, 바로 MainActivity가 존재하는 것을 확인했습니다.
그렇다면 MainActivity의 코드 구조를 확인해보겠습니다.
가장 주가 될 함수인 onCreate와 a, verify 그리고 init 이라는 메서드가 존재합니다.
init 메서드는 특이하게 구현체가 없네요 ..
확인해보니 'native' 예약어를 사용한 메서드네요.
JNI를 통해 타 언어로 작성된 함수임을 알 수 있습니다. (JNI란?)
JNI 파트는 우선 넘어가고, 다시 코드를 분석해보겠습니다.
가장 먼저 a 메서드 입니다.
아 ... 이녀석이 제 루팅을 감지하고 바로 앱을 종료시킨 버릇없는 녀석이군요.
위에서 만난 루팅 탐지 팝업과 동일한 형태를 정의하고, 호출하는 것을 확인할 수 있습니다.
이번 문제 풀이에서는 사용하지 않으나, Frida를 통해 onClick 메서드를 후킹하면 루팅 탐지 팝업을 무력화시킬 수 있을 것 입니다.
아래에 위치한 verify 메서드를 확인해보니, m 객체의 a메서드를 호출한 결과값으로 성공 팝업을 출력하는 것을 볼 수 있습니다.
a 메서드의 선언부를 확인해보겠습니다.
JNI를 통해 선언한 bar 메서드를 그저 반환하고 있음을 확인할 수 있습니다.
JNI로 선언된 코드를 확인해보겠습니다.

우선, JNI는 시스템의 아키텍처에 따라 필요한 native 파일이 달라지기 때문에, 제 아키텍처와 맞는 폴더에 선언된 .so 파일을 Export 해주겠습니다.
그 이후, IDA를 통해 정적 분석을 해보겠습니다.

IDA를 통해 .so 파일에 선언된 함수들을 보니,
가장 아래에 JNI 네이밍 규칙에 맞게 CodeCheck 클래스의 bar 메서드가 선언되어 있음을 확인할 수 있습니다.
해당 함수를 디컴파일 해보겠습니다.

문자열을 비교하는 코드들이 있고, 바로 Flag를 확인할 수 있습니다.

성공