모바일 앱 통신 프로토콜 종류 중 HTTP(S)가 아닌, TCP로 통신하는 앱이 있다.
TCP 통신 패킷은 BurpSuite의 기본적인 기능만으로는 Intercept 할 수 없기 때문에,
다른 방법을 찾아야한다.
BurpSuite Extender에 NoPE Proxy
라는 툴로 TCP 통신을 Intercept 할 수 있긴 하지만,
오늘은 mitm_relay
라는 파이썬 스크립트를 사용해보겠다.
mitm_relay
HTTP(S)가 아닌 다른 프로토콜을 사용하는 통신 패킷을 Intercept 하여BurpSuite와 연결해서 사용할 수 있는 아주 좋은 툴이다.
다운받아서 파이썬으로 실행하면 간편하게 사용할 수 있다.
옵션 사용법은 다음과 같다.
-h, --help 이 도움말 메시지를 표시하고 종료
-l <듣기>, --listen <듣기>
릴레이가 수신할 주소입니다. 기본값: 0.0.0.0
-r <릴레이> [<릴레이> ...], --relay <릴레이> [<릴레이> ...]
새 릴레이를 만듭니다. 매개변수를 반복하여 여러 릴레이를 생성할 수 있습니다. 프로토콜이
생략하면 TCP로 간주됩니다. 형식: [udp:|tcp:]lport:rhost:rport
-s <스크립트>, --script <스크립트>
handle_request() 및 handle_response() 함수를 구현하는 Python 스크립트(예제 참조). 그들
지정된 경우 트래픽을 프록시로 전달하기 전에 호출됩니다.
-p <프록시>, --proxy <프록시>
모든 요청/응답을 전달할 프록시입니다. 생략하면 트래픽이 콘솔에만 인쇄됩니다.
(스크립트가 지정되지 않은 경우 모니터링 모드). 형식: 호스트:포트
-c <인증서>, --cert <인증서>
SSL/TLS 가로채기에 사용할 인증서 파일
-k <키>, --key <키>
SSL/TLS 가로채기에 사용할 개인 키 파일
-cc <클라이언트 인증서>, --clientcert <클라이언트 인증서>
서버 연결에 사용할 클라이언트 인증서 파일
-ck <클라이언트 키>, --clientkey <클라이언트 키>
서버 연결에 사용할 클라이언트 개인 키 파일
-t <tls1|tls11|tls12|ssl2|ssl3>, --tlsver <tls1|tls11|tls12|ssl2|ssl3>
SSL/TLS 버전 강제 실행
-sk <ssl 키 로그 파일>, --sslkeylog <ssl 키 로그 파일>
SSL(사전)마스터 비밀을 <ssl keylog 파일>에 덤프합니다.
-ct 1.0, --client-timeout 1.0
클라이언트 소켓 연결 시간 초과
-st 1.0, --server-timeout 1.0
서버 소켓 연결 시간 초과
일반적으로 사용하는 옵션은 -l
, -p
, -r
옵션이다.
간단하게 예시를 들어보자면, 다음과 같다.
-l
옵션을 통해 BurpSuite를 사용하는 PC의 IP를 설정하고,
-p
옵션으로 BurpSuite에 설정된 Proxy 서버 및 포트를 설정한다.
-r
옵션은 Intercept 후 마지막으로 목적지에 보내주는 서버 IP를 설정하면 된다.
python mitm_relay.py -l <InterceptPC_IP> -p <proxyIP:port> -r <Protocol:Port:ServerIP:Port>
실습 환경
1. Android 환경 설정
첫 번째로 해야할 일은, 안드로이드에서 사용하는 앱에서 서버와 통신하는 IP와 포트를 알아야 한다.
방법은 여러가지가 있지만, 내가 자주 사용하는 방법은 tcpdump를 이용해서 실제로 앱이 서버의 어느 IP와 포트로 통신하는지 패킷을 직접 보는 것이다.
이 방법 말고도 통신 패킷을 저장해서 보여주는 앱들이 플레이스토어에 있으니, 그런 것들을 사용해도 된다.
서버 IP와 포트를 확인했다면, ADB Shell에 접속하여
iptables 설정을 통해 서버로 가는 패킷을 PC로 보내는 룰을 등록해야 한다.
기본적으로 안드로이드에 설치되어있는 앱은 당연히 서버와 통신할 것이다.
여기서, 서버로 가는 패킷들을 모두 PC로 보내버리면 PC에서는 패킷을 받지만, 서버는 받지 못한다.
그 때 mitm_relay.py
를 사용해서 PC로 받은 패킷들을 보거나 변조하고 서버로 보내주는 것이다.
iptables
# iptables -L -t nat
# iptables -t nat -D OUTPUT 1
# iptables -A OUTPUT -t nat -p tcp -d <서버IP> --dport <서버Port> -j DNAT --to-destination <나의PC>
실습 룰 등록
# iptables -A OUTPUT -t nat -p tcp -d 192.168.0.104 --dport 8190 -j DNAT --to-destination 192.168.0.105
# # iptables -L -t nat
... (생략) ...
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere 192.168.0.104 tcp dpt:8190 to:192.168.0.105
... (생략) ...
안드로이드에서 iptables 룰 등록을 완료했으니, 서버(192.168.0.104:8190)로 가는 TCP 패킷들은 이제 다 PC(192.168.0.105)로 가게 될 것이다.
2. PC 설정
두 번째는 PC에서 mitm_relay.py를 실행하는 것이다.
PC로 오는 패킷들을 프록시 서버를 거쳐 본 서버로 보내줘야하기 때문이다.
λ python mitm_relay.py -l 192.168.0.105 -p 127.0.0.1:8080 -r tcp:8190:192.168.0.104:8190
[!] Server cert/key not provided, SSL/TLS interception will not be available.
To generate certs, see provided script 'gen_certs.sh'.
[i] Client cert/key not provided.
[+] Webserver listening on ('127.0.0.1', 49999)
[+] Relay listening on tcp 8190 -> 192.168.0.104:8190
이제 안드로이드에서 서버로 가는 패킷은 PC로 가게 될 것이고,
PC로 온 패킷은 프록시 서버를 거쳐 본 서버로 가게 될 것이다.
BurpSuite를 키고 Proxy 설정을 127.0.0.1:8080
로 맞추기만 하면 된다.
3. 패킷 전송
사실 앱은 TCP 통신을 테스트하는 Simple TCP Socket Tester
앱이다.
사실 서버도 TCP 통신을 테스트하기 위해 구성해놓은 아이폰이다.
이제 안드로이드 폰에서 TCP 통신을 하는 앱을 실행해서
서버로 TCP Test!
라는 문자열을 전송한다.
4. 패킷 변조
안드로이드에서 서버로 패킷을 전송하면, 서버로 가지 않고, PC의 BurpSuite로 Intercept 할 수 있게 된다.
아래 그림과 같이 TCP Test!
라는 문자열이 왔다.
이 문자열을 XCP Xest@
라고 변조해서 보내보겠다.
5. 결과
서버에 도착한 메시지를 보면 처음에 안드로이드가 보낸 TCP Test!
가 아닌 PC가 변조한 XCP Xest@
라는 문자열이 도착한 것을 확인할 수 있다.
mitm_relay.py
를 실행한 콘솔에도 통신되는 패킷 정보가 기록된다.
C >> S [ 192.168.0.102:53498 >> 192.168.0.104:8190 ] [ Sat 30 Jul 15:23:06 ] [ 9 ] (modified!)
XCP Xest@
이렇게 HTTP(S)가 아닌 다른 프로토콜로 통신하는 패킷을 BurpSuite로 Intercept 해서 변조해보았다.
다음에는 NoPE Proxy에 대한 글도 작성해보겠다.