[KakaoTalkPC] 카카오톡 PC 버전 분석 (2)

안녕하세요-

저번 글이 카카오톡 PC 버전에 대해선 마지막이 될 수있다고 했었는데.
아마도 이번 글이 정말 마지막이 되지 않을까 싶습니다.

PC 버전만이 아니라 아마 큰 관심이 가는 기능이 추가되지 않는 이상 카카오톡에 대해서는 더이상의 분석은 하지 않을듯 싶습니다.

이러기로 결정한 이유는 크게 두가지인데..

  1. 원래 애시당초 호기심에 시작을 한 분석이므로 블로그 글 한두개정도만 우려먹고 끝낼 예정이었음..
  2. 카카오톡 모바일이나 PC버전의 코어부분을 대충 분석해온 결과, 지난 1년동안 많은 발전이 있었고 솔직히 개발팀/보안팀이 꽤나 잘 함. (즉, 코드 질은 좋아지고 있고 보안적인 실수도 줄어드는 반면에 분석하기는 점점 귀찮고 어렵게 바뀌어가고있음..)

여하튼 이번 글에서 설명할 방법이 얼마나 빠르게 막힐지는 모르겠지만, 혹시라도 유용하게 사용하실 수 있는 분들을 위해 적습니다.

사실 기술 자체는 카카오톡에만 제한된것이 아니기 때문에 이번 기회가 아니라도 언젠간 써먹을 수 있는 날이 오리라 믿….

 

서론. Man in the middle?

오늘 설명 드릴 기술은 Man-in-the-middle (MITM) 이라고 불리는 공격(?) 방법입니다.

간단히 설명하자면 공격자가 클라이언트와 서버사이에 끼어들어서 패킷을 엿보거나 수정하는 공격입니다.
그림으로 표현해보자면… 다음과 같습니다.

KakaoTalk PC (Without MITM)

KakaoTalk PC (Without MITM)

일단 MITM 공격이 이루어지지 않는 원래 상황에서는 클라이언트와 서버사이에 malicious한 다른 기기는 존재하지 않고 통신을 하게 됩니다. 보안에 조금이라도 신경을 쓴 시스템이라면 보통 SSL과 같은 cryptography stack을 이용하여 secure한 통신을 하기 마련인데, 이런 경우에는 제 3자가 중간에서 패킷을 들여다볼 수 있다고 해도 암호화 되어있기 때문에 내용을 쉽게 파악할 수 없습니다.

즉, 카카오톡처럼 HTTPS (SSL/DH key exchange)를 사용하면 그냥 중간에서 패킷을 가로채는것만으로는 내용을 확인할 수 없게 됩니다.

그래서 이런 경우에는 ‘가짜 서버’를 만들어서 클라이언트를 속여야합니다.
결론적으로 클라이언트는 진짜 서버와 통신하고 있다고 생각하여 request를 보내고, ‘가짜 서버’는 마치 자신이 원래 클라이언트인것 처럼 하여 진짜 서버에 같은 데이터로 request를 보냅니다.

여기서 가짜 서버는 원래 클라이언트와 암호화에 사용된 key를 나누었기 때문에 client가 보내는 데이터를 복호화할 수 있습니다.

다시 한번 그림으로 보자면..

KakaoTalk PC (With MITM)

KakaoTalk PC (With MITM)

사실 이런 네트워크 통신 구조를 만드려면 클라이언트의 hosts 파일을 감염시키거나, DNS query를 조작하거나, 또는 ARP poisoning을 통한 공격을 해야하기 때문에 살짝 번거롭습니다. (이정도 되면 그냥 상대 컴퓨터/스마트폰에 루트킷을 까는것이 더 효율적이고 편합니다 -_-)

어찌되었든, 저희 ‘공격자’는 암호화된 내용을 알아내고 싶어하는 ‘클라이언트’이기도 하므로, 공격의 셋업은 상당히 쉬워집니다.
이 부분에 대해서는 아래에서 조금 더 자세히 설명하도록 하겠습니다.

자, 그럼 저렇게 셋업만 하면 끝나는것 아니냐?!

