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. 간만의 안드로이드 리버싱 문제라서 반가웠다.)

+ Recent posts