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.
Осталось только изменить выходящие пакеты. Как мне этого добиться?
Не стесняйтесь спрашивать больше информации, и спасибо!