[KakaoTalk+] LOCO 프로토콜 분석 (1)

작년 10월 즈음 카카오톡에서 메세징 시스템 기반을 다시 디자인하는 큰 공사를 치뤘습니다.
카카오톡 메세징의 scalability와  speed를 높이기 위해서 2011년 4월정도 부터 시작된 프로젝트인 일명 ‘겁나빠른황소’ 프로젝트는 약간의 시행착오를 겪으며 안정화되어 지금은 거의 모든 기기의 카카오톡에서 사용중인 카카오톡 자체 프로토콜입니다. LOCO는 이 프로젝트의 내부 코드명으로 추정 됩니다. 기존에 사용하던 웹서버 (…/xxx.json에 HTTPS POST request를 보내는) 방식에서 TCP 레이어 위에서 작동하는 프로토콜을 만듦으로써 패킷 경량화 및 빠른 responsiveness를 얻게 되었습니다. 사실 예전에 http request기반 프로토콜을 분석할때 문득 든 생각이, ‘이 방식으로 얼마나 버틸 수 있을지, 유져가 늘어나고 메세지 빈도가 늘어날 수록 서버는 죽어나고 유져들은 불편해질 텐데’  이었는데, 발빠르게 scalable한 시스템을 개발 및 도입한 카카오팀에게 찬사를 보냅니다 :)

사실 해커 입장에서.. 한번 분석해봤던 놈인데 아예 바뀌었다고 하면 왠지 모르게 어떻게 바뀌었는지 뭔가 실수는 없었는지 궁금하기 마련입니다. 그래서 올해 8월쯤에 살짝 들여다 봤었는데, 열심히 적어둔 노트가 4달 사이에 어디론가 사라져버렸습니다… 블로깅을 열심히 안하고 미루고 미룬 댓가인듯 싶군요 ㅠㅠ 그래서 더 귀찮아져서 방치해두고 있다가.. 더이상 미루면 아예 글 쓰는게 귀찮아질 듯 싶어 어제 다시 마음을 다잡고 새로 분석을 시작했습니다. 오랜만에 하려니 다 까먹어서.. 초반에 좀 삽질을 하긴 했지만.. 한번 봤던거라 그런지 금방 Proof-of-concept을 뽑을 수 있었습니다.

제가 iPhone 유져이고 Android는 일 때문에 간간히 작업하다보니 평소에는 iOS 앱이나 Android 앱 위주로 분석을 많이 했는데, 이번에는 새로운걸 배워볼겸 Windows Phone용 앱을 이용하여 분석하기로 했습니다. 이런 결정을 한 또 다른 이유는 ARM 어셈블리로 되어있는 거지같은 Objective-C 코드를 보는것보다 또는 거지같은 code obfuscation을 적용한 Android Java 코드를 보는것보다, 아주 깔끔하게 MSIL (Microsoft Intermediate Language — .NET)로 되어있는 윈폰 앱을 분석하는게 훨씬 편했기 때문입니다 — 아시는 분은 아실테지만, 디컴파일 프로세스 자체도 매우 쉽구요. 덕분에 윈폰용 개발툴에 에뮬레이터, 그리고 사이드 로딩하기 위한 app signing 등등.. 전혀 써볼 일 없던 툴들이나 기술들을 사용해 볼 수 있는 좋은 기회였습니다.

자, 두서가 길었으니.. 이제 본론으로 들어가 보도록 하죠.

1. KakaoTalk 앱 구하기

당연한 말이지만, 일단 분석을 하기 위해서는 앱 원본이 필요합니다. 타겟 앱을 추출하는 방법은 여러가지가 있고 상황에 따라서 달라질 수 있지만, 보통 그렇게 어렵지 않습니다..
윈폰 마켓플레이스 같은 경우에는 3MktPlace와 같은 프로그램을 사용해서 임의의 앱을 다운 받을 수 있었습니다 — 사실 마켓플레이스 search/download URL 쿼리들을 알아내서 직접 받는 방법을 적어두었지만 역시 소실.. // 하지만 올해 8월부터 MS에서 마켓플레이스의 모든 앱들을 (정확히는 xap 파일) encrypt 시킨 후 배포하기 시작하면서 실질적으로 다운 받아도 decrypt를 할 수 없으니 앱 바이너리를 분석할 수도 없게되었습니다. 하지만 당연히 폰에서 앱을 설치할때는 decrypt를 하고 설치하므로.. 앱을 설치한 후 파일을 긁어오면 딱히 문제 없이 모든 리소스를 가져올 수 있습니다.

하지만 가난한 저에게 윈폰이 있을리 만무하고.. 에뮬레이터밖에 없어서 딱히 앱을 깔아서 추출하기도 힘든 상황..
…그래서 분석은 앱들이 encrypt되어 배포되기전에 받아놓은 윈폰용 카카오톡 버전 1.1.0.0을 사용하기로 했습니다. 어짜피 LOCO 프로토콜 디자인은 마이너버전 업데이트에서 변경되지 않았을 뿐더러,   LOCO 자체만의 버전은 사실 1.0 이후부터는 변함이 없었기 때문입니다. 어쨋든, 여차저차 예전에 받아두고 열어보지않아 먼지가 가득한(?) xap파일의 압축을 풀고 필요한 바이너리/라이브러리를 찾았습니다.

결론적으로 위의 두개 모듈이 제일 중요합니다.

KakaoTalkSLLib.dll은 다음과 같은 구조로 되어있고, 전반적으로 Model을 정의하는 클래스들로 이루어져있습니다. 보시다시피 이 중에는 LOCO 버전 1에 해당하는 API, request 및 response핸들러가 정의되어있습니다.

         …       

다음으로 KakaoTalkWP71.dll에서는 전반적으로 앱 자체의 Control과 View를 담당합니다. 여기서 크게 유용한것은 여러가지 커맨드에 대한 정의를 담고 있는 KakaoTalkWP71.Command namespace에 속해있는 클래스들입니다.

        …        

 자, 이제 분석할 준비는 다 된것 같으니… 실질적으로 카톡이 어떤식으로 작동하는지 알아봅시다.
물론.. 워낙 크고 복잡해진 앱이다보니 모든걸 리버싱하는건 (정신적으로나 육체적으로나..) 별로 유익하지 않으므로..
제가 관심있는 분야인 ‘친구 추가’ 및 ‘대화방 생성 + 메세지 작성’을 중점적으로 보도록 하겠습니다.

2. 네트워크 패킷 분석

프로그램 분석을 할 때 바이너리 분석부터 바로 시작할 수 있지만, 카카오톡과 같은 메신져류의 프로그램들은 네트워크 기반이기 때문에 네트워크 패킷을 캡쳐하여 분석하는것이 꽤 큰 도움이 됩니다. 예전에 카카오톡을 분석할 때는 아이폰 기기에서 직접 tcpdump를 사용하여 패킷 캡쳐를 했지만, 이번에는 윈폰 에뮬레이터를 사용하여 PC 환경에서 분석하므로 그냥 wireshark를 사용하여 캡쳐 및 분석을 하도록 합니다.

우선 ‘친구 찾기’ 기능을 시도해봅니다.

        …        

보시다시피 카카오톡 서버와 주고 받는 SSL 패킷을 발견 할 수 있습니다.

흐음.. 여기서 두 가지 방법을 생각해볼 수 있습니다. MITM (Man-in-the-middle) 공격을 해서 가짜 certificate을 통한 decryption을 하던가 아니면 아예 앱 자체를 수정하여 https request 대신 http request를 하도록 하는것이죠 (물론, 이건 카카오톡 서버가 아직 non-https request를 허용한다는 가정 아래서 이고, 확인결과 가능한 것으로 나타났습니다). MSIL 코드를 수정하여 repackage 할 수도 있지만.. 귀찮으니 일단 어느 코드에서 http나 https 사용여부를 결정하는지, 그리고 어떻게 하면 가장 적게 수정하여 원하는 목표를 이룰 수 있을지 알아보도록 합니다 ㅡ_ㅡㅋ

뒤적뒤적이다보니 KakaoTalkWP71.dll에 있는 AppLaunchingCommand 클래스의 Execute 메소드에서 KakaoLibModel의 대부분 값을 초기화하는데, 그 중에는 나중에 https request를 날리는데 사용되는 API에서 레퍼런스하는 KakaoLibModel.Current.HttpScheme 역시 설정합니다. 여기서, HttpSchemeType.https 라는 값으로 초기하게 되는데 http는 0, https는 1의 값을 가지고 있습니다. 관련 MSIL 코드를 바이너리에서 찾아보면 ldc.i4.1 (4-byte load integer constant of value 1) 명령어를 사용하여 https에 해당하는 값을 로드하고 set_HttpScheme 메소드를 호출하여 HttpScheme의 값을 업데이트 하는것을 볼 수 있습니다.

 

해당 인스트럭션의 옵코드는 0x17이고, 우리는 http에 해당하는 0 값을 로드하고 싶으므로, 0x16 옵코드에 해당하는 ldc.i4.0 인스트럭션으로 변경해야합니다.
변경한 뒤 xap으로 다시 패키징하고 signing을 다시 하고 에뮬레이터에 사이드로딩을 한 이후에 같은 기능을 실행한 뒤 패킷캡쳐를 해보면 이젠 https가 아닌 http request를 보내는것을 확인할 수 있습니다. (유져 세션키에 해당하는 HTTP_S 헤더는 삭제하였습니다)

 위의 스크린샷에서 볼 수 있듯이 윈폰용 카카오톡 앱에서 친구 찾기를 하면 https://fr-talk.kakao.com/wp/friends/find_by_uuid.json에 ‘uuid=아이디’ data와 함께 POST request를 보내서 결과를 받아옵니다. 예전 분석에서도 알 수 잇었듯이 fr-talk.kakao.com은 카카오톡의 친구관련 (fr[iend]) 서버입니다. 어떤 폰에서 request를 날리느냐에 따라서 url은 조금씩 달라지지만, 이 부분은 예전과 다른점이 크게 없다는것을 알았습니다. 즉, 친구찾기 기능은 LOCO 프로토콜을 사용하지 않고 이전 방식 그대로 사용한다는 것이죠.

하지만, 어찌되었든 더 편리한 분석 및 디버깅을 위해서는 https보다는 http 패킷들을 이용하는것이 훨씬 유용하니 괜한 시간과 노력을 투자한건 아닙니다 :)
앞으로 LOCO 프로토콜을 사용하지 않는 HTTP API들은 바로바로 확인할 수 있게되었으니까요.

 

일단 친구 찾기 부분만 간단하게 Python으로 구현해보면 다음과 같습니다:

 

다음 포스트에서는.. 진짜 LOCO 프로토콜에 대해서 알아보도록 하겠습니다.. ㅋㅋ.. 재미난게 많아요 :D

 

 

You may also like...

10 Responses

  1. rootnix says:

    세준님 정말 재밌게 봤습니다~!
    앞으로 계속 포스팅 바래요~!!

  2. adult_child says:

    좋은 내용 잘 봤습니다..

    저도 위와 같이 분석을 따라 해보고 싶은데.. 혹시

    위에서 분석한 바이너리 버전을 저도 받아볼 수 있을까요 ‘ㅡ’?

    KaKaoTalkSLLib.dll
    KakaoTalkWP71.dll

    이거라고 하셨는데…

    이거 두개만 있으면 PC에서도 윈도우 모바일 환경을 꾸미고 위 두파일 로드하여

    카카오톡을 실행 할 수 있는건가요 ‘ㅡ’

    • Cai says:

      안녕하세요-
      이론상 가능하긴 하지만 해보진 않아서 모르겠네요 ^^;
      PC에서의 카톡 실행 목적보다는 카톡의 기능들을 따로 구현하는데 의의가 있던 분석이기 때문이죠. 바이너리 요청은 제 개인 이메일로 따로 연락 주시면 되겠습니다. 좋은 하루 되세요!

  3. xap은zip이에요 says:

    제가알기론.

    • Cai says:

      네 맞습니다 :)
      딱히 다르다고 표현한적은 없는듯 싶은데, 많이들 아실법 해서 굳이 같다고 말한적도 없군요. 햇갈리셨던 독자분들은 xap파일은 zip처럼 압축을 푸시면 됩니다.

    • goodguy says:

      블로깅 잘 봤습니다~
      패킷 분석과 관련하여 궁금한게 있어서 메일로 문의 드릴까 하는데요.
      메일로 보내 드림 확인해 주시나요?

      • Cai says:

        네, 한동안 카톡관련해서는 손대지 않아서 거의 다 잊었거나 많이 바뀌었겠지만.. 제가 아는/기억하는 한에서는 답변해드립니다 :)

  4. 죽향 says:

    안녕하세요 Cai님!

    session_key 부분을 어떻게 추출할수 있을까요?

    안드로이드 버전에서 apk파일을 받았는데.. 초보자라 어떻게 해야할지 감도 안오네요. ㅠㅠ

    • Cai says:

      세션키는 https대신 http를 사용하게하여 패킷캡쳐를 하시거나 loco 패킷을 decrypt하시면 됩니다. 아니면 루팅된 폰이라면 저장되어있는 세션키를 직접 읽어도 되구요.

  5. 유창열 says:

    바이러니 요청좀 합니다.
    KaKaoTalkSLLib.dll
    KakaoTalkWP71.dll

    b41206@naver.com 부탁드립니다.

Leave a Reply

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