找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888
查看: 1198|回复: 1

关于iptabled fragment功能无效的验证

[复制链接]
发表于 2020-3-19 14:16 | 显示全部楼层 |阅读模式
本帖最后由 1637664504 于 2020-3-20 18:30 编辑

研究iptables的攻击规则,发现如下的命令无效。
iptabled -A INPUT -f -j DROP

测试
win10: 192.168.0.2
linux: 192.168.0.5

测试1:无分片的报文
win10# ping 192.168.0.5 -->可以ping通

测试2:带分片的报文
win10# ping 192.168.0.5 -l 3000 -->可以ping通

测试3:linux过滤分片的报文
linux# iptables -A INPUT -f -j DROP
win10# ping 192.168.0.5 -l 3000 -->依旧可以ping通

linux# iptables -nvL
Chain INPUT (policy ACCEPT 6729 packets, 8666K bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 DROP       all  -f  *      *       0.0.0.0/0            0.0.0.0/0

可以发现,规则没有匹配到任何一个报文。

网上找到关于 -f 分片的说明:
iptables -A INPUT -f
Dropping IP fragments is probably obsolete advice: the Linux kernel can and will automatically re-assemble and sanity-check all fragments as needed anyway. This happens before packets are handled by iptables connection tracking, so it is likely this rule may never match anything.

找到kernel 对于碎片整理的代码
  1. ip_input.c
  2. ip_rcv()
  3. {
  4.     return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
  5.                net, NULL, skb, dev, NULL,
  6.                ip_rcv_finish);
  7. }

  8. net/ipv4/netfilter/nf_defrag_ipv4.c
  9. static struct nf_hook_ops ipv4_defrag_ops[] = {
  10.     {
  11.         .hook       = ipv4_conntrack_defrag,
  12.         .pf     = NFPROTO_IPV4,
  13.         .hooknum    = NF_INET_PRE_ROUTING,                        #注册的链
  14.         .priority   = NF_IP_PRI_CONNTRACK_DEFRAG,        #优先级
  15.     }
复制代码
发现defrag(碎片整理) 在PRE_ROUTING chain处理的,优先于INPUT chain 处理。
猜想可能是defrag导致 iptables -f无效,于是在ubuntu上做如下验证。

猜想验证:
linux
#kernel配置文件
/usr/src/linux-headers-4.4.0-148-generic/.config
CONFIG_NF_DEFRAG_IPV4=m

lsmod|grep nf_defrag_ipv4 #确认没有加载此模块

win10:
win10# ping 192.168.0.5 -l 3000 -->依旧可以ping通

Linux# iptables -nvL #发现依旧匹配没有匹配到数据包

验证结论:与defrag 功能无关。

计划:
看iptables -f 在netfilter 处理的,代码是否调用到相关的函数。

问题:
请问大家,相关的背景,原理。
针对测试,有相关的解决解决方案。

2020/03/20更新
测试环境变更
win10: 192.168.0.2
Getway: 10.110.14.5
Dest_IP:10.110.14.16

分析:
1.报文分析
win10# ping xxx -l 3000 -n 1
一共发出三个报文,wireshark 抓到信息
No1 tcp ip.len=1500 flag=0x2000
No2 tcp ip.len=1500 flag=0x2000
No3 icmp ip.len=68 flag=0x0x72

2.linux调试
kernel/net/ip_input.c
int ip_rcv()
{
        ...
    if((iph->protocol == 1) && ip_is_fragment(iph)){
        printk("xxx find icmp frag len=%d id=%x s%x d%x\n",ntohl(iph->tot_len),ntohl(iph->id),
                ntohs(iph->saddr),ntohs(iph->daddr));
    }
}
可以打印出这个三个报文。

3.验证1iptables 能否匹配到这三个报文。
在iptables PREROUTING, INPUT添加如下规则
iptables -t mangle -A PREROUTING  -s 192.168.0.2 -d 10.110.14.16 -j LOG --log-prefix "11 mangle"
iptables -t mangle -A PREROUTING  -s 192.168.0.2 -d 10.110.14.16 -f -j LOG --log-prefix "12 mangle"
iptables -t nat -A PREROUTING  -s 192.168.0.2 -d 10.110.14.16 -j LOG --log-prefix "22 nat"
iptables  -I INPUT 10 -s 192.168.0.2 -d 10.110.14.16 -j LOG --log-prefix "33 filt"

dmesg 打印log:
[ 3188.325756] 11 mangleIN=BR_LAN OUT= MAC=d8:6c:a1:2f:37:a7:e8:4e:06:66:93:50:08:00 SRC=192.168.0.2 DST=10.110.14.16 LEN=3028 TOS=0x00 PREC=0x00 TTL=128 ID=22063 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=2847
[ 3188.343275] 22 natIN=BR_LAN OUT= MAC=d8:6c:a1:2f:37:a7:e8:4e:06:66:93:50:08:00 SRC=192.168.0.2 DST=10.110.14.16 LEN=3028 TOS=0x00 PREC=0x00 TTL=128 ID=22063 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=2847

验证结论:
1.对比第1,2条规则:
  1.ID=22063(分片报文标志MF 0x2000)说明分片报文。
  2.-f 无法匹配ip报文MF标志位。
  3.defrag的优先级是高于mangle PREROUTING的,此处LEN=3028应该是完整报文(待验证)。但No1,No2两个分片报文确认没有匹配。
2.对比第1,4规则:
  1.此处验证有误,由于是getway,需要在FORWARD中匹配。

4.验证2直接在ip_rcv中丢弃报文
  1. <div>kernel/net/ip_input.c</div><div>int ip_rcv()</div><div>{</div><div>    if((iph->protocol == 1) && ip_is_fragment(iph)){</div><div>        printk("xxx find icmp frag len=%d id=%x s%x d%x\n",ntohs(iph->tot_len),ntohs(iph->id),</div><div>                ntohs(iph->saddr),ntohs(iph->daddr));</div><div><font color="#008000">+<span style="white-space:pre">                </span>goto drop;</font></div><div>    }</div><div>
  2. </div><div><div>drop:</div><div><span style="white-space:pre">        </span>kfree_skb(skb);</div><div>out:</div><div><span style="white-space:pre">        </span>return NET_RX_DROP;</div></div><div>}</div>
复制代码


win10# ping xxx -l 3000 -n 1
结果:ping failed。--符合预期

验证结论:
1.使用ip_is_fragment() 判断可行。

计划:
1.此处修改不符合规范,暂定使用iptable 新增模块来实现。
2.很好奇-f 到底是如何匹配报文,暂未找到代码实现。

只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
 楼主| 发表于 2020-3-24 13:24 | 显示全部楼层
解决方法:
echo 0 > /proc/sys/net/ipv4/ipfrag_low_thresh
echo 0 > /proc/sys/net/ipv4/ipfrag_high_thresh


Change frag buffer to 0. Frag package will drop.
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

欢迎大家光临恩山无线论坛上一条 /1 下一条

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

GMT+8, 2024-9-22 23:25

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

| 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com

快速回复 返回顶部 返回列表