晚上好。对我来说,发布到该站点是新的,但是我一直是一个感激不尽的读者,他已经在这个论坛上学到了很多东西。这是我第一次遇到无法解决自己的问题,也无法借助Stackoverflow或互联网提供的任何其他资源上存在的条目的帮助。

希望您能再次为我提供帮助(从现在开始,我也将能够为其他人提供帮助,因为我觉得自己已经成长为可以在这里成为写作成员(member)的地步了)。

问题:

我正在研究内核模块。目的是使用PRE_ROUTING netfilter钩子(Hook)从内核窃取具有特定源IP的传入数据包。仅TCP数据包正在对此进行询问。

现在,钩子(Hook)通过dev_queue_xmit()将数据包重新注入(inject)到正常的内核数据包处理例程中,并将数据包的NF_STOLEN返回到内核。来自其他源地址的数据包不会重新注入(inject),而是通过为它们返回NF_ACCEPT而不是NF_STOLEN来忽略。

内核模块还存储每个被盗数据包的TCP seq编号,以便确定来自所提及IP的传入数据包是新的还是已经通过dev_queue_xmit()修改并重新注入(inject)的,因为这些数据包再次遍历了钩子(Hook)。

什么正在工作:

  • 模块已加载
  • Hook已注册
  • 每个数据包都会调用
  • Hook。
  • Hook可以确定数据包SRC IP是否是我要查找的IP。
  • Hook对于具有其他源地址
  • 的数据包返回NF_ACCEPT
  • 在返回NF_STOLEN的同时,重新注入(inject)具有源地址的数据包
  • 重新注入(inject)的数据包再次遍历钩子(Hook)并被忽略

  • 问题

    加载模块后用浏览器访问IP时,我的IP堆栈似乎崩溃了。我再也无法ping通任何地址。该模块记录它遇到了来自相关IP的数据包,并对其重新排队,之后又找到了一个已知的数据包(因此,一切似乎都很好),但是:与站点/任何其他地址的连接不正确。

    这是 Hook 代码:
    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;
    
    
    }
    

    Hook 如何注册:
    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
    

    最佳答案

    我已经找到了易于实现的目标解决方案。不需要自定义内核模块的解决方案。

    此外,经过更多研究,不能简单地“重新注入(inject)” NF_STOLEN数据包。
    但是,要修改数据包,甚至不需要返回NF_STOLEN。

    可以仅更改有效负载,调整校验和并然后返回NF_ACCEPT,因为您在 Hook 中访问的sk_buffer在进一步处理数据包时将被内核重用。

    关于c - Linux内核模块: How to reinject packets the kernel considers as NF_STOLEN?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25958715/

    10-15 01:18