google ctf 2017 - food.apk Writeup
Google CTF 2017 - Fook.apk Writeup
끝난지 좀 됐지만 공부겸 google ctf 2017 의 문제중 안드로이드 문제인 food.apk 를 풀어봤다.
주어진 apk 는 정상 실행이 안되어서 정적 분석을 먼저 해 보았는데, 실행되고 바로 libcook.so 라이브러리를 호출해 주고 있었고 별다른 코드가
보이지 않았다.
so 파일을 들여다 보면 아래와 같이 dex 파일을 새롭게 생성해 주는 것을 볼 수 있다.
하지만 해당 파일을 바이너리에서 복사해서 붙여넣고 디컴파일을 시도하면 가장 중요한 함수인 cc() 함수가 제대로 보이지 않는다.
so 를 다시 살펴보면 마지막 부분에서 아래와 같이 특정 부분을 xor 해주는 것을 볼 수 있다.(0x720 오프셋 부터 0x90 byte)
해당 바이트를 가져와서 0x5a 로 xor 해서 원본 코드를 확인해 보자. python 으로 간단히 만들어 줬다.
그 후 뽑아냈던 dex 파일의 0E 로 채워진 부분들(0x720 오프셋) 을 위에서 xor 한 값으로 채워주고 다시 디컴파일을 해 보면 정상적으로 cc() 함수가 보인다.
cc() 함수. 어떤 입력값을 비교한 후 맞으면 flag 를 출력해준다. 굳이 실행시킬 필요없이 flag 출력함수인 R.C() 를 분석하기만 하면 flag 를 추출할 수 있다.
# R.C 인데..약간 복잡하긴 하지만 상관없다. 그대로 갖다 쓰면 되니까 ㅎ
라고 생각하고 파이썬으로 대강 작성한 후에 돌려봤더니 아래처럼 일부 플래그만 나오는 이상한 현상이 발생했다(ㅠㅠ)
�TF{�aco��l�ttu��_����to_l�bst��������
몇번의 삽질을 한 후 찾은 버그는 바로 자바 소스에서 (byte) 캐스트 때문에 char 형으로 강제 형변환이 되면서 발생한 문제였다.
파이썬과 약간 처리 방식이 다른듯 했다. 결국 % 256 연산을 통해 음수가 나오지 않도록 해주니 제대로 나왔다. 아래는 전체 python 소스이다.
# solve_food2.py
print "[*] google ctf 2017 : food.apk " print "[*] get this.k array.." flag = [ -19, 116, 58, 108, -1, 33, 9, 61, -61, -37, 108, -123, 3, 35, 97, -10, -15, 15, -85, -66, -31, -65, 17, 79, 31, 25, -39, 95, 93, 1, -110, -103, -118, -38, -57, -58, -51, -79 ] compareArr = [0x13, 0x11, 0x13, 0x03, 0x04, 0x03, 0x01, 0x05] bArr = [26,27,30,4,21,2, 18, 7] for i,c in enumerate(compareArr): print hex(c^bArr[i]) # 0x9 0xa 0xd 0x7 0x11 0x1 0x13 0x2 this_k = [0x9, 0xa, 0xd, 0x7, 0x11, 0x1, 0x13, 0x2] this_k = [9,10,13,7,17,1,19,2] print "[*] get Flag!" def r_c(arr1, arr2): v7 = 256 v3 = [None]*v7 v4 = [None]*v7 v0 = 0 v1 = 0 while v1 != v7: v3[v1] = v1 v4[v1] = arr2[v1 % len(arr2)] v1 += 1 v2 = v1^v1 v1 = 0 while v2 != v7: v1 = v1 + v3[v2] + v4[v2] & 255 v3[v1] = (v3[v1]^v3[v2]) % 256 v3[v2] = (v3[v2]^v3[v1]) % 256 v3[v1] = (v3[v1]^v3[v2]) % 256 v2 += 1 v4 = "" v2 ^= v2 v1 ^= v1 while v0 != len(arr1): v2 = v2 + 1 & 255 v1 = v1 + v3[v2] & 255 v3[v1] = (v3[v1]^v3[v2]) % 256 v3[v2] = (v3[v2]^v3[v1]) % 256 v3[v1] = (v3[v1]^v3[v2]) % 256 v4 += chr((arr1[v0] ^ v3[v3[v2] + v3[v1] & 255]) % 256) v0 += 1 return v4 print r_c(flag, this_k)
실행해보면 flag 를 확인할 수 있다.
hyunmini@~/2017.googlectf/food$ python food_flag2.py [*] google ctf 2017 : food.apk [*] get this.k array.. 0x9 0xa 0xd 0x7 0x11 0x1 0x13 0x2 [*] get Flag! CTF{bacon_lettuce_tomato_lobster_soul} |
끝! (ps. 간만의 안드로이드 리버싱 문제라서 반가웠다.)