深入学习nf_tables之chain


基础知识

table分不同的族(family):每个 table 都会从属于某个族,族决定了该 table 会处理哪些种类的数据包。族包括 ip、 ip6、 inet、 arp、 bridge 和 netdev。

  1. 属于 ip 族的 table 只负责处理 IPv4 数据包;
  2. 属于 ip6 族的 table 只负责处理 IPv6 数据包;
  3. 属于 inet 族的 table 则既可处理 IPv4 又可处理 IPv6 数据包。

创建base chain

创建chain的基本方式在笔者之前的博客”nf_tables入门2“中已经讲过了:

但是注意这里创建的仅仅是一个辅助用的普通chain,如果我们传入了HOOK参数,就是要创建一个base chain,这里会有好多问题,让我们逐一进行分析。

首先我们需要添加参数:

这样我们走到nf_tables_addchain函数是就会走入第一个if中,在这里创建的是一个base_chain:https://elixir.bootlin.com/linux/v5.15/source/net/netfilter/nf_tables_api.c#L2084

可以看到首先会进入到nft_chain_parsee_hook函数中对hook进行分析:https://elixir.bootlin.com/linux/v5.15/source/net/netfilter/nf_tables_api.c#L1924 ,首先拆解nested_attr,然后大端序获取hook_num和hook_priority:

之后就是根据当前的family和default的type来获取type结构体:

https://elixir.bootlin.com/linux/v5.15/source/net/netfilter/nf_tables_api.c#L614

但是经过调试,笔者发现这个type数组是空的:😱

之后

初始化chain_type

首先就近在nf_tables_api.c文件中找关于chain_type数组初始化的代码:

https://elixir.bootlin.com/linux/v5.15/source/net/netfilter/nf_tables_api.c#L1329

然后回溯:

nf_tables_module_init	
nft_chain_filter_init
nft_chain_filter_netdev_init
nft_register_chain_type

结果在gdb中发现找不到nft_chain_filter_netdev_init这个函数,然后发现需要如下编译配置:

类比地,如果有如下配置

参考

https://www.iceswordlab.com/2023/02/06/cve-2022-1015/


文章作者: q1ming
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 q1ming !
  目录