|
原文链接:信息熵在ICMP隧道检测中的实践
ICMP协议通常用来测试网络通不通、主机可不可达、路由可不可用。宅男们打游戏时也常用来ping一下,看看延迟高不高,太高迅雷就得关一关了。
而网络攻击者通过ICMP协议,可以进行隧道传输,实现数据窃取,规避掉一些防火墙规则。
如何检测这种隧道?用传统的签名无法对抗负载加密,复杂的统计比对让检测引擎不堪重负,准确率也不高。
而基于ICMP常规的通讯数据和攻击时产生的畸形数据,利用信息熵来分析,可以为检测打开突破口。
1
ICMP隧道
在ICMP报文中,最值得关注的是类型0x0和类型0x8。0x0类型的ICMP报文代表ICMPECHOREPLAY(响应),0x8类型的ICMP报文代表ICMPECHO(查询)。
以ping命令为例。在进行工作时,ping命令向远程主机发送一个或多个ICMPECHO数据包,其目的是判断远程主机是否可以到达。
ICMP数据包的选项部分可以填写数据,通常在ICMP报文到达远程主机的过程中,记录沿途经过的路由器地址以及沿途经过路由器时耗费的时间。一般的通讯数据形式如下:
 
PTunnel介绍PTunnel是一种可以把TCP链接通过ICMP的显示请求(ping请求)和回复(ping回复)包进行传输的工具。
这种工具能够将数据信息隐秘地送入或送出网络,可以用于只有ICMP数据流允许出入的网络的情况。源码下载地址:
“http://www.cs.uit.no/~daniels/PingTunnel/。”
运行环境PTunnel可以安装在Windows系统和Linux系统中。实验环境为:
客户端:Windows 7 + WireShark 【192.168.12.87】;
服务端:Kali 【192.168.12.234】;
在客户端和服务器端安装PTunnel,双方能直接通过IP地址实现点到点的数据通讯。
运行方式客户端:
 
服务端:
 
模拟场景中,服务端安装MySQL仅允许本地登录,双方与防火墙串联在一起形成单一网络。
通过PTunnel工具建立ICMP隧道,绕过中间防火墙协议和服务器MySQL地址策略的限制,实现在客户端上成功访问服务器的本地MySQL数据库。
在服务器端开启PTunnel监听模式:
- root@localhost:~#ptunnel
- [inf]:Starting ptunnel v 0.71.
- [inf]:(c) 2004-2009 Daniel Stoedle, <daniels@cs.uit.no>
- [inf]:Security features by Sebastien Raveau,<sebastien.raveau@epita.fr>
- [inf]:Forwarding incoming ping packets over TCP.
- [inf]:Ping proxy is listening in privileged mode.
复制代码
在客户端以管理员权限启动cmd命令行,输入命令参数如下:c:\Users\xxxx\Desktop>ptunnel.exe-p 192.168.12.234 -lp 808 -da 127.0.0.1 -dp 3306
将192.168.12.234上的3306端口和本地客户端808端口建立ICMP隧道,实现数据的通讯。在客户端连接808端口就相当于连接远程服务器上的数据库3306端口。
在客户端另起一个cmd命令行,连接本地的808端口,实现对远程服务器192.168.12.234数据库的访问。命令如下:
C:\xampp\mysql\bin>mysql.exe-h 127.0.0.1 -P 808 -uroot -p123456
在客户端上通过PTunnel成功连接上服务器的数据库:
 
数据报文分析实际通信中,客户端将一直发送ICMP请求报文,而对应的服务端将针对请求报文发送ICMP应答报文,从而在服务端和客户端建立起一条ICMP隧道,通过将TCP报文封装在ICMP报文中,从而能够实现数据的传输。
如下图所示,所有的ICMP请求报文均是从客户端发送至服务端:
 
客户端与服务端通过ICMP协议中请求和应答包建立初始连接,数据包序号为3、4,类似于TCP连接中的三次握手:
 
在建立初始连接后,从序号为5的数据包为服务端向客户端发送握手初始化包,该包是为了提醒客户端下面需要进行身份认证:
 
客户端收到服务器提出的身份验证请求后,将身份帐号密码封装到ICMP请求包的data部分,返回给客户端:
 
