5

TCP安全测试指南-魔兽3找联机0day | WooYun知识库

 6 years ago
source link:
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

TCP安全测试指南-魔兽3找联机0day

在安全测试的过程中,我们通常使用应用层工具直接测试待测目标,比如一个HTTP网站应用程序,我们可以直接发送HTTP请求来对其进行模糊测试,而对于HTTPS,也可以建立SSL连接后直接发送HTTP请求对其进行模糊测试

然而在某些黑盒测试中,由于信息不对称,我们无法获悉应用层协议的具体格式,因此难以直接在应用层进行安全测试,这时我们需要对应用层协议本身进行FUZZ,这就需要使用更底层协议来进行安全测试

本文以著名的RTS游戏魔兽争霸3为例,介绍在网络层对TCP连接进行安全测试的基本工具、方法、以及漏洞挖掘思路

0x00 概述


我想测试魔兽争霸3联机游戏的安全问题

然而魔兽争霸3并没有使用HTTP协议来进行通信,因此我既不能用burp来proxy拦截,也不能直接用curl等常用工具来进行FUZZ

魔兽争霸3联机对战使用了TCP连接,自己定义了一套数据包格式(已经有人分析过了,但在本文中我们假设数据包格式未知)

所以我要在传输层对魔兽争霸3的TCP连接进行安全测试,重点测试以下内容:

  1. 断线重连
  2. 网络的延迟与丢包
  3. TCP原始数据的嗅探/修改
  4. TCP连接的重放与交互式测试

0x01 断线测试


由于魔兽争霸3并没有断线重连机制,所以TCP连接断开后会直接导致游戏断开,而在许多第三方对战平台上,玩家的离线等同于战败,因此也诞生了许多游戏“踢人”外挂

下面使用WooyunWifi路由器上的dsniff工具包中的tcpkill工具为例进行测试:

