ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [2020 Google CTF] Reversing:Android writeup(풀이)
    문제 풀이/2020 Google CTF 2020. 8. 25. 14:48

    오랜만에 온라인 CTF에 참가하게 되었다.

    마지막으로 참가를 2018년에 했으니까.. 안한지 2년은 넘은 것 같다.

     

    어쨌든 문제를 풀게 되었으니 간단하게라도 writeup을 남겨보고자 한다.

    문제 Description
    91b17683f3f2b06b679d729a5b5279cdbdfea7607546ac34c1f7114add7e4a0970410d22d359d09055f8fa7d6efe20b4b3f4be67ed5d7a5257fc4117175848c8 (2).zip
    0.19MB

    첨부파일은 문제 Attachment 이다.

    문제를 읽어보면 딱봐도 안드로이드 apk 리버싱처럼 보인다. 또 attachment 압축을 풀면 reverse.apk 가 나온다.

     

    0. 앱 실행

    - 내 폰에 직접 깔아서 실행을 해보았다.

    아. Key를 입력하고 Check를 누르면? 저 ?(물음표)가 X표시로 바뀐다. 아앗

    (보통 폰에 apk를 설치하는 것은 위험하지만.. 구글을 믿고 다운 받음. + 위험한 ransomware 같은거면 문제 description에 아마 써져있음)

     

    1. APK Decompile

    - https://www.popit.kr/how-to-decompile-an-android-apps/ 등에 개념이 나와있다.

    - JADX를 이용해 "classes.dex" 파일을 디컴파일해서 자바 코드를 뽑아낼 수 있다.

     

    2. 자바 코드 확인

    - com/google/ctf/sandbox/C0000.java 가 MainActivity임

    - MainActivity에서 "CHECK" 버튼을 누르는 부분을 보면 Key 계산 로직이 있을 것이라고 추측됨. 거길 봐보자.

    이..이럴수가..

    흠. JADX error: Method load error가 난다. 한번도 본적이 없는 에러다.

    와. 역시 구글이다. 아무튼 뭔가를 잘 조작해서 디컴파일이 안되게 문제를 만들었나보다. 리스펙

     

    3. 삽질

    - "smali"의 개념을 바탕으로 classes.dex 파일에서 smali 관련 코드를 직접 수정을 해서 컴파일을 다시 하거나, 아니면 smali를 보고 원래 코드를 추측해보고자 함. 하지만 나의 집중력이 부족해서 몇시간 보다가 포기함.

     

    4. JADX-gui unstable 버전

    - 지푸라기라도 잡는 심정으로. Jadx gui unstable 버전(https://bintray.com/skylot/jadx/unstable/v1.1.0-b1331-1774dc74#files)을 깔아서 디컴파일을 돌려봤다. Unstable 버전이라 함은 아무래도 가장 최신의 코드가 반영되어 있기 때문에 혹시 위의 에러가 고쳐지지 않았을까? 하는 마음에서 돌려봄.

    - 아앗..? 띠용..?

    위 코드 75 line에서 사용함

    지엔쟝~ 선생님 믿고 있었습니다~ 아구구~ 잘된다.

    onClick 내부에 뭔가 try. catch. Exception unused. RuntimeExpection. 등을 넣어두어서 디컴파일이 안됐던게 아닐까. 하는 생각이 있다.

    코드를 잘 살펴보면 49 line의 char들은 "Apprarently this is not flag. What's going on?" 이런식으로 fake flag가 박아져있다.

    밑쪽의 로직을 보면. 4글자 단위로 내가 입력한 char에 해당하는 어떤 정수 값을 만들고, 그걸 m0라는 함수에 넣어서 이 값이 위의 f0class의 해당하는 idx에 맞으면 flag가 나오는 것을 확인할 수 있다. 저기 66 - 75 line을 잘 참고해서 로직을 보면 될 것 같다.

    예를 들어보자.

    일단 내가 입력한 flag에서 또 다른 flag가 나오는게 아니라, 해당 flag가 맞는지만 확인하는 로직이기 때문에. 첫번째 4글자는 항상 "CTF{" 라고 추측할 수 있다(다른 flag 형식과 똑같이)

    그럼

    >>> ord('C') + (ord('T') << 8) + (ord('F') << 16) + (ord('{') << 24)
    2068206659

    이렇게 되고. 

    >>> m0(2068206659, 4294967296)[0] % 4294967296]
    40999019

    이렇게 됨. 근데 저게 f0class의 첫번째 idx의 value과 같다. 아. 그러면 4개 char의 조합을 잘해서 f0class의 value를 잘 구하면 되겠다. 라는 생각이 난다.

    그걸 바탕으로 파이썬 코드를 짜봤다.

    reverse.py
    0.00MB

    모든 결과를 dict에 담고. dict의 key는 f0class의 값. value는 1,2,3,4 번째 char로 했다. 

    이런식으로 하면 순조롭게 flag가 구해진다.

    CTF{y0u_c4n_k3ep_y0u?_m4gic_1_h4Ue_laser_b3ams!}

     

    끝! 해당 flag를 입력하니 깃발도 잘 나온다.

    댓글

Designed by Tistory.