操作数据库时,可以看到命令和返回信息:
 
 
2
信息熵
如果通过签名规则的方式针对上述流量进行检测还是能起到一定的效果,但如果数据经过了加密,例如SSH的流量,那就无法使用签名的方式来检测。
我们也可以通过找规律的方式去检测,例如负载的长度不一致、请求和响应报数不一致、负载内容相似度等等,包括可以使用suricata的lua规则。但这类规则维护起来比较麻烦,且在公网流量中测试误报较多。
对于这些很难用签名规则检测的恶意流量,不可能直接用一种规则就能准确检测出来,首先需要从来海量流量中找到有异常的部分,也就是找线索。
针对ICMP隧道这类流量,相比正常流量,表现出来的规律就是数据的随机性特别大——没有规律,这就使得信息熵派上了用场。
信息熵信息熵可以作为一个系统复杂程度的度量,如果系统越复杂,出现不同情况的种类越多,那么它的信息熵是比较大的。简单的说就是,信息随机性越强,熵值越大。
检测思路检测思路其实就是观察到的异常现象,用代码语言描述然后落地,但如果没有点数学基础,实现起来就比较费时费力。
具体步骤如下:
首先,采集一定时间内的ICMP流量,计作一段流,作为计算输入。
然后,针对流中的每次ICMP通讯中的负载进行熵计算。
最后,对所有熵计算标准平方差。
如果标准方差为0,则说明这些负载都一样;如果标准方差越偏离0,则说明负载随机性很高,不是正常的ICMP通讯。
代码实现根据信息熵计算的原理,即“对不重复数据的计算,且负载中的不重复数据的数量一定小于报文长度”,通过计算报文的熵,最后进行标准方差计算,部分代码如下。
获取报文熵:
- //判断是否存在
- intIsRepeat(int x,u_char y,u_char** z)
- {
- for(int n = 0; n < x; n++)
- {
- if(z[0][n] == y)
- {
- z[1][n] += 1;
- return1;
- }
- }
- return 0;
- }
- //返回存在个数
- intRepeatCount(u_char* x,int y,u_char** z)
- {
- z[0][0]=*x;
- z[1][0]=1;
- int maxC=1;
- x++;
- for(int n=0;n<y-1;n++)
- {
- if(!IsRepeat(maxC, *x, z))
- {
- z[0][maxC]=*x;
- z[1][maxC]=1;
- maxC++;
- }
- x++;
- }
- return maxC;
- }
-
- //log换底公式
- floatMathLogFunc(float x)
- {
- return(x*(log(x)/log(2)));
- }
- //计算报文的熵
- floatCalcEntropy(int x, int y, u_char** z)
- {
- float result = 0;
- for(int n = 0; n < x; n++)
- {
- result += -MathLogFunc((float)z[1][n]/y);
- }
- returnresult;
- }
- floatgetEntropy(u_char* x, int y)
- {
- u_char**tmp = (u_char**)malloc(2 * sizeof(u_char*));
- for(inti1 = 0; i1 < 2 ; i1++)
- {
- tmp[i1] = (u_char*)malloc(y * sizeof(u_char));
- memset(tmp[i1], 0, y * sizeof(u_char));
- }
- floatresult = CalcEntropy(RepeatCount(x, y, tmp), y, tmp);
- for(inti2 = 0; i2 < 2;i2++)
- {
- free(tmp[i2]);
- }
- free(tmp);
- returnresult;
- }
- 计算标准方差:
- //计算平均值
- floatCalcAverage(float* x, int y)
- {
- floattmp = 0;
- for(inti = 0; i < y; i++)
- {
- tmp+= x[i];
- }
- return((float)tmp/y);
- }
- //计算标准方差
- floatCalcSD(float* x,int y)
- {
- float average = CalcAverage(x, y);
- float tmp = 0;
- for(int i = 0; i < y; i++)
- {
- tmp += (float)pow(x[i] - average, 2);
- }
- return((float)sqrt(tmp/y));
- }
复制代码
测试效果通过PTunnel、Nishang等工具制造出一些ICMP隧道的报文,用程序测试看一下效果。
正常ping百度、163等网站的ICMP报文,计算出来的为0:
 
而计算工具产生的隧道报文时,就看到以下标准方差很大:
 
 
 
3
总结
在现网测试时,往往会遇到一些来历不明的ICMP流量,大多数都是相似的负载,偶尔会夹杂时间戳信息,也会有一些IoT设备发出的流量,调整标准方差来判断即可。
利用信息熵来检测ICMP隧道的方式,能有效的解决规则不好描述、难以维护的问题,但对于一些加密、未知的流量,这种方式只是一个线索发现功能,要确认是否是真正的攻击流量,还需要借助其他数据信息进行综合判断。
|
|