그러게요.. 세상이 참 그렇게 편하면 얼마나 좋겠습니까만…
그러면 재미가 없기 때문에 보안연구가들은 이 공격에 대한 방어책을 구현합니다.
(사실 엄청 당연한 것이기도 하지만.. 한동안 enforce되지 않았던적이 있었죠..)

바로 Certificate Authority (CA) certificate을 체크하는 것인데요.
뭐 자세한건 따로 읽어보고 공부하시도록 하고..

쉽게 설명하면 클라이언트가 ‘내가 지금 서버라고 생각하는 네 녀석이 진짜 그 서버인지 어떻게 알지? 증명해봐‘ 라는 능력을 갖게 되는 것이죠.

KakaoTalk PC (With CA check)

KakaoTalk PC (With CA check)

만약 서버가 클라이언트에게 (SSL 통신 초기에) 제시한 서버의 certificate이 valid한 CA에서 sign된 것이 아니라면 (즉, 만들어진 rogue cert이라면) 클라이언트는 즉시 통신을 중단합니다. 좋은 보안 메커니즘이지만 서버와 클라이언트 사이에 오고가는 데이터를 분석해야하는 저희로써는 꽤나 귀찮은 기능인 셈이죠.

여기서 사용되는 CA certificate은 보통 웹브라우져에 내장되어 배포되거나 운영체제와 함께 배포됩니다.

보통 이런 상황을 공략하기 위해서 임의로 rogue CA cert 또한 만들어서 운영체제에서 trust 하도록 등록합니다. 그러면 어플리케이션에서 (이 rogue CA cert로 sign된) 서버의 cert가 믿음직한 CA에 의해서 sign되었는지 체크할때 통과하게 되겠죠.

하지만 우리의 카카오톡은 그렇게 호락호락하지 않습니다!

운영체제의 CA cert들이야 쉽게 추가 가능하기 때문에 분석자들이 마음만 먹으면 더이상 ‘믿음직한’ 대상이 되지 못하기 때문입니다.

그래서 카카오톡 PC 같은 경우에는 자체적으로 프로그램 내부에 카카오톡 서버들의 certificate을 sign하는데 쓰인 CA의 cert이 내장되어있습니다.
그리고 카톡은 윈도우에서 제공하는 WinHttp* API들을 거의 쓰지 않고 자체적인 http 핸들링을 하기 때문에 (ㅎㄷㄷ.. 요즘도 사실인지는 확인 X) 윈도우 운영체제가 대신 certificate 검사를 해주지 않고 직접 합니다.

카카오톡에서 일하고 계신 지인분에게 들은 바로는 조만간 모바일용 앱에도 자체적 CA cert를 embed하여 시스템에 등록된 cert들이 아닌 앱과 함께 embed된 CA를 상대로 체크할 것이라고 하셨는데.. 이미 구현이 되어있는지는 체크하지 않아서 모르겠습니다. 아하핳.. 전 게으르니까요^_^ 관심있으신분들이 해보시고 알려주시길..ㅋㅋ

 

본론. KakaoTalk PC 패킷 복호화 하기

어쨋든 이쯤되면 뭘 어떻게 해야 성공적인 MITM 공격을 할 수 있는지 알게된 셈입니다.

아직도 모르시겠다구요? 실망입니다.   …장난입니다.

결론적으로는 가짜 서버 (middle man server) 셋업은 보통의 MITM 셋업과 같습니다.
단지 가짜 서버의 certificate을 sign하는데 사용된 rogue CA cert을 프로그램에 내장된 CA cert을 바꿔치기하면 됩니다.

그냥 이렇게만 말하고 끝내면 김이 새니까, MITM 공격을 해보신적이 없는 분들도 해보실 수 있도록 처음부터 차례대로 설명해보도록 하죠!

 

1. Rouge CA Certificate 생성하기

Middle man 서버로 사용할 서버에 ssh해서 들어간 후, 다음과 같이 CA certificate 생성에 사용될 private key를 생성합니다.

다음으로는 self-signed CA certificate을 만듭니다.

여기서 굳이 512 bit으로 하는 이유는 나중에 프로그램 내부에서 바꿔치기를 할때 혹시나 공간 부족 현상이 일어나지 않도록 하기 위함입니다. (원본 CA cert에서는 1024bit이 사용되었습니다.)

