通过iptables 修改数据包TTL,来隐藏traceroute 时的路由跳数

原理

程序利用增加存活时间(TTL)值来实现其功能的。每当数据包经过一个路由器,其存活时间就会减1。当其存活时间是0时,主机便取消数据包,并发送一个ICMP TTL数据包给原数据包的发出者。

程序发出的首3个数据包TTL值是1,之后3个是2,如此类推,它便得到一连串数据包路径。注意IP不保证每个数据包走的路径都一样。

实现

主叫方首先发出 TTL=1 的 UDP 数据包,第一个路由器将 TTL 减1得0后就不再继续转发此数据包,而是返回一个ICMP 超时报文,主叫方从超时报文中即可提取出数据包所经过的第一个网关地址。然后又发出一个 TTL=2 的UDP 数据包,可获得第二个网关地址,依次递增 TTL 便获取了沿途所有网关地址。

需要注意的是,并不是所有网关都会如实返回 ICMP 超时报文。出于安全性考虑,大多数防火墻以及启用了防火墻功能的路由器缺省配置为不返回各种 ICMP 报文,其余路由器或交换机也可被管理员主动修改配置变为不返回ICMP 报文。因此 Traceroute 程序不一定能拿全所有的沿途网关地址。所以,当某个 TTL 值的数据包得不到响应时,并不能停止这一追踪过程,程序仍然会把 TTL 递增而发出下一个数据包。一直达到默认或用参数指定的追踪限制(maximum_hops)才请勿追踪。

依据上述原理,利用了 UDP 数据包的 Traceroute 程序在数据包到达真正的目的主机时,就可能因为该主机没有提供 UDP 服务而简单将数据包抛弃,并不返回任何信息。为了解决这个问题,程序设计者使用了一个技巧,因UDP 协议规定端口号必须小于 30000 ,他故意违反协议设置了一个大于 30000 的端口号,所以目标主机收到数据包后唯一能做的事就是返回一个“端口不可达”的 ICMP 报文,于是主叫方就将端口不可达报文当作跟踪退出的标志。

隐藏此后的4跳路由

Iptables -t mangle -A PREROUTING -m ttl –ttl-gt 1 -j TTL –ttl-inc 4

在PREROUTING链上抓数据包只要是TTL大于1的 将TTL加4.

验证配置

iptables -t mangle -nvL

Chain PREROUTING (policy ACCEPT 684G packets, 41T bytes)

pkts bytes target prot opt in out source destination

684G 41T TTL all — * * 0.0.0.0/0 0.0.0.0/0 TTL match TTL > 1 TTL increment by 4

Ttl (match TTL value)

This module matches the time to live field in the IP header.

–ttl-eq ttl

Matches the given TTL value.

–ttl-gt ttl

Matches if TTL is greater than the given TTL value.

–ttl-lt ttl

Matches if TTL is less than the given TTL value.

TTL (change TTL value)

This is used to modify the IPv4 TTL header field. The TTL field determines how many hops (routers) a packet can traverse

until it’s time to live is exceeded.

Setting or incrementing the TTL field can potentially be very dangerous, so it should be avoided at any cost.

Don’t ever set or increment the value on packets that leave your local network! mangle table.

–ttl-set value

Set the TTL value to ‘value’.

–ttl-dec value

Decrement the TTL value ‘value’ times.

–ttl-inc value

Increment the TTL value ‘value’ times.

禁止PC机上tracert

iptables -A FORWARD -p icmp -m length –length 92 -j DROP

length

This module matches the length of the layer-3 payload (e.g. layer-4

packet) of a packet against a specific value or range of values.

[!] –length length[:length]