Sissel's blog

网闸啊,看看我的分片小工具

字数统计: 1.3k阅读时长: 5 min
2021/07/05 Share

需要做一个没那么定制化,但又不能没有用的小工具,来绕过旁路waf、网闸这样的东西,今年演练时鹿师傅实在是太秀了。

0. 补充知识

MTU:最大传输单元(英语:Maximum Transmission Unit,缩写MTU)是指 数据链路 层上面所能通过的最大数据包大小(以字节为单位)。Linux下默认范围是68-9000,分片会在 网络层 进行,并完成重组。

MSS:TCP最大报文段长度(Max Segment Size),通常的转换方式为 MSS = MTU - 40,这个40里面是20的tcp header,20的ip header。
当一个主机想要把 MSS 设置到一个非默认的值时,MSS 大小会以一个 TCP 可选项的方式在握手时的 SYN 包中定义。由于最大分段大小被一个 TCP 参数控制,主机可以在接下来的任意分段中改变它。

1. 简单的方案

  1. 将代理服务器的MTU改小,会出现ip层切片传输。
  2. 将代理服务器的MSS改小,会出现TCP层的分片(segment)。

1.1 修改MTU

1
2
sudo ifconfig eth0 mtu 100
netstat -i

另外可以硬核一些,将mtu设为68(内核中的min_mtu)

1
sudo ifconfig eth0 mtu 68

看看内核代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int dev_validate_mtu(struct net_device *dev, int new_mtu,
struct netlink_ext_ack *extack)
{
/* MTU must be positive, and in range */
if (new_mtu < 0 || new_mtu < dev->min_mtu) {
NL_SET_ERR_MSG(extack, "mtu less than device minimum");
return -EINVAL;
}

if (dev->max_mtu > 0 && new_mtu > dev->max_mtu) {
NL_SET_ERR_MSG(extack, "mtu greater than device maximum");
return -EINVAL;
}
return 0;
}

很不错,这很不错。
思考一下,在网络层分片之后,理论上只会在des ip的主机上重组。但是在到达目标主机的路上会出现被一些waf、路由器、交换机等丢弃 or 在路上被某些重组的情况。另外仅修改MTU其实并不能完全满足我们的需求,我们还需要例如 构造虚假id、加入奇怪的标志位、随机等待 等操作(参考腾讯SRC的文章)。

下面考虑在传输层做分片。

1.2 直接修改MSS

1
2
3
4
5
# 根据mtu来计算mss
sudo iptables -A OUTPUT/INPUT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

# 设置mss
sudo iptables -A OUTPUT/INPUT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 64

配置在客户端,在协商时SYN,给出了mss=64,服务端回了一个1460。最终传输时ms=64并没有生效。
且和上面的需求同理,我们需要对包进行更加复杂的配置,所以未继续跟下去。

2. 更好的选择 NFQUEUE

Nfqueue是iptables和ip6tables的target,这个target可以将数据包交给用户空间。比如,下面的一个iptables规则

1
iptables -A INPUT -j NFQUEUE --queue-num 0

那么在用户空间,可以使用libnetfilter_queue来连接到queue 0(默认)并且从内核获得该消息,然后,必须给出对这个数据包的裁决(Drop,Accept等等)

一般在iptables中的target有以下五种(ACCEPT,DROP,RETURN,QUEUE,other_chain,而NFQUEUE是QUEUE的扩展。相比于QUEUE,它可以由用户指定不同的queue number。

3. 做一个自动分片的小工具

我基于 https://github.com/kkevsterrr/geneva 进行了修改,做到了遇到恶意关键字会自动分片,拆分包等待k秒,重发某个包等功能的小工具hh

主要是看看规则树怎么实现的,我要往里面添加更多有意义的功能。

strategy

传入的规则参数叫 string_strategy,在 /engine.py 中 构造engine时解析

1
self.strategy = actions.utils.parse(string_strategy, self.logger)

跟入 /actions/utils.py 中,注释的非常清楚 \/ 作为规则中出包和入包的分割,先出后入。同一个方向中,又会以 | 作为不同规则的分割。最终每个规则被构建成ActionTree

1
2
new_tree = actions.tree.ActionTree(direction)
success = new_tree.parse(str_action, logger)

再跟入 /actions/tree.py 的 parse 方法,它会将过滤器及操作,用正则匹配出来。我们主要看action部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# The format of each action matches this regular expression. For example, given
# the action tree: [TCP:flags:SA]-tamper{TCP:flags:corrupt}-|
# it would parse out the trigger "TCP:flags:SA" and the tree as
# "-tamper{TCP:flags:corrupt}"
match = re.match(r"\[(\S*)\]-(\S*)|", string)
if not match or not match.group(0):
logger.error("Could not identify trigger or tree")
return False

# 主要看action
# Parse the rest of the tree and setup the action tree
try:
self.action_root = self.do_parse(self.action_root, tree, logger)
except ActionTreeParseError:
logger.exception("Exception caught from parser")
return False
1
2
3
4
5
# Parse the action_string using action.utils
action_obj = actions.action.Action.parse_action(action_string, self.direction, logger)
if not action_obj:
raise ActionTreeParseError("Did not get a legitimate action object from %s" %
action_string)

好的,学会了1+1,接着去添加自己的node就可以了!后面的内容,迫于是内部小工具,不在博客写啦!

n. 参考资料

Linux下TCP-MSS 修改,实验以及测试(详细):
https://blog.csdn.net/Victordas/article/details/101534276

iptables设置mss
https://developer.aliyun.com/article/520008

知乎:IP数据分片之MTU和TCP的MSS
https://zhuanlan.zhihu.com/p/100385612

windows可以通过一个工具来修改 DrTCP
http://www.dslreports.com/drtcp

腾讯SRC:网络层绕过IDS/IPS的一些探索(好东东)
https://security.tencent.com/index.php/blog/msg/147

iptables设置mss
https://developer.aliyun.com/article/520008

Segment和Fragment的区别(实验,tcp直接分段传输,udp只能ip分片)
https://blog.csdn.net/jacicson1987/article/details/111178705

CATALOG
  1. 1. 0. 补充知识
  2. 2. 1. 简单的方案
    1. 2.1. 1.1 修改MTU
    2. 2.2. 1.2 直接修改MSS
  3. 3. 2. 更好的选择 NFQUEUE
  4. 4. 3. 做一个自动分片的小工具
    1. 4.1. strategy
  5. 5. n. 参考资料