카카오톡 패킷 복호화 - kakaotog paekis boghohwa

내가 톡방에 쓰는 메세지는 어떻게 전송되고 있는 것일까 문득 궁금해졌습니다.

그래서 일단 Burp 프록시를 걸어서 잡아봤습니다. 몇몇 페이지(Pay, #뉴스, 카카오TV 등)는 SSL Pinning이 걸려있는지 네트워크 연결상태가 좋지 않다고 나옵니다.

카카오톡 패킷 복호화 - kakaotog paekis boghohwa

Pinning 우회를 하게 되면 카톡 앱 내부의 페이지들의 패킷을 Burp 또는 Fiddler 프록시로 들여다 볼 수 있습니다.

카카오톡 패킷 복호화 - kakaotog paekis boghohwa

그런데 문제는 카톡 대화방 내에서의 패킷은 프록시에 잡히지가 않습니다. HTTP나 HTTPS가 아닌 다른 프로토콜을 쓰고 있는게 분명해 보입니다.

카카오톡 패킷 복호화 - kakaotog paekis boghohwa

혹시 대화방에서의 내 메세지가 암호화가 되지 않은채 평문 전송하고 있는 것은 아니겠지? 라는 생각이 들었습니다만, 후킹을 통해 살펴보니 AES로 잘 암호화해서 전송하고 있네요.

카카오톡 패킷 복호화 - kakaotog paekis boghohwa

이번에는 와이어샤크로 대화방 내의 패킷을 잡아보니 암호화된 패킷이 TCP 프로토콜을 이용하여 서버의 5242 포트로 전송되고 있습니다. 포트 번호는 고정되어 있지 않고 5223, 5228, 5242, 9282 등 카톡을 재실행하거나 네트워크 연결 오류가 발생하면 바뀌더군요.

카카오톡 패킷 복호화 - kakaotog paekis boghohwa

어떤 때는 80번 포트로도 전송되는데 HTTP프로토콜은 아닙니다.(구글 search 해보니 카카오톡은 자체 TCP 프로토콜인 LOCO 프로토콜을 사용하고 있다고 하네요)

카카오톡 패킷 복호화 - kakaotog paekis boghohwa

TCP 패킷은 프록시 설정을 하여도 버프로 잡을 수가 없습니다만, 네트워크 설정 조작을 하면 버프에서도 TCP패킷을 볼 수 있습니다.(hackcatml.tistory.com/98 참고) 카톡 대화방 패킷은 암호화되어 전송되기 때문에 버프로 패킷 잡아봤자 의미가 없지만, 추후 TCP 네트워크 진단 연습용으로 잡아봤습니다.

"Can i catch you using BurpSuite??" 대화방 메세지가 TCP패킷에 담겨서 AES로 암호화된 결과가  hex값("7D 55 74 BB F0 ...")으로 전송되고 있습니다.

카카오톡 패킷 복호화 - kakaotog paekis boghohwa

Request TCP 패킷입니다. 암호화된 TCP 패킷이 날라가므로 알수 없는 지렁이 문자열들이 잡히네요.

카카오톡 패킷 복호화 - kakaotog paekis boghohwa

hex값으로 보면 "Can i catch you using BurpSuite??" 문자열이 TCP 패킷에 담겨 잘 암호화되어 전송되고 있는지 확인 가능합니다.

카카오톡 패킷 복호화 - kakaotog paekis boghohwa

무료 인증서의 보편화로 인하여 기업의 서비스 뿐만 아니라 개인 도메인에 대한 암호화에 대한 처리는 날이 갈수록 높아지는 상황에서, 특히 응용프로그램 제어 뿐만 아니라 악성 코드를 배포하기 위한 서버 또한 암호화 통신을 하여 제어하기 어렵게 만들고 있다.

그림 1. Let's Encrypt 도메인 추세(출처: https://letsencrypt.org/2018/12/31/looking-forward-to-2019.html)

전용 암복호화 장비나 HAproxy와 같은 리버스 프록시를 이용하여 종단 서버구간의 페이로드를 식별하는 방법이 있지만, 성능 문제나 일부 응용프로그램들은 복호화 불가능한 문제가 여전히 남아있다.

Inspection이 불가능한 패킷을 TCP 헤더 및 SSL/TLS Handshake 패턴을 통한 제어

카카오톡 패킷 복호화 - kakaotog paekis boghohwa
그림 2. TLS 사이트 접속시 SNI 필드

alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (msg:"web.telegram"; flow:to_server,established; tls_sni; content:"web.telegram.org";  sid:8300001; rev:1;)

※ tls_sni 키워드는 suricata only parsing 키워드로 snort에선 지원하지 않음 (snort에서는 parsing만 불가할 뿐 매치는 정상적으로 가능)

대부분의 업체들은 서버 설정파일 내 vhost를 지정하여 한 개의 IP로도 복수의 도메인 서비스를 제공한다.

이를 식별하기 위해서 ServerNameIdicataion(SNI) 필드가 사용되며, SSL handshake의 client hello에서 확인하여 SSL 패킷에 대하여 부분적으로 제어가 가능하다. 한국은 현재 방송통신심의위원회가 관리하는 Warining 사이트에 대하여 DNS를 필터링 하여 제어하고 있기 때문에 https 접속에 대하여 제어가 불가능하다.

현재의 시스템을 변경하여 SNI 필드를 검출하는 방식으로 변경할 예정이라고 한다.

SNI 필드의 문제

  • SNI 필드의 사용은 필수가 아님
  • Webapp이 아닌 설치형 응용프로그램들은 정해진 주소를 사용하는 서버와 통신하는 경우가 종종 있음
  • Encrypted-SNI(ESNI) 사용으로 필드가 암호화 되어 제어가 어려움
  • cloudflare와 파이어폭스 등에서 지원. 아직까지는 지원 사이트가 거의 없음
  • ESNI는 초기 단계로 향후 몇년간 SNI 필드 제어는 크게 문제없으나 장기적으로 다른 해결책이 필요함

SNI 필드 또는 SSL/TLS handshake 정보 제어는 정교한 제어가 불가능 함


ex. 카카오톡의 파일첨부 기능 등
카카오톡은 장문의 메시지를 전송할 때는 일반 텍스트 전송이 아닌 파일첨부와 동일한 양상을 보이기 때문에 단순한 장문 텍스트인지 파일첨부 인지 식별이 불가능함

그림 3. 암호화된 SNI 필드 (Unknown type 65486)

헤더 정보를 활용한 SSL/TLS 제어

카카오톡은 1000 bytes를 초과 장문 전송은 파일첨부와 같은 형식으로 전송을 한다.

그림 4 .  카카오톡의  1000 bytes  미만의   텍스트   전송그림 5 .  카카오톡의  1000 bytes 이상 의   텍스트   전송그림 6 .  카카오톡   파일   첨부   시   패킷

일반 텍스트 전송은 세션이 종료되기 전까지 메시지를 전송했을 때 누적되어 전송 되는 반면, 1000 bytes를 초과하거나 파일 첨부 시에는 매번 세션을 열고 종료하는 차이가 발생하는 것을 확인할 수 있다. 또한 일반 텍스트 전송은 전송 메시지와 응답 메시지에 따라 Seq와 ACK도 누적되지만, 파일 첨부 트래픽은 최종 응답 메시지 이전까지 Client의 ACK가 67로 유지된다.

이 처럼 파일 첨부는 일반 텍스트 전송과 뚜렷한 양상을 보이지만, 장문 전송과 파일첨부는 구별하기가 어려움이 있다.다만 장문 전송과 파일 전송은 특정 Sequence를 중심으로 -1, +1의 가변적인 길이를 가지는 특징이 있다.아래 3개의 그림은 동일하게 43 bytes의 파일명(확장자 명 포함)을 가지는 파일을 전송 하였을 때의 차이를 보여줍니다.

그림 7. 43 bytes의 파일 명을 가지는 파일 전송 시 ACK(556)그림 8. 43 bytes의 파일 명을 가지는 파일 전송 시 ACK(555)그림 9. 43 bytes의 파일 명을 가지는 파일 전송 시 ACK(554)

파일 전송은 파일명에 따라 길이가 달라지기 때문에 특정 범위를 지정하기가 어렵지만, 장문 전송은 553, 554, 555라는 고정 범위의 값을 가짐

그림 10. 파일 명 길이에 따른 ACK

스프레드 시트에 나와 있듯이 파일명의 길이가 40 부터 44까지는 장문 전송의 ACK 값과 중첩된다.

그렇기 때문에 40부터 44 길이를 가지는 파일에 대해서는 Client Sequence가 5000 bytes를 넘어가는 경우에 한해서 제어한다. 5000 bytes는 장문을 전송하기에도 충분한 길이이며, 파일을 제어하기에도 적절한 경우라고 판단하여 지정한 임의의 값이다.

반면, 그 외 파일 명 길이를 가지는 파일에 대해서는 장문 전송과는 ACK 값이 겹치지 않기 때문에 Stream size에 상관없이 해당 세션을 바로 제어 한다.

파일 첨부를 제어하기 위해서 4개의 룰을 사용하여 제어할 수 있다.

alert tcp $HOME_NET [1024:] ->  $EXTERNAL_NET 443 (msg:"kakaotalk ssl connection"; flow:to_server,established,no_stream; dsize:268; content:"|00 01 00 00 0a 00 00 00 02 00 00 00|"; depth:12; fast_pattern; flowbits:set,kakaossn; noalert; sid:6270006; rev:2;)

alert tcp $EXTERNAL_NET [443] ->  $HOME_NET [1024:] (msg:"kakaotalk upload sessions"; flow:to_client,established,no_stream; flowbits:isset,kakaossn; stream_size:client,>,552; stream_size:client,<,556; stream_size:server,=,1; flowbits:set,kakaofile; noalert; sid:6270007; rev:3;)

alert tcp $HOME_NET [1024:] -> $EXTERNAL_NET 443 (msg:"kakaotalk file session"; flow:to_server,established,no_stream; flowbits:isset,kakaossn; flowbits:isnotset,kakaofile; stream_size:server,=,67; threshold: type limit, track by_src, count 1, seconds 86400; sid:6270008; rev:1;)

alert tcp $HOME_NET [1024:] -> $EXTERNAL_NET 443 (msg:"kakaotalk text section session"; flow:to_server,established,no_stream; flowbits:isset,kakaossn; flowbits:isset,kakaofile; stream_size:client,>,5000; sid:6270009; threshold: type limit, track by_src, count 1, seconds 86400; rev:1;)

1. 카카오톡에서 장문 전송 또는 파일 전송 시 SSLv2 세션을 개시하며, 268 페이로드 사이즈를 가지면서 SSLv2 세션개시 패킷을 확인하고 kakaossn 객체에 세션 정보를 저장한다.
2. Client의 스트림 사이즈가 552보다 크고 556보다 작으면서, Server의 스트림 사이즈가 1이라면 kakaofile 객체에 세션 정보를 저장한다.
3. 확인된 패킷이 kakaossn에 등록된 세션의 일부이지만 kakaofile이라는 세션에 등록된 패킷의 일부가 아니고 서버가 전송한 스트림 바이트가 67이라면 탐지
4. 확인된 패킷이 kakaossn와 kakaofile 모두에 등록된 세션의 일부이고 Client가 전송한 스트림 바이트가 5000을 초과한다면 탐지

User-Agent 식별 JA3

JA3는 SSL/TLS Handshake에서 사용되는 필드들을 사용하여 client를 식별하는 방법으로 Salesforce Engineering의 John B. Althouse, Jeff Atkinson, Josh Atkins의 이름을 본 따서 JA3라고 명명하였으며, Bro IDS, Suricata IDS, NGiNX, Darktrace, Splunk, Ealstic.co 등 다양하게 지원한다.

https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967

JA3는 SSL Handshake에서 Client Hello 메시지의 필드를 구별. User-Agent들의 fingerprint를 식별하는 방법 중 하나로 사용 되기 때문에 내부 사용자가 직접 접속한 특정 사이트 등을 식별하여 접속을 차단하는 등의 제어는 불가능하다.

User-Agent를 식별하기 때문에 SSL/TLS 서버로 DDoS 공격과 같이 악성행위를 하는 외부 봇들의 fingerprint를 식별하여 연결을 차단하는데 사용하는 것은 가능하다.

JA3S는 서버의 응답을 기반으로 한 fingerprint 방법입니다. 탐지에 있어서 JA3보다는 명확성이 떨어지지만 salesforce는 KaliLinux와 같이 특정 C2 연결에 대해서 탐지가 어느정도 가능하며, 서버의 응답을 활용할 수 있다는 가능성을 보여주었습니다. JA3 및 JA3S에 대한 자세한 정보는 salesforce의 링크에 명시되어 있다.

그림 11. Slideshare.net 접속 시 JA3그림 12. linkedin.com 접속 시 JA3