【发布时间】:2014-11-15 12:17:34
【问题描述】:
晚上好。在这个网站上发帖对我来说是新的,但很长一段时间以来,我一直是一个感恩的读者,他从这个论坛学到了很多东西。这是我第一次遇到我自己都无法解决的问题,也无法借助 Stackoverflow 或互联网提供的任何其他资源上已有的条目来解决。
我希望你能再次帮助我(从现在开始,我也将能够帮助其他人,因为我觉得我已经成长到可以开始在这里成为写作成员的地步了)。
问题:
我正在开发一个内核模块。它的目的是使用 PRE_ROUTING netfilter 钩子从内核中窃取具有特定源 IP 的传入数据包。只有 TCP 数据包对它感兴趣。
现在,钩子通过 dev_queue_xmit() 将数据包重新注入到正常的内核数据包处理例程中,并将数据包的 NF_STOLEN 返回给内核。来自其他源地址的数据包不会被重新注入,而是通过为它们返回 NF_ACCEPT 而不是 NF_STOLEN 而被忽略。
内核模块还存储每个被盗数据包的 TCP 序列号,以确定来自上述 IP 的传入数据包是新的,还是已经通过 dev_queue_xmit() 修改和重新注入,因为这些数据包再次遍历钩子.
什么还在起作用:
- 模块被加载
- 挂钩已注册
- 为每个数据包调用 Hook。
- Hook 可以确定数据包 SRC IP 是否是我要查找的 IP。
- Hook 为具有其他源地址的数据包返回 NF_ACCEPT
- 带有源地址的数据包被重新注入,同时为它们返回 NF_STOLEN
- 重新注入的数据包再次穿过钩子并被忽略
问题
当我在加载模块后使用浏览器访问 IP 时,我的 IP 堆栈似乎崩溃了。我再也无法ping通任何地址。该模块记录了它遇到来自相关 IP 的数据包,并将它们重新排队,之后发现了一个已知的数据包(所以一切看起来都很好),但仍然:没有正确连接到站点/任何其他地址。
这里是钩子代码:
static unsigned int hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *))
{
struct iphdr *iph;
struct tcphdr *tcph;
unsigned int i;
if(!skb)
return NF_ACCEPT;
iph = (struct iphdr *)skb_network_header(skb);
if(!iph || !(iph->saddr) || iph->saddr != *(unsigned int*)suspicious_ip)
return NF_ACCEPT;
tcph = (struct tcphdr *)skb_transport_header(skb);
for(i=0; i < number_of_known_packets; i++)
{
if(tcph->seq == *(already_known_packets+i))
{
debug("Already known packet");
return NF_ACCEPT;
}
}
debug("New packet");
printk("seq: %u\n", tcph->seq);
if((number_of_known_packets + 1) * 4 >= memory_allocated_for_known_packets)
imba_realloc(500*4);
*(already_known_packets+number_of_known_packets++) = tcph->seq;
debug("Requeuing packet");
// once the requeuing is working proper, I want to manipulate the payload as well
printk("Result: %i", dev_queue_xmit(skb));
return NF_STOLEN;
}
钩子是如何注册的:
static struct nf_hook_ops nfho;
int init_module(void)
{
debug("module loaded");
already_known_packets = kmalloc(memory_allocated_for_known_packets, GFP_KERNEL);
debug("initial memory allocated");
nfho.hook = hook;
nfho.hooknum = NF_INET_PRE_ROUTING;
nfho.pf = PF_INET;
nfho.priority = 1;
nf_register_hook(&nfho);
debug("hook registered");
return 0;
}
系统日志:
Sep 21 13:11:43 linux kernel: [ 3298.937902] [PACKET PROXY] module loaded
Sep 21 13:11:43 linux kernel: [ 3298.937907] [PACKET PROXY] initial memory allocated
Sep 21 13:11:43 linux kernel: [ 3298.937931] [PACKET PROXY] hook registered
Sep 21 13:11:49 linux kernel: [ 3305.415404] [PACKET PROXY] New packet
Sep 21 13:11:49 linux kernel: [ 3305.415410] seq: 1538346824
Sep 21 13:11:49 linux kernel: [ 3305.415412] [PACKET PROXY] Requeuing packet
Sep 21 13:11:49 linux kernel: [ 3305.415430] Result: 0
Sep 21 13:11:49 linux kernel: [ 3305.415440] [PACKET PROXY] New packet
Sep 21 13:11:49 linux kernel: [ 3305.415441] seq: 618234741
Sep 21 13:11:49 linux kernel: [ 3305.415442] [PACKET PROXY] Requeuing packet
Sep 21 13:11:49 linux kernel: [ 3305.415447] Result: 0
Sep 21 13:11:49 linux kernel: [ 3305.421440] [PACKET PROXY] New packet
Sep 21 13:11:49 linux kernel: [ 3305.421452] seq: 2129598066
Sep 21 13:11:49 linux kernel: [ 3305.421458] [PACKET PROXY] Requeuing packet
Sep 21 13:11:49 linux kernel: [ 3305.421477] Result: 0
Sep 21 13:11:49 linux kernel: [ 3305.427449] [PACKET PROXY] New packet
Sep 21 13:11:49 linux kernel: [ 3305.427456] seq: 2327127721
Sep 21 13:11:49 linux kernel: [ 3305.427458] [PACKET PROXY] Requeuing packet
Sep 21 13:11:49 linux kernel: [ 3305.427466] Result: 0
Sep 21 13:11:49 linux kernel: [ 3305.427470] [PACKET PROXY] New packet
Sep 21 13:11:49 linux kernel: [ 3305.427471] seq: 1333567182
Sep 21 13:11:49 linux kernel: [ 3305.427473] [PACKET PROXY] Requeuing packet
Sep 21 13:11:49 linux kernel: [ 3305.427476] Result: 0
Sep 21 13:11:49 linux kernel: [ 3305.427494] [PACKET PROXY] New packet
Sep 21 13:11:49 linux kernel: [ 3305.427502] seq: 2650236943
Sep 21 13:11:49 linux kernel: [ 3305.427506] [PACKET PROXY] Requeuing packet
Sep 21 13:11:49 linux kernel: [ 3305.427514] Result: 0
Sep 21 13:11:49 linux kernel: [ 3305.427522] [PACKET PROXY] New packet
Sep 21 13:11:49 linux kernel: [ 3305.427533] seq: 444387468
Sep 21 13:11:49 linux kernel: [ 3305.427534] [PACKET PROXY] Requeuing packet
Sep 21 13:11:49 linux kernel: [ 3305.427539] Result: 0
Sep 21 13:11:49 linux kernel: [ 3305.427544] [PACKET PROXY] New packet
Sep 21 13:11:49 linux kernel: [ 3305.427545] seq: 1405773113
Sep 21 13:11:49 linux kernel: [ 3305.427547] [PACKET PROXY] Requeuing packet
Sep 21 13:11:49 linux kernel: [ 3305.427550] Result: 0
Sep 21 13:11:50 linux kernel: [ 3306.413448] [PACKET PROXY] Already known PACKET
Sep 21 13:11:50 linux kernel: [ 3306.413641] [PACKET PROXY] Already known PACKET
Sep 21 13:11:50 linux kernel: [ 3306.414153] [PACKET PROXY] Already known PACKET
Sep 21 13:11:50 linux kernel: [ 3306.414989] [PACKET PROXY] Already known PACKET
Sep 21 13:11:50 linux kernel: [ 3306.415102] [PACKET PROXY] Already known PACKET
Sep 21 13:11:50 linux kernel: [ 3306.417880] [PACKET PROXY] Already known PACKET
Sep 21 13:11:50 linux kernel: [ 3306.418065] [PACKET PROXY] Already known PACKET
Sep 21 13:11:50 linux kernel: [ 3306.418134] [PACKET PROXY] Already known PACKET
Sep 21 13:11:50 linux kernel: [ 3306.433788] [PACKET PROXY] New packet
Sep 21 13:11:50 linux kernel: [ 3306.433812] seq: 2146375282
Sep 21 13:11:50 linux kernel: [ 3306.433816] [PACKET PROXY] Requeuing packet
Sep 21 13:11:50 linux kernel: [ 3306.433850] Result: 0
Sep 21 13:11:51 linux kernel: [ 3306.441424] [PACKET PROXY] Already known PACKET
Sep 21 13:11:51 linux kernel: [ 3306.441587] [PACKET PROXY] New packet
Sep 21 13:11:51 linux kernel: [ 3306.441596] seq: 3958642290
Sep 21 13:11:51 linux kernel: [ 3306.441610] [PACKET PROXY] Requeuing packet
Sep 21 13:11:51 linux kernel: [ 3306.441634] Result: 0
Sep 21 13:11:51 linux kernel: [ 3306.441646] [PACKET PROXY] New packet
Sep 21 13:11:51 linux kernel: [ 3306.441648] seq: 1476007538
Sep 21 13:11:51 linux kernel: [ 3306.441652] [PACKET PROXY] Requeuing packet
Sep 21 13:11:51 linux kernel: [ 3306.441660] Result: 0
Sep 21 13:11:51 linux kernel: [ 3306.443131] [PACKET PROXY] New packet
Sep 21 13:11:51 linux kernel: [ 3306.443139] seq: 3288274546
Sep 21 13:11:51 linux kernel: [ 3306.443148] [PACKET PROXY] Requeuing packet
Sep 21 13:11:51 linux kernel: [ 3306.443194] Result: 0
Sep 21 13:11:51 linux kernel: [ 3306.443226] [PACKET PROXY] New packet
Sep 21 13:11:51 linux kernel: [ 3306.443231] seq: 788862834
Sep 21 13:11:51 linux kernel: [ 3306.443241] [PACKET PROXY] Requeuing packet
Sep 21 13:11:51 linux kernel: [ 3306.443258] Result: 0
Sep 21 13:11:51 linux kernel: [ 3306.443276] [PACKET PROXY] New packet
Sep 21 13:11:51 linux kernel: [ 3306.443278] seq: 2601129842
Sep 21 13:11:51 linux kernel: [ 3306.443281] [PACKET PROXY] Requeuing packet
Sep 21 13:11:51 linux kernel: [ 3306.443286] Result: 0
Sep 21 13:11:51 linux kernel: [ 3306.443294] [PACKET PROXY] New packet
Sep 21 13:11:51 linux kernel: [ 3306.443295] seq: 2131695474
Sep 21 13:11:51 linux kernel: [ 3306.443299] [PACKET PROXY] Requeuing packet
Sep 21 13:11:51 linux kernel: [ 3306.443305] Result: 0
Sep 21 13:11:51 linux kernel: [ 3306.443313] [PACKET PROXY] New packet
Sep 21 13:11:51 linux kernel: [ 3306.443314] seq: 3943962482
Sep 21 13:11:51 linux kernel: [ 3306.443317] [PACKET PROXY] Requeuing packet
Sep 21 13:11:51 linux kernel: [ 3306.443320] Result: 0
Sep 21 13:11:57 linux kernel: [ 3312.685399] [PACKET PROXY] New packet
Sep 21 13:11:57 linux kernel: [ 3312.685425] seq: 2667014159
Sep 21 13:11:57 linux kernel: [ 3312.685430] [PACKET PROXY] Requeuing packet
Sep 21 13:11:57 linux kernel: [ 3312.685463] Result: 0
【问题讨论】:
标签: c linux linux-kernel netfilter