NF_INET_POST_ROUTING MAC-адреса?

Я пытаюсь получить полный контроль над всеми пакетами, поступающими из моей системы и прибывающими в мою систему, и могу делать с ними все, что захочу.

Я сделал модуль ядра и использую ловушки netfilter, чтобы попытаться это сделать.

Вот оно:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>

#include "/home/bar/Libraries/PacketProtocolDefinitions.h"

static struct nf_hook_ops nfho, nfho_s;

unsigned int hook_func_recv(void *priv, struct sk_buff *sock_buff, const struct nf_hook_state *state){

    struct IpHeader *iph;
    struct EthernetFrame *ethf;

    if (!sock_buff) {return NF_ACCEPT;}

    if (!(iph = (struct IpHeader *)skb_network_header(sock_buff))) {printk(KERN_INFO "iph = 0");return NF_ACCEPT;}
    if (!(ethf = (struct EthernetFrame*)skb_mac_header(sock_buff))) {printk(KERN_INFO "ethf = 0"); return NF_ACCEPT;}

    if(iph->Protocol==IPPROTO_TCP) {return NF_ACCEPT;}

    if(iph->Protocol==IPPROTO_ICMP) {
        printk(KERN_INFO "=== BEGIN NF_INET_PRE_ROUTING ICMP ===\n");

        //ethf->destination[5] = 0xc3; //used for testing

        printk(KERN_INFO "Ethernet Frame: original source: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", 
            ethf->source[0], ethf->source[1], ethf->source[2], ethf->source[3], ethf->source[4], ethf->source[5]
        );

        printk(KERN_INFO "IP header: original source: %d.%d.%d.%d\n", 
            (iph->source[0]), (iph->source[1]), (iph->source[2]), (iph->source[3])
        );

        printk(
            KERN_INFO "Ethernet Frame: original destination: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", 
            ethf->destination[0], ethf->destination[1], ethf->destination[2], 
            ethf->destination[3], ethf->destination[4], ethf->destination[5]
        );

        printk(
            KERN_INFO "IP header: original destin: %d.%d.%d.%d\n", 
            (iph->destination[0]), (iph->destination[1]), (iph->destination[2]), (iph->destination[3]) 
        );
        printk(KERN_INFO "=== END NF_INET_PRE_ROUTING ICMP ===\n");

    }
    return NF_ACCEPT;
}

unsigned int hook_func_send(void *priv, struct sk_buff *sock_buff, const struct nf_hook_state *state){

    struct IpHeader *iph;
    struct EthernetFrame *ethf;

    if (!sock_buff) {return NF_ACCEPT;}

    if (!(iph = (struct IpHeader *)skb_network_header(sock_buff))) {printk(KERN_INFO "iph = 0");return NF_ACCEPT;}
    if (!(ethf = (struct EthernetFrame*)skb_mac_header(sock_buff))) {printk(KERN_INFO "ethf = 0"); return NF_ACCEPT;}

    if(iph->Protocol==IPPROTO_TCP) {return NF_ACCEPT;}

    if(iph->Protocol==IPPROTO_ICMP) {
        printk(KERN_INFO "=== BEGIN NF_INET_POST_ROUTING ICMP ===\n");

        //ethf->source[5] = 0xc3; //used for testing

        printk(
            KERN_INFO "Ethernet Frame: original source: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", 
            ethf->source[0], ethf->source[1], ethf->source[2], 
            ethf->source[3], ethf->source[4], ethf->source[5]
        );

        printk(
            KERN_INFO "IP header: original source: %d.%d.%d.%d\n", 
            (iph->source[0]), (iph->source[1]), (iph->source[2]), (iph->source[3])
        );

        printk(
            KERN_INFO "Ethernet Frame: original destination: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", 
            ethf->destination[0], ethf->destination[1], ethf->destination[2], 
            ethf->destination[3], ethf->destination[4], ethf->destination[5]
        );

        printk(
            KERN_INFO "IP header: original destin: %d.%d.%d.%d\n", 
            (iph->destination[0]), (iph->destination[1]), (iph->destination[2]), (iph->destination[3]) 
        );
        printk(KERN_INFO "=== END NF_INET_POST_ROUTING ICMP ===\n");

    }
    return NF_ACCEPT;

}

static int __init initialize(void) {
    nfho.hook     = hook_func_recv;
    nfho.hooknum  = NF_INET_PRE_ROUTING;
    nfho.pf       = PF_INET;
    nfho.priority = NF_IP_PRI_FIRST;
    nf_register_hook(&nfho);

    nfho_s.hook     = hook_func_send;
    nfho_s.hooknum  = NF_INET_POST_ROUTING;
    nfho_s.pf       = PF_INET;
    nfho_s.priority = NF_IP_PRI_FIRST;
    nf_register_hook(&nfho_s);

    printk(KERN_INFO "Sniff Module Loaded.");
    return 0;
}

static void __exit cleanup(void) {
    printk(KERN_INFO "Sniff Module Unloaded.");
    nf_unregister_hook(&nfho_s);
    nf_unregister_hook(&nfho);
}

module_init(initialize);
module_exit(cleanup);

Сейчас я делаю это только для ICMP, так что я могу просто пропинговать тестирование и не получать спама kern.log с информацией о пакете.


Мне кажется, что у NF_INET_POST_ROUTING MAC-адреса установлены в 0?

результат
(Для простоты я удалил остальные, но они правильно заполнены)

Из того, что я прочитал:

NF_IP_POST_ROUTING: эта ловушка запускается любым исходящим или перенаправленным трафиком после того, как маршрутизация произошла и незадолго до того, как она будет выведена на провод.

Что здесь происходит?
используя сокет в пространстве пользователя с AF_PACKET, SOCK_RAW а также htons(ETH_P_ALL) показывает MAC-адрес, так почему бы не перехватить?

Я только пытаюсь получить контроль над тем, что выходит из моей системы на данный момент, так как NF_INET_PRE_ROUTING, кажется, работает довольно хорошо, я могу изменить macaddr, и, как я тестировал с необработанными сокетами, он действительно меняется:

пример необработанных сокетов
(с фиолетовым текстом, являющимся пакетами от / до меня, и зеленым, в противном случае ответ на пинг от того, кого я пингую, отображается зеленым, потому что я сменил макинтош на крючке)

Я на Ubuntu 16.04.

Осталось только изменить выходящие пакеты. Как мне этого добиться?

Не стесняйтесь спрашивать больше информации, и спасибо!

0 ответов

Другие вопросы по тегам