이번 문제 풀이는 길다. 이거 하나 푸느라고 몇 시간을 낭비했는지 모르겠다.
우선 클래스 수가 적다.
저부분만 보면 될거같다.
해쉬값들이 보이고 성공 문자열도 보인다.
우선 실행을 해봤는데 이틀전 푼 문제와 디자인이 똑같다. 하지만 문제 난이도는 엄청 다르다.
다시 위에 소스를 보면 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) l = 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 |