현재까지 CA cert를 생성하는데 사용된 private key파일인 x509-ca-key.pem과 CA cert 파일인 x509-ca.pem, 두 파일이 잘 만들어졌다면 다음 스텝으로 넘어갑니다.

 

2. Rouge Server Certificate 생성하기

CA cert을 생성할때와 마찬가지로, server certificate 생성에 사용될 private key를 만들어줍니다.

역시 server certificate을 생성합니다. 앞서 생성한 CA cert로 sign을 함과 동시에 말이죠.

여기까지 잘 따라하셨다면, 총 4개의 파일을 갖게 됩니다: x509-ca-key.pem,  x509-ca.pem,  x509-server-key.pem,  x509-server.pem

마지막으로 chain verification 한번 딱 해주고 certificate들을 설치해주도록 하겠습니다 :)

 

3. Rogue Server Certificate 설치하기

사실 여기서부터는 서버 셋팅에 따라서 조금 차이가 있습니다. 웹서버를 어떤 녀석으로 쓰냐에 따라서 설치 방법에 차이가 있기 때문이죠.

이 글에서는 데모를 위해 nginx 웹서버를 사용하도록 하겠습니다.

일단 server certificate 관련 파일들을 옮겨줍니다. 꼭 이 path로 옮길 필요는 없습니다.

그리고 나서, /etc/nginx/sites-enabled/default  파일을 수정해줍니다.
파일 맨 아래로 오시면 HTTPS 관련 configuration을 보실 수 있습니다. 다음과 같이 수정해줍니다.

주의하실 점은 ssl_ciphers에 DH와 EDH를 추가하셔야 한다는 점입니다~ (이미 추가되어 있지 않다면)

저장하시고 나와서 웹 서버를 재시작 해주시면 준비 완료!

일단 이걸로써 middle man 서버 셋팅은 끝이 났습니다.
다음은 클라이언트 쪽을 수정해주어야 합니다.

기억하시죠? hosts 파일 수정 Go Go!

 

4. Hosts 파일 수정하기

카카오톡 클라이언트가 설치되어있는 윈도우 머신에서 다음 경로로 이동합니다.

C:\WINDOWS\system32\drivers\etc

여기서 hosts 파일을 애용하시는(?) 텍스트 에디터를 사용하여 관리자 권한으로 수정합니다.
(저는 notepad를 사용하도록 하겠습니다.)

Hosts file

hosts file

검은색으로 가려진 부분에는 middle man 서버 아이피를 적으시고 host name에는 MITM를 하고자하는 서버의 host name을 적어주시면 됩니다.

저희 같은 경우에는 로그인할 때 이용되는 sb-talk.kakao.com 서버인척 할 계획이므로 위와같이 적어줍니다.

 

5. 카카오톡 클라이언트 내장 CA Certificate 바꾸기

이제 마지막으로 해야할 것은 카카오톡 PC 클라이언트에 내장되어있는 CA Certificate을 바꿔치기하는 것입니다.

이걸 하는데는 여러가지 방법이 있는데, 일단 클라이언트 자체는 Themida를 통해 패킹되어있으므로 언팩을 실시한 후 바이너리 에디팅을 통해 static하게 바꿔주거나 메모리상에서 바꿔주면 됩니다. 여러면에서 두번째 방법이 구현하기도 쉽고 접근하기도 쉬우므로 추천합니다.

이 작업을 조금 더 쉽게 하는것을 돕기 위해 간단한 툴을 만들어 배포합니다.
물론, 단순한 Proof-of-Concept 용도이기 때문에 모든 컴퓨터에서 잘 작동한다는 보장은 없습니다 ^_^

KakaoTalk PC CA Cert Replacer

KakaoTalk PC CA Cert Replacer

GPLv2 라이센스로 Visual Studio 프로젝트를 github에 올려두었으니 수정하거나 직접 빌드하고 싶으신 분들은 그렇게 하시면 되겠습니다. (-_- 평생 개인프로젝트 용도로 public repo는 써본적이 없는데 이런데서 쓰게 되는군요..ㅋㅋㅋ)

그냥 막히기 전까진 쓰겠다하시는 분들은 여기서 다운받아서 쓰시면 됩니다.
** 주의 ** 해당 툴을 실행하시기 위해서는 .NET 4.0 이상이 필요합니다. 설치되어있지 않다면, 여기서 다운받으실 수 있습니다.

사용 방법은 아래 부록을 참조하시면 됩니다.

 

6. KakaoTalk PC 로그인 request 패킷 복호화 하기

일단 ‘가짜’서버 쪽 로그를 확인하면 다음과 같은 결과를 확인할 수 있습니다.

위의 로그는 성공적으로 MITM을 하여서 카카오톡 서버와 통신하고 카카오톡 인증번호 문자를 받아서 로그인하는 과정입니다. 아마 예전 포스팅들을 주의깊게 보신 분들은 request URL들이 익숙하실테죠 :)

어찌되었든, Wireshark으로 덤프를 뜨면 SSL 세션은 여전히 암호화되어 보입니다.

자 그럼 이 암호화된 패킷들을 어떻게 복호화하느냐?!
예전엔 recompile하여야 했던 기능이 요즘엔 Wireshark에 내장되어있어서 편하게 설명할 수 있겠네요!

일단 시작하기 전에, 2번 스텝에서 생성했던 x509-server-key.pem 파일을 로컬 컴퓨터에 저장해두시고 경로를 기억해두셔야 합니다.

1. 패킷들을 캡쳐한 뒤, Edit  -> Preferences 를 갑니다.
2. 왼쪽 서브메뉴에서 Protocols 를 확장하고 SSL을 선택합니다.
3. RSA keys list  항목의 Edit  버튼을 누릅니다.
4. New 를 누르고 IP address에는 middle man 서버의 아이피를, Port443을, Protocolhttp를, Key file에는 위에서 받아놓은 x509-server-key.pem 파일의 경로를 넣으시면 됩니다.
5. OK  버튼을 누른 뒤,  Apply 를 눌러 적용합니다.

제대로 따라하셨다면, 이제 패킷들을 다시 보시면 차이점을 확 느끼시게 될겁니다 :p
다음과 같은 복호화된 HTTP 패킷들이 보일테니까요!

Decrypted Packet

Decrypted Packet

이제 여기서 오른쪽 클릭을 하신 후, Follow SSL Stream 을 하시면 다음과 같이 HTTP Request 내용을 plaintext로 보실 수 있게됩니다.

Decrypted SSL Stream

Decrypted SSL Stream

 

결론. 유용한 MITM

이번 시리즈를 시작했을때 언급했던것과 같이 사실 이 포스팅은 카카오톡 PC에 대한것이라기 보다는 전반적으로 SSL을 사용하는 앱/프로그램들을 분석하는데 유용하게 사용될 수 있는 MITM 접근 방법에 대해서 설명하는 포스팅이라고 보는것이 더 정확할 듯 합니다.

사실 카카오톡 PC 클라이언트가 특별한 case study였던 이유는 OS에 내장되어있는 CA를 사용하지 않고 자체적으로 패킹된 프로그램 내부에 가지고 있는 CA certificate을 사용하여 검증하였다는 사실때문입니다.

이런 이유때문에 현존하는 generic한 방법으로는 카카오톡 PC를 상대로 MITM 공격을 할 수 없었던 것이죠. 이 부분에 있어서 위에서 잠깐 말했듯이 카카오톡 엔지니어분과 살짝 이야기했던적이 있는데, 이미 인지하고 계신 부분이라.. 뭐 딱히 카카오측에서 놀랄만한 접근 방법은 아니라고 생각합니다. 아마도 개인적으로는 CA Certificate부분을 메모리상에서 plaintext로 풀어둘것이 아니라, 암호화해놓고 Themida의 vmprotect 기능을 사용하여 decrypt하고 verify하는 루틴을 짜면 분석하기가 훨씬 더 귀찮아지지 않을까 하는… 제안(?)을 해봅니다… (물론 불가능한것은 없기에 충분한 노가다를 통하면 분석/바꿔치기 가능합니다 -_-)

그리고 아마 곧 openssl library를 동적 링크하지 않고 static하게 링크할 계획을 가지고 있다고 알고 있습니다. 그럼 분석이 더더욱 빡세지겠죠.. 하하하.

