CTF | wargame

codeengn / smartapp / challenge 04 (안드로이드 apk 리버싱, 맵핑되지 않은 메소드 연결)

nopdata 2017. 5. 2. 13:24

[ 문제 ]

bctf mobile 문제를 풀다가 아직 codeengn 문제를 다 풀지 않았던 것을 알아서 풀게 된 문제. 이전 문제들과 동일하게 서명이 없기 때문에 설치를 할 수 없다. 어차피 리컴파일 하면 서명을 다시 해야하기 때문에 있으나 없으나 큰 차이는 없다.

이번 문제의 경우 풀면서 genymotion을 통한 adb를 사용하였다. (설정 : http://i5on9i.blogspot.kr/2014/12/adb-genymotion.html)

[ apk 실행시 화면 ]

실행을 하면 위처럼 입력창 하나와 버튼 하나, 결과가 뿌려지는 텍스트가 하나 있다. apk의 구조는 상당히 간단하다. MainActivity가 있고, 거기서 키값 확인을 한다. 키값은 고정된 sha256값과 비교를 하게 된다.
사용되지 않는 클래스로 zFindKey 클래스가 있는데 helloWorldA,B,C 메소드가 존재한다.

[ MainActivity와 zFindKey 클래스 ]

코드가 너무나도 간단해서 알아낼 수  있는 정보가 없었다. write up을 여기서 참고했는데, 보면 zFindKey 클래스의 메소드는 A,B,C 세개만 존재한다. 하지만 classes.dex 파일의 string을 긁어보면 helloWorldD라는 이름을 찾을 수 있다.
따라서 고의적으로 출제자가 맵핑정보를 삭제해 어떤 디컴파일러도 디컴파일 하지 못했던 것.

[ classes.dex string 일부 ]

그렇다면 다시 설정을 해주어야 한다. dex file format의 경우 많이 나와있지 않아, 010 editor를 이용한 분석을 하였다.

[ classes.dex - 010 editor ]

왼쪽부터 순서대로 최상위에서 바꿔야 할 정보로 내려온 것이다. 클래스 정의 부분을 보면 class_def[12]가 zFindKey에 대한 정보가 들어있다. 여기서 direct_methods_size. 메소드의 개수 오프셋을 보면 0x4로 되어있다. A,B,C와 init까지 4개가 설정되어 있는 것이다.
여기서 D가 연결되어 있지 않아 디컴파일러가 인식하지 못한 것이다. helloWorldD를 사용하는 방법은 두가지가 있다.

  1. helloWorldC라고 정의된 오프셋을 덮어씌운다.
  2. direct_methods_size를 5로 변경하여 helloWorldD를 추가한다.

오프셋 추가의 경우 밀려서 다음 데이터가 덮어씌워질 우려도 있지만, 문제 출제의 의도가 일부러 숨겨놓았기 때문에 새로 추가할 공간은 충분하다. writeup에서 추가하는 방법을 사용하였으므로, 덮어씌우는 방법을 사용하기로 하였다.

[ helloWorldC 맵핑 정보 ]

helloWorldC의 정보를 보면 위와 같다. 먼저 method_idx_diff는 이전 메소드 인덱스 + method_idx_diff를 현재 인덱스로 사용하게 한다고 한다. (http://www.ahnlab.com/kr/site/securityinfo/secunews/secuNewsView.do?curPage=1&menu_dist=2&seq=23400)
access_flags는 자바에서 public, private 등으로 이해하면 된다. 여기서는 public으로 정의되어 있다. 다음으로 code_off가 있는데 이게 메소드 내부의 기능이 저장된 부분이다. helloWorldC의 위치는 0xCB8에 저장되어 있고, 이 값을 helloWorldD의 코드가 저장되어 있는 위치로 바꾸어 주면 된다.
helloWorldD의 주소는 0xCB8에서 코드 길이를 추가한 0xCD0가 된다. 해서 이 값을 0xCD0로 바꾸고 디컴파일러로 다시 확인을 해 보면 다음과 같이 나온다.

[ helloWorldD 코드 ]

메소드 이름은 변경하지 않아 helloWorldC이지만 코드의 내용이 helloWorldD의 내용으로 변경된 것을 볼 수 있다. 이 코드를 그대로 돌려 보면 encode 된 hex 값이 나오게 되고 이 값을 디코딩 하여 프로그램을 돌리면 답을 확인할 수 있다.

[ 답 확인 ]

[ 에이핑크 ? ]
flag : BoanprojectZZang

+++ 메소드 이름 변경하기
helloWorldC를 helloWorldD로 변경하기 위해서는 String idx 값을 확인하고 변경해주면 된다.