diff options
Diffstat (limited to 'md/notes')
| -rw-r--r-- | md/notes/kernel/netfilter_module.md | 280 | ||||
| -rw-r--r-- | md/notes/kernel/netlink_show_ip.md | 2 | ||||
| -rw-r--r-- | md/notes/kernel/netlink_socket.md | 2 | ||||
| -rw-r--r-- | md/notes/kernel/topics.md | 4 | 
4 files changed, 285 insertions, 3 deletions
diff --git a/md/notes/kernel/netfilter_module.md b/md/notes/kernel/netfilter_module.md new file mode 100644 index 0000000..fbe56b6 --- /dev/null +++ b/md/notes/kernel/netfilter_module.md @@ -0,0 +1,280 @@ +title: Netlink socket +keywords: kernel,linux,netlink,socket + +# Kernel netfilter module + + +## Files + +You need to create to files __Makefile__ and __netlink_socket.c__. + +__Makefile__ +```Makefile +obj-m += netlink_socket.o + +KDIR ?= /lib/modules/$(shell uname -r)/build + +all: +	make -C $(KDIR) M=$(PWD) modules + +clean: +	make -C $(KDIR) M=$(PWD) clean + +``` + + +__netlink_socket.c__ +```c +//http://www.tldp.org/LDP/lkmpg/2.4/html/c147.htm +#include <linux/module.h>  /* Needed by all modules */ +#include <linux/kernel.h> + +int netlink_socket_init( void ) +{ +	printk(KERN_DEBUG "Netlink World!\n"); +	return 0; +} + +void netlink_socket_exit( void ) +{ +	printk(KERN_DEBUG "Exit Netlink World!\n"); +} + +module_init( netlink_socket_init ); +module_exit( netlink_socket_exit ); + +MODULE_LICENSE("GPL"); +``` + + +Add to makefile step to compile userspace program + +```makefile +all: +	make -C $(KDIR) M=$(PWD) modules +	gcc netlink_connect.c -o netlink_connect +``` + + + +## Prepare the hook function + +```c +... +static unsigned int netfilter_icmp_blockicmppkt_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) +{ +	struct iphdr *iph;   // IP header +	struct udphdr *udph; // UDP header + +	if(!skb) +		return NF_ACCEPT; + +	iph = ip_hdr(skb); // retrieve the IP headers from the packet +	if(iph->protocol == IPPROTO_UDP) {  +		udph = udp_hdr(skb); +		if(ntohs(udph->dest) == 53) { +			return NF_ACCEPT; // accept UDP packet +		} +	} +	else if (iph->protocol == IPPROTO_TCP) { +		return NF_ACCEPT; // accept TCP packet +	} +	else if (iph->protocol == IPPROTO_ICMP) { +		printk(KERN_INFO "Drop ICMP packet \n"); +		return NF_DROP;   // drop TCP packet +	} + +	return NF_ACCEPT; +} +... +``` + +## Register netfilter + +```c +... +int netfilter_icmp_init( void ) +{ +	... +	nf_blockicmppkt_ops = (struct nf_hook_ops*)kcalloc(1,  sizeof(struct nf_hook_ops), GFP_KERNEL); +	if (nf_blockicmppkt_ops != NULL) { +		nf_blockicmppkt_ops->hook = (nf_hookfn*)netfilter_icmp_blockicmppkt_hook; +		nf_blockicmppkt_ops->hooknum = NF_INET_PRE_ROUTING; +		nf_blockicmppkt_ops->pf = NFPROTO_IPV4; +		nf_blockicmppkt_ops->priority = NF_IP_PRI_FIRST; // set the priority +		 +		nf_register_net_hook(&init_net, nf_blockicmppkt_ops); +	} +	... +	return 0; +} +... +``` + +## Data structures and fucntions + +The lis of functions used in this example + +__nf_register_net_hook__ +``` +int nf_register_net_hook(struct net *net, const struct nf_hook_ops *ops); +``` + +__udp_hdr__ +```c +static inline struct udphdr *udp_hdr(const struct sk_buff *skb) +{ +	return (struct udphdr *)skb_transport_header(skb); +} +``` + +__ip_hdr__ +```c +static inline struct iphdr *ip_hdr(const struct sk_buff *skb) +{ +	return (struct iphdr *)skb_network_header(skb); +} +``` + +list of hooknum options in hook_ops +```c +enum nf_inet_hooks { +	NF_INET_PRE_ROUTING, +	NF_INET_LOCAL_IN, +	NF_INET_FORWARD, +	NF_INET_LOCAL_OUT, +	NF_INET_POST_ROUTING, +	NF_INET_NUMHOOKS, +	NF_INET_INGRESS = NF_INET_NUMHOOKS, +}; +``` + +list of pf options in hook_ops +```c +enum { +	NFPROTO_UNSPEC =  0, +	NFPROTO_INET   =  1, +	NFPROTO_IPV4   =  2, +	NFPROTO_ARP    =  3, +	NFPROTO_NETDEV =  5, +	NFPROTO_BRIDGE =  7, +	NFPROTO_IPV6   = 10, +#ifndef __KERNEL__ /* no longer supported by kernel */ +	NFPROTO_DECNET = 12, +#endif +	NFPROTO_NUMPROTO, +}; +``` + + +list of priority option in hook_ops +```c +enum nf_ip_hook_priorities { +	NF_IP_PRI_FIRST = INT_MIN, +	NF_IP_PRI_RAW_BEFORE_DEFRAG = -450, +	NF_IP_PRI_CONNTRACK_DEFRAG = -400, +	NF_IP_PRI_RAW = -300, +	NF_IP_PRI_SELINUX_FIRST = -225, +	NF_IP_PRI_CONNTRACK = -200, +	NF_IP_PRI_MANGLE = -150, +	NF_IP_PRI_NAT_DST = -100, +	NF_IP_PRI_FILTER = 0, +	NF_IP_PRI_SECURITY = 50, +	NF_IP_PRI_NAT_SRC = 100, +	NF_IP_PRI_SELINUX_LAST = 225, +	NF_IP_PRI_CONNTRACK_HELPER = 300, +	NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX, +	NF_IP_PRI_LAST = INT_MAX, +}; +``` + +List of protocol options when check for ip header protocol + + +```c +enum { +  IPPROTO_IP = 0,		/* Dummy protocol for TCP		*/ +  IPPROTO_ICMP = 1,		/* Internet Control Message Protocol	*/ +  IPPROTO_IGMP = 2,		/* Internet Group Management Protocol	*/ +  IPPROTO_IPIP = 4,		/* IPIP tunnels (older KA9Q tunnels use 94) */ +  IPPROTO_TCP = 6,		/* Transmission Control Protocol	*/ +  IPPROTO_EGP = 8,		/* Exterior Gateway Protocol		*/ +  IPPROTO_PUP = 12,		/* PUP protocol				*/ +  IPPROTO_UDP = 17,		/* User Datagram Protocol		*/ +  IPPROTO_IDP = 22,		/* XNS IDP protocol			*/ +  IPPROTO_TP = 29,		/* SO Transport Protocol Class 4	*/ +  IPPROTO_DCCP = 33,		/* Datagram Congestion Control Protocol */ +  IPPROTO_IPV6 = 41,		/* IPv6-in-IPv4 tunnelling		*/ +  IPPROTO_RSVP = 46,		/* RSVP Protocol			*/ +  IPPROTO_GRE = 47,		/* Cisco GRE tunnels (rfc 1701,1702)	*/ +  IPPROTO_ESP = 50,		/* Encapsulation Security Payload protocol */ +  IPPROTO_AH = 51,		/* Authentication Header protocol	*/ +  IPPROTO_MTP = 92,		/* Multicast Transport Protocol		*/ +  IPPROTO_BEETPH = 94,		/* IP option pseudo header for BEET	*/ +  IPPROTO_ENCAP = 98,		/* Encapsulation Header			*/ +  IPPROTO_PIM = 103,		/* Protocol Independent Multicast	*/ +  IPPROTO_COMP = 108,		/* Compression Header Protocol		*/ +  IPPROTO_L2TP = 115,		/* Layer 2 Tunnelling Protocol		*/ +  IPPROTO_SCTP = 132,		/* Stream Control Transport Protocol	*/ +  IPPROTO_UDPLITE = 136,	/* UDP-Lite (RFC 3828)			*/ +  IPPROTO_MPLS = 137,		/* MPLS in IP (RFC 4023)		*/ +  IPPROTO_ETHERNET = 143,	/* Ethernet-within-IPv6 Encapsulation	*/ +  IPPROTO_RAW = 255,		/* Raw IP packets			*/ +  IPPROTO_MPTCP = 262,		/* Multipath TCP connection		*/ +  IPPROTO_MAX +}; +``` + +## Compile + +Compile the module and userspace program + +```sh +make +``` + +## Load module + +```sh +sudo insmod netlink_socket.ko +``` + +check that module is running + +```sh +lsmod | grep netlink +``` + +## Unload module + +```sh +rmmod netlink_socket +``` + + +## Test + +Run userspace programm and receive back message with capitalised letters + +```bash + +``` + +## Note  + +This example mostly followed from levelup blog, now time to figure out what I can add on top of it. + +## Links + +1. https://inai.de/documents/Netfilter_Modules.pdf   +2. https://infosecwriteups.com/linux-kernel-communication-part-1-netfilter-hooks-15c07a5a5c4e   +3. https://www.netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-4.html   +4. https://github.com/zentyal/ndpi-netfilter/blob/master/src/main.c   +5. https://levelup.gitconnected.com/write-a-linux-firewall-from-scratch-based-on-netfilter-462013202686   +6. https://blogs.oracle.com/linux/post/introduction-to-netfilter   +7. https://elixir.bootlin.com/linux/v6.6.20/source/include/uapi/linux/netfilter.h#L12   +8. https://elixir.bootlin.com/linux/v6.6.20/source/net/ipv4/ip_input.c#L560 +9. https://elixir.bootlin.com/linux/v6.6.20/source/include/linux/ip.h#L19 +10. https://elixir.bootlin.com/linux/v6.6.20/source/include/linux/udp.h#L21 +11. https://elixir.bootlin.com/linux/v6.6.20/source/include/linux/skbuff.h#L842 + diff --git a/md/notes/kernel/netlink_show_ip.md b/md/notes/kernel/netlink_show_ip.md index 87f0b83..204e7a1 100644 --- a/md/notes/kernel/netlink_show_ip.md +++ b/md/notes/kernel/netlink_show_ip.md @@ -247,7 +247,7 @@ make  Output looks like -``` +```sh  received message type 20  interface lo  prefix length 8 diff --git a/md/notes/kernel/netlink_socket.md b/md/notes/kernel/netlink_socket.md index e022e52..fd3477e 100644 --- a/md/notes/kernel/netlink_socket.md +++ b/md/notes/kernel/netlink_socket.md @@ -1,7 +1,7 @@  title: Netlink socket  keywords: kernel,linux,netlink,socket -# Kernel compile "Hello world" +# Kernel netlink socket  As base start from minimal kernel module diff --git a/md/notes/kernel/topics.md b/md/notes/kernel/topics.md index 8682aeb..e2c107b 100644 --- a/md/notes/kernel/topics.md +++ b/md/notes/kernel/topics.md @@ -35,14 +35,15 @@ accordingly.  [Kernel /dev/hwrng](/writeup/kernel_dev_hwrng.md)    [Netlink socket](/notes/kernel/netlink_socket.md)   +[Netfilter module](/notes/kernel/netfilter_module.md)    <!-- Create syscall  --> -  <!-- Dummy I2C driver  -->  <!-- Dummy SPI driver  -->  <!-- Create ADC driver  -->  <!-- Mutex'es -->  <!-- Threads -->  <!-- Locking --> +<!-- RB-trees -->    ### Deep into kernel @@ -57,6 +58,7 @@ accordingly.  ### Kernel userspace  [Netlink show ip](/notes/kernel/netlink_show_ip.md)    +  <!-- Netfilter set ip -->  <!-- khttpd -->  | 