[email protected]:~# tcpkill -i br-lan port 6112
tcpkill: listening on br-lan [port 6112]
192.168.1.143:59892 > 192.168.1.163:6112: R 2875503812:2875503812(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504063:2875504063(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504565:2875504565(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875503812:2875503812(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504063:2875504063(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504565:2875504565(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970133:2041970133(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970389:2041970389(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970901:2041970901(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875503818:2875503818(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504069:2875504069(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504571:2875504571(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970133:2041970133(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970389:2041970389(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970901:2041970901(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875503824:2875503824(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504075:2875504075(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504577:2875504577(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970142:2041970142(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970398:2041970398(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970910:2041970910(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875503824:2875503824(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504075:2875504075(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504577:2875504577(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970151:2041970151(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970407:2041970407(0) win 0
192.168.1.163:6112 > 192.168.1.143:59892: R 2041970919:2041970919(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875503830:2875503830(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504081:2875504081(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875504583:2875504583(0) win 0
192.168.1.143:59892 > 192.168.1.163:6112: R 2875503830:2875503830(0) win 0

这里演示的是全局切断,在实际应用场景中也可以使用包过滤表达式切断特定IP的连接

0x02 网络的延迟与丢包


由于魔兽争霸3是一个实时对战的游戏,因此网络状态也会影响游戏的进行,魔兽争霸3本身对于实时操作的要求并不高,但是形如DOTA之类的自定义游戏模式对网络的延迟极为敏感,如果玩家在DOTA游戏中有很大延迟,可能会直接导致团灭并且游戏失败

下面使用WooyunWifi路由器上的tc工具中的netem内核模块为例进行测试:

tc qdisc add dev wlan0 root netem delay 1s

由于网络延迟,玩家控制的英雄在延时时间内无法响应玩家的操作

当然,您也可以用包过滤表达式指定任意ip的延时规则,包括随机浮动的延时时间

0x03 TCP原始数据的嗅探/修改


如何嗅探TCP数据包已经是妇孺皆知的常识了,用wireshark或者tcpdump之类的都可以

至于如何修改TCP数据包,我推荐使用TCP透明代理模式来进行操作,原理其实和HTTP透明代理相似

至于工具我测试了3款,各有千秋:netsed简单实用少依赖,mitmproxy无比强大有扩展,bettercap则是替代ettercap的ruby工具

首先,我们在11对战平台上新建一个房间,然后打开wireshark,抓取war3的服务器端口(11对战平台使用的是服务器建主策略,并不是玩家建立主机,而是在服务器上有一个proxy专门用来与各个客户端通信)

我们可以看到建主服务器ip为119.188.39.137,端口为2012,而聊天数据以及最开始交换用户名的数据都是明文的,而且后来测试发现也没有数据完整性验证

下面使用WooyunWifi路由器上的netsed工具为例进行测试:

iptables -t nat -A PREROUTING -p tcp --dport 2012 -j REDIRECT --to 10101

netsed tcp 10101 119.188.39.137 2012 s/lxj616/wooyun



netsed 1.2 by Julien VdG <[email protected]>
  based on 0.01c from Michal Zalewski <[email protected]>
[*] Parsing rule s/lxj616/wooyun...
[+] Loaded 1 rule...
[+] Using fixed forwarding to 119.188.39.137,2012.
[+] Listening on port 10101/tcp.
[+] Got incoming connection from 192.168.1.163,53956 to 119.188.39.137,2012
[*] Forwarding connection to 119.188.39.137,2012
[+] Got incoming connection from 192.168.1.143,50527 to 119.188.39.137,2012
[*] Forwarding connection to 119.188.39.137,2012
[+] Caught client -> server packet.
[*] Forwarding untouched packet of size 771.
[+] Caught client -> server packet.
[*] Forwarding untouched packet of size 791.
[+] Caught server -> client packet.
[*] Forwarding untouched packet of size 24.
[+] Caught server -> client packet.
[*] Forwarding untouched packet of size 24.
[+] Caught client -> server packet.

于是整局游戏里lxj616都在其他用户眼里变成了wooyun,包括聊天和玩家列表

当然,netsed只有简单的替换功能,下面介绍一些更灵活的解决方案(不再以war3为例)

mitmproxy的官方示例介绍了如何修改TCP数据

https://github.com/mitmproxy/mitmproxy/blob/master/examples/tcp_message.py

下面使用Woobuntu系统上的mitmproxy工具为例进行测试:

bettercap的官方示例介绍了如何修改TCP数据:

https://www.bettercap.org/docs/proxying/tcp.html#sample-module

下面使用Woobuntu系统上的bettercap工具为例进行测试:

注:tcp-proxy刚开始时显示未启动,后面在输出信息中后续启动的tcp-proxy

0x04 TCP连接的重放与交互式测试


如果只是想要重放TCP的数据包本身而非TCP连接,使用tcpreplay工具直接重放即可,这种方式确实可以把之前抓取的pcap数据包全部重放到指定的interface上,这在测试一些IDS设备或者有抓包业务逻辑的应用时能起到预期的效果

下面使用Woobuntu系统上的tcpreplay工具为例进行测试:

tcpreplay -i enp0s3 test.pcap

然而仅仅重放抓取的数据包并不能建立有效的tcp连接,因此也不会被服务端正确的响应,这样就起不到FUZZ服务端应用的作用了,我们如果想要和服务端模拟一次真正的TCP会话,就必须在建立新连接后重新填写数据包对应的TCP序列号。形象的比喻一下就是你在重放HTTP请求时要修改你自己cookie里面的session-id

如果要重放tcp连接,可以使用tcpreplay系列工具中的tcpliveplay工具:

http://tcpreplay.appneta.com/wiki/tcpliveplay.html

不过我必须说这工具兼容性太差了,必须要按照官方文档中的Fresh Install Guide来配置特殊依赖,而且内核不可以用新版本,因此在Woobuntu 16.04上根本无法正常运行该工具

不过使用tcpliveplay并不是最好的办法,因为它的原理是解析并修改tcp协议包,而实际上我们的目标并不是解析并修改传输层的tcp协议包,我们只是要FUZZ上层应用,因此我们直接新建一个tcp连接,然后重放tcp承载的数据就可以了

下面以基于Ubuntu的Woobuntu系统为例进行测试,首先安装所需的tcptrace,以及可能需要的tcpslice

apt install tcptrace tcpslice

之后我们抓取我们想要重放的tcp数据包,这里我们用wireshark进行抓取,抓取的是玩家lxj616加入房间然后在聊天栏里面说了两句话整个过程

您也可以在WooyunWifi路由器上通过tcpdump工具进行抓包

tcpdump -i br-lan dst port 6112 -C 100 -z "gzip" -w lxj616.pcap

抓完的包可能会很大,而路由器存储空间较小,所以设置了文件分段,分段的文件形如:

lxj616.pcap

lxj616.pcap1.gz

lxj616.pcap2.gz

(可选)我们可以把他们通过以下命令合在一起:

tcpslice -w full.pcap lxj616.pcap*

在抓到足够的数据包后,我们从中解析出各条tcp连接的数据:

tcptrace -e lxj616.pcap

1 arg remaining, starting with 'lxj616.pcap'
Ostermann's tcptrace -- version 6.6.7 -- Thu Nov  4, 2004

18 packets seen, 18 TCP packets traced
elapsed wallclock time: 0:00:00.027297, 659 pkts/sec analyzed
trace file elapsed time: 0:00:10.018743
TCP connection info:
  1: FullMatelErLuLu.lan:51416 - alkaid-PC.lan:6112 (a2b)   10>    8<

Warning : some extracted files are incomplete!
          Please see -l output for more detail.

这个警告是发现了不完整的TCP数据流,因为我测试时没点退出游戏就关闭抓包了

然后在当前目录下会生成形如a2b_contents.dat或者b2a_contents.dat的文件,找到哪一个是我们需要重放的流数据(同时注意数据方向)

最后我们来重放TCP连接请求测试:

cat a2b_contents.dat | nc 192.168.1.163 6112

而对于游戏主机来说,确实看起来有玩家跑进来说了两句话

0x05 总结


虽然在本文中对魔兽争霸3测试时发现了一些潜在问题,但都只是程序逻辑的小问题,而非安全性bug,因此在不会影响游戏平衡性的条件下,不需要把它们当做漏洞进行报送(虽然对于11对战平台而言,用户名是不可以修改的,但是你改了又能怎样,并没有用),写出本文来分享思路,供同道中人一起学习讨论


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK