본문 바로가기

CTF/Write-up

Hashdays 2012 Android Challenge

이번 문제 풀이는 길다. 이거 하나 푸느라고 몇 시간을 낭비했는지 모르겠다.


우선 클래스 수가 적다.


저부분만 보면 될거같다.


해쉬값들이 보이고 성공 문자열도 보인다.


우선 실행을 해봤는데 이틀전 푼 문제와 디자인이 똑같다. 하지만 문제 난이도는 엄청 다르다.

다시 위에 소스를 보면 sha-256도 보이는데 hashes의 첫 번째 값을 sha-256으로 복호화하면


엄청 간단한데 이렇게 키값이 보인다.


성공!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


자! 그럼 본론으로 들어가보자

이 문제는 2012년도 문제다. 지금은 해쉬 데이터 베이스가 많아서 바로 나왔지만 (누군가 이미 값을 넣어봤을테니)

그 당시에는 바로 나오지 않았을 것이다. 그래서 정석 풀이대로 풀어봤다.


다시 소스를 보면 내가 입력한 값을 sha-256으로 암호화 하고 이 값이랑 hashes에 있던 값과 비교를 하는데

아무것도 없이 저 해쉬값을 브포하는건 무리다. 위에 플래그를 봤지만 10자리가 넘는 값이기 때문이다.

그리고 정답이 아니면 answers[4]를 리턴하는데 아래처럼 나온다.



이 문제는 트릭이 하나 있는데 


소스 맨 밑에 이런 메소드가 있다. 검색해보면 알겠지만 아무도 호출하지 않는다.


hexArray 이것 또한 다른 메소스에서 참조하지 않는다.


문제의 트릭은 소스를 디컴파일해도 볼 수 없게 메소드를 숨겨놓았다.

이런 종류의 문제는 처음 풀어봐서 매우 힘들었다. 그럼 이제부터 숨겨진 메소드를 찾아보자


classes.dex를 010 에디터로 보면 71개의 메소드를 보여주는데


그 중 isEmulator()밑에 있는 work()라는 메소드가 있다. 이 work() 메소드가 지금부터 복구해야할 메소드다.


이 부분은 classes.dex를 ida로 열었을 때 isEmulator() 메소드 부분이다.


저 부분에서 밑으로 조금 내리면 btye들이 있는데 p를 눌러준다. 그럼 이렇게 jadx에서 없던 부분들이 생긴다.


classes.dex에서 저 부분을 가르키게 변경해야하는데 현재 메소드는 6개다.


이 부분이 6개의 메소드 부분인데.

3f뒤에 하나의 메소드를 더 추가한다.


값을 이렇게 추가하는데

22는 위에서 봤던 34번 째 메소드를 16진수로 바꾼 값이다.

01은 ACC PUBLIC = 0x1으로 공용 접근이 가능하다.

그다음은 0x1FCC를 가르키게 해줘야하는데 0x1FCC는 work() 메소드의 위치다.



이렇게 수정하니 마지막에 새로운 메소드가 생겼고 값들이 제대로 들어간것을 확인할 수 있다.


dex를 수정했으니 dextools를 사용해 sha1 checksum를 맞춰줘야한다.


이제 jadx로 열어보면 안보이던 메소드가 나타난다.

이제 저 해쉬값을 AES 암호를 통해 assets 폴더에 있는 blob.bin 파일과 다시 연산해서

새로운 파일을 만들어낸다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from Crypto.Cipher import AES
 
# MayTheF0rceB3W1thU
 
def hexStringToByteArray(string):
    num = len(string)-1
    data = []
    for x in range(0, num, 2):
        data.insert(x/2, (int(string[x], 16<< 4+ int(string[x+1], 16))
    return data
 
ha = "E6A7C9A6C6A5CCE9CEADC958F405CCBFDEE2D023C613CB76CCEDC2C7D5B5ADAE"
ha = hexStringToByteArray(ha)
= len(ha)
 
key = []
iv = []
result = ""
 
for x, y in zip(range(0, l, 2), range(l)):
    key.insert(y, chr(ha[x] ^ 0xa7))
    iv.insert(y, chr(ha[x+1] ^ 0xa7))
 
 
with open('blob.bin''rb') as infile:
        decryptor = AES.new("".join(key), AES.MODE_CBC, "".join(iv))
        with open('flag.txt''wb') as outfile:
            while True:
                chunk = infile.read(1024)
                if len(chunk) == 0:
                    break
                outfile.write(decryptor.decrypt(chunk))
            print "Success!"
 
cs

나는 자바를 못하기 때문에 파이썬으로 고대로 옴겼다.


제대로 복호화하면 이렇게 나온다! 플래그를 아스키아트로 보여준다.


이렇게 플래그를 볼 수 있었다.


'CTF > Write-up' 카테고리의 다른 글

Reto Android Crackme #1  (0) 2017.03.05
pragyan ctf MI6  (0) 2017.03.03
Insomni’hack 2012 InsomniDroid CrackMe  (0) 2017.02.24
BSidesSF-pinlock  (0) 2017.02.20
BSidesSF Reversing  (0) 2017.02.14