简介
icmptunnel的工作原理是将你的内容封装在ICMP echo数据包中,一般在ICMP数据包的 "data "字段中发送,并将其发送到你自己的代理服务器。代理服务器解压缩数据包并转发。传入的以客户为目的地的IP数据包再次被封装在ICMP回复数据包中,并发回给客户。
icmptunnel通过创建一个虚拟的隧道接口来工作。客户端主机上的所有用户流量被路由到icmptunnel在这个接口上监听IP数据包。这些数据包被封装在一个ICMP echo数据包中(即ICMP数据包的payload只是原始IP数据包)。这个新产生的ICMP数据包被发送到客户机外,通过受限的互联网连接发送到代理服务器。
代理服务器收到这些ICMP数据包并解压缩原始IP数据包。再进行IP伪装后被重新传送到互联网上。因此,目标相信是代理服务器发出的请求。然后,目标用一个IP数据包回应代理服务器。这又被icmptunnel捕获,封装在一个ICMP回复包中,并发回给客户端。
在客户端,IP数据包被从ICMP回复数据包的payload中解析和注入。用户应用程序从这个虚拟接口读取,从而获得适当的IP数据包。
+--------------+ +------------+
| | ICMP traffic | | IP traffic
| Client | -------------------> | Proxy | ------------------>
| | <------------------- | Server | <------------------
| | through restricted | | proper internet
+--------------+ internet +------------+
github仓库:https://github.com/DhavalKapil/icmptunnel
安装使用
- 编译
git clone https://github.com/DhavalKapil/icmptunnel
cd icmptunnel/
make
- 在服务器端以root权限运行的隧道:
icmptunnel -s 10.0.1.1
- 在客户端执行
route -n
,找到你的网关和相应信息:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.100.2 0.0.0.0 UG 0 0 0 ens33
- 编辑client.sh
- 用代理服务器的IP替换
- 用上面的Gateway地址替换
- 用上面的Iface替换
- 在客户端,以root权限运行:
icmptunnel -c <server>
现在隧道应该成功运行,客户端应该能够访问互联网。所有流量都将通过 ICMP 隧道进行传输。
分析特征
ICMP TTL的设置一般情况下与主机的操作系统相关,当然也可以手动去修改。
操作系统 | TTL |
---|---|
UNIX | 255 |
Linux | 64 |
MS Windows 95/98/NT 3.51 | 32 |
MS Windows NT 4.0/2000/XP/2003 Server | 128 |
FreeBSD 2.1R | 64 |
VMS/Multinet | 64 |
Windows XP | 128 |
在源代码icmp.c中233行可以看到TTL被固定为255,从流量中也可以看到TTL为255。
void prepare_headers(struct iphdr *ip, struct icmphdr *icmp)
{
ip->version = 4;
ip->ihl = 5;
ip->tos = 0;
ip->id = rand();
ip->frag_off = 0;
ip->ttl = 255;
ip->protocol = IPPROTO_ICMP;
icmp->code = 0;
icmp->un.echo.sequence = rand();
icmp->un.echo.id = rand();
icmp->checksum = 0;
}
检测思路
- 检测同一来源 ICMP 数据包的数量。一个正常的 ping 每秒最多只会发送两个数据包。而使用 ICMP 隧道的浏览器在同一时间会产生上千个 ICMP 数据包。
- 寻找那些响应数据包中 payload 跟请求数据包不一致的 ICMP 数据包。
- 如果在内网中,可以检查 ICMP 数据包的协议TTL值,icmptunnel 默认会设置所有的 ICMP 的IP层TTL值为255。内网拓扑容易确定具体的跳数,简单计算可以印证。