[KakaoTalk-iOS] 암호잠금 (Passcode) 풀기

보통 프로토콜/바이너리 분석 관련 주제만 다루어 왔어서 글을 쓸 기회는 없었는데, 어제 SNS에서 아이폰용 카카오톡 암호를 풀어주는 툴을 보고 간략하게 몇 글자 적어야겠다는 생각이 들었습니다 :)

툴이 오픈소스가 아닌지라 기능을 직접 구현하고 싶어하시는 분들이나 어떻게 암호를 크랙할 수 있는지 알고 싶으신 분들에게 어려움이 있을 수 있다는 생각에서 쓴 글이고, 목표 자체가 해당 툴의 기능을 재현하는것이었기 때문에 안드로이드 쪽은 분석하지 않았습니다 — 테스트할 기기가 없다는게 더 큰 이유지만… 독자분들의 과제로 남겨두도록 하겠.. (쿨럭)

 

Crack It!

사실 카카오톡 passcode에 대한 문제점은 초기때부터 지금까지 쭈욱 있어왔다. 초기 시절에는 평문으로 저장이 되어있었고, 그 이후에는 ‘a’를 salt로 한 해쉬값을 이용했었던 적이 있고, 지금은 조금은 달라졌지만 결국엔 SHA256를 이용한 해쉬를 쓰는데, 이 값은 순정폰에서도 뽑아낼 수 있기 때문에.. 어떤값을 이용해서 해쉬가 생성되는지만 알면 잠금에 사용된 암호를 알아내는건 무척 쉽다.

일단, 비밀번호를 크랙하려면 두 가지 재료가 필요하다: EncryptedPasscode와 UserId.

아래에서 좀 더 보겠지만, 말이 “encrypted”지 사실은 그냥 “hashed”다. 물론 그냥 비밀번호를 그대로 해쉬한건 아니다..
UserId는 이전 포스팅들에서도 여러번 언급한대로 해당 유져의 고유 번호이다.

이 재료들을 구하는 방법을 소개한다.

첫번째 재료인 EncryptedPasscode는 com.iwilab.KakaoTalk.plist 파일 안에 존재하는데, 이 파일은 순정폰에서도 i-Funbox 등을 이용하면 쉽게 읽을 수 있다.

해당 plist파일을 읽어보면 다음과 같이 EncryptedPasscode 키에 해당하는 값을 볼 수 있다.

 

두번째 재료인 UserId 역시 i-Funbox등을 통해 Talk.sqlite 파일을 뽑아내서 읽으면 된다. 물론 sqlite DB 파일이므로 읽을 수 있는 툴을 사용해야 하는데, 윈도우에서는 DB Browser 같은걸 쓰면 된다 — 리눅스나 맥에서는 그냥 sqlite cli를 사용해도 된다.

DB 파일을 로드한 뒤에, ZUSER 테이블을 보면 Z_PK == 1 에 해당하는, 즉 자기 자신의 ZID 칼럼을 보면 된다.

(내 UserId를 알만한 사람들은 이미 알고 있겠지만 ㅜㅜ 그나마 설명에 필요없는 몇자리라도 가려보려고 노력해본다..쿨럭)

 

자, 필요한 재료들이 다 모였으니 요리를 해보자(?)

이번 요리의 레시피는 다음과 같다.

간단하지 아니한가?!

일부러 좀 있어보이게 하려고 itertools 모듈을 썼는데, 풀어서 쓰면 진짜 간단하다.

즉, iOS용 카카오톡에서 사용하는 EncryptedPasscode는 다음과 같은 ‘알고리즘 규칙 (-_-)’ 으로 만들어진다:

  1. 우선 UserId의 마지막 네자리를 뒤에서부터 읽는다 => 예를들어, 자신의 UserId가 12345678 이라면, 8765가 되는것이다.
  2. 네자리 수 Passcode의 각각 한 글자와 위에서 얻은 네자리 수 각각 한 글자를 번갈아가며 섞는다
    => 예를들어, passcode가 0103이라면, 08170635가 되는것이다.
  3. 스텝 2에서 만들어진 문자열을 sha256 해쉬한다 => sha256(“08170635”) –> 71960ab60fc2b308d4a16b0c590c23e2b562224ec82ae067935dcdad692b22e3

마지막 스텝에서 만들어진 sha256 해쉬가 EncryptedPasscode다.

물론 우리는 Passcode를 모른다는 가정하에 있기 때문에, 0000부터 9999까지 bruteforce를 해줘야한다.

그걸 해주는게 위의 짤막한 코드.

제일 마지막에 있는 9999까지 가는데 성능도 그닥 좋지 않은 머신에서 0.03초정도 걸린다.
(만약에 iOS환경에서 위에서 설명된대로 했는데도 아무 결과가 나오지 않는다면.. 자네가 무언가 잘못한거라네..ㅋㅋ)

 

급하게(?) 맺는말

결론적으로, 안드로이드에서든 iOS에서든 카카오톡에 내장되어있는 숫자암호를 너무 믿으면 안된다. 이건 비단 카카오톡의 문제라기보다는 암호가 4자리 숫자 밖에 되지 않으므로 가능성이 10000개 (사람이 치려면 고생 좀 하겠지만, 불가능한것은 아니고, 컴퓨터는 1초도 채 안걸리는 작업량이다..) 밖에 되지 않는다는데 있다.

한가지 아쉬운점은 이 작업을 (적어도 순정폰에서는) 어렵게 하기 위해서 Keychain을 썼으면 더 좋았을텐데, 그러지 않았다는 점이다 — 왜 카카오쪽에서 keychain을 쓰지 않고 굳이 파일/DB를 이용한 자체적인 데이터 스토리지를 사용하는지에 대해선 듣긴 했지만…ㅜㅜ

유져 입장에서 조금 더 안전하게 사용하기 위해서는, 다음 지침을 생활화하자:
1. 일단 폰 자체의 암호 시스템을 이용한다 (패스워드/패스코드/지문인식)
2. 자신이 사용중이 아닐때는 반드시 잠금상태로 유지한다
3. 보안이 확실한 개인 컴퓨터/기기가 아닐 경우, 폰을 연결했을때 “이 컴퓨터를 신뢰하겠습니까?” 메세지에서 “신뢰하지 않음”을 누른다

끝!

궁금하신 점은 메일이나 댓글로~~

아참. 악용하진 말자.
정말 자신의 비밀번호를 까먹었거나… 혹은 친구들의 장난으로 묶인(?) 경우에만 사용하자 — 실제로 이 일이 나에게 일어났었다 ㅠㅠ

 

PS. 그나저나 오랜만에 plist를 살펴봤는데, 초창기에 지적했던 session key가 아직도 (아마도?) 평문으로 저장되어있다. 물론 요즘엔 이전과 달리 세션키”만” 가지고는 상대방의 메세지를 임의로 읽거나 보낼 수 없지만.. 그걸 하는데 필요한 device_uuid 마저도 plist에 고스란히 저장되어있다 ㅠㅠ 물론 암호화 되어있는거 같긴 하지만.. 이 역시 아마 고정키로 AES암호화 했을터.. 이걸 다시금 깨닫고 나니 정말 폰관리를 잘해야겠다는 생각이…ㄷㄷ — 이 문제의 개선방법은 위에서도 언급한 keychain 사용이다.. 물론 폰 자체가 루팅당하면 답 없지만서도.. 그건 아예 스케일이 다른 공격이니까..

 

You may also like...

18 Responses

  1. 정서윤 says:

    재발 알려줘요

Leave a Reply

Your email address will not be published. Required fields are marked *