뭐… 쨋든 결론으로 돌아가자면..

1. 카카오톡은 엔지니어링/보안에 꽤나 고민을 많이 하고 있고, 충분히 잘 구현하고 있다 — 적어도 국내에서는 제대로 보안의 문제와 해결방법을 이해하고 있는 많지 않은 팀 중 하나라고 생각함.
2. 이제 잠정적으로 카카오톡 분석은 중단. 이메일을 몇십개 보내셔도 답장 못받으실 거에요 ㅠㅠ
3. 위에서 설명한 MITM을 이용한 암호화된 패킷 분석은 수많은 곳에서 적용하여 사용 가능!

 

긴 글 읽어주셔서 감사합니다. _ _)

다음 주제는 뭐가 될지 모르겠지만… 그때까지 안녕히~

 

————————————-

부록. KakaoTalk PC CA Cert replacer 사용법

Step 1: 카카오톡 PC 실행 및 Replacer 실행

카카오톡 PC 클라이언트를 먼저 실행한 뒤, Replacer를 실행합니다.

만약 Replacer가 카카오톡 PC 클라이언트를 찾지 못했다면 에러 메세지를 보여줍니다. 카카오톡을 켜신 후, Refresh 버튼을 누르시면 됩니다.

KakaoTalk PC CA Cert Replacer

KakaoTalk PC CA Cert Replacer

 

Step 2: 카카오톡 PC 내장 CA Certificate 읽어들이기

사실.. 누를 수 있는 버튼이 그리 많지 않죠 ^_^?

Read 버튼을 누르시면 프로그램안에 내장되어있는 CA Certificate을 찾아서 보여줍니다.

Original Certificate

Original Certificate

참 쉽죠?

 

Step 3: Middle man 서버 CA certificate 덮어쓰기

이전에 만들어둔 x509-ca.pem 기억나시죠?

그 내용을 그대로 복사 붙여넣기 해줍니다.

그리고 나서 Write 버튼을 눌러주시면 끝!

Replacing CA Cert

Replacing CA Cert

위와 같이 성공 메세지를 보실 수 있으면 다 된것입니다.

이제 이 상태로 카카오톡 PC에서 로그인을 하시면 됩니다. 물론, hosts 파일 변경하는것 까먹지 마시구요.

 

*** 주의 *** Replacer 툴은 프로세스의 메모리를 덮어씌우는 형태기 때문에 카카오톡을 끄게되면 MITM 패치적용이 해제됩니다. 카카오톡 프로세스를 껐다 키셨다면, 위의 작업을 다시 해주셔아합니다 ;)

 

You may also like...

22 Responses

  1. ㅇㅇ says:

    안녕하세요 혹시 카카오톡 상대방과 대화하다가 상대방이 저의 아이피 주소를 알아내는 경우가 있나요?
    그게 가능한가요?

    • Cai says:

      최근엔 보지 않아서 모르겠지만, 카카오톡 자체만으로 대화를 통해서 아이피를 알아내는것은 불가능합니다 (서버를 통해서 메세지 등이 전달 되기 때문이죠). 하지만 상대방이 보낸 링크 등을 클릭하여 (특히 상대방이 컨트롤하는) 다른 외부 사이트를 방문 시 아이피를 알아낼 수 있습니다.

  2. kknd says:

    지나가다 재밌게 보고 갑니다^^

  3. 0x4B5348 says:

    안녕하세요. 궁금한 것이 하나 있어서 덧글 남기고 갑니다.
    카카오톡과같은 클라이언트를 분석하는데, 서버가 없는 경우에 패킷을 분석할 수 있을까요?
    만약 안된다면, 클라이언트를 직접 분석해서 어떤 패킷을 정의해서 보내는지 알아낼 수 있나요?

    정말 좋은 글 잘봤습니다. 글이 되게 동기부여를 시켜주네요. 감사합니다.

  4. 0x4B5348 says:

    좋은 글 잘봤습니다. MITM단에서 패킷을 적절히 처리하고 임의의 값을 리스폰스해주면, 사설 서버와 같은 개념이 되나요?

Leave a Reply to 0x4B5348 Cancel reply

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