270 likes | 291 Views
Raw Sockets. Unix Network Programming v1 - Stevens, Fenner, Rudoff Linux Socket Programming - Walton. Slides provided by Bob Cotter, updated by Shuai Zhao. Simple Layered Model. Application. FTP, e-mail, Client/Server. Transport. Connection Control. Internetwork. Routing. Network Access.
E N D
Raw Sockets Unix Network Programming v1 - Stevens, Fenner, Rudoff Linux Socket Programming - Walton Slides provided by Bob Cotter, updated by Shuai Zhao
Simple Layered Model Application FTP, e-mail, Client/Server Transport Connection Control Internetwork Routing Network Access Ethernet, fiber, Token Ring
IP Data Encapsulation User Data Application Layer TCP TCP / UDP Layer IP Layer PH Physical Layer
IP Raw Socket Application User Data Raw socket TCP Bypassing Normal Network stack PH
What can you do with Raw Sockets? • A way to pass information to network protocols other than TCP or UDP (e.g. ICMP and IGMP) • A way to implement new IPv4 protocols • A way to build our own packets (be careful here) • …
Why Would We Use Them? • We can only receive frames destined to a particular address (unicast), broadcast and multicast • All headers ( from layer 1 all way to layer 3, OSI model) are removed by network stack and only the data is shipped to Layer 4 (app layer) • We can not modify the packet headers of packets when they are sent out from our host.
Why Raw is interesting? • Use case: • Promiscuous mode: receive frames for all computers connected to our broadcast domain • sudo ifconfig eth0 promisc • sudo tcpdump –i eth0 • Get all the headers from network packet – raw socket • Sniffing • Packet injection • Network monitoring tools: wireshark • Network hacking tools: nmap
Promiscuous Mode • Let network driver accept all packets, even the packet is not for you. • Used for network monitoring: legit (wireshark) or hacker (nmap) • Set up your interface to be promisc: • Sudo ifconfig eth0 promisc
Sniffing – getting all headers • If interface is in promiscuous mode, means we are getting “full packets” with all the headers • Getting packets for all of your broadcast domain users
Packet injectionsending arbitrary packets-make your own packet • We artificially make a packet and send out to network • Most active network monitoring tools and hacking tools are using it • Total network stack bypass
Normal Socket Operation (TCP) • Create a socket • s = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP) • Bind to a port (optional) • Identify local IP and port desired and create data structure • bind (s, (struct sockaddr *) &sin, sizeof(sin)) • Establish a connection to server • Identify server IP and port • connect (s, (struct sockaddr *) &sin, sizeof(sin)) • Send / Receive data • Place data to be send into buffer • recv (s, buf, strlen(buf), 0);
Raw Sockets Operation (ICMP) • Create a socket • s = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP) • Send / Receive data • Place data to be sent into buffer • sendto (s, buf, strlen(buf), 0, addr, &len);
Create a Raw Socket • s = socket (PF_INET, SOCK_RAW, protocol) • IPPROTO_ICMP, IPPROTO_IP, etc. • Can create our own IP header if we wish • const int on = 1; • setsockopt (s, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on));
Raw Socket Output • Normal output performed using sendto or sendmsg. • Write or send can be used if the socket has been connected • If IP_HDRINCL not set, starting addr of the data (buf) specifies the first byte following the IP header that the kernel will build. • Size only includes the data above the IP header. • If IP_HDRINCL is set, the starting addr of the data identifies the first byte of the IP header. • Size includes the IP header • Set IP id field to 0 (tells kernel to set this field) • Kernel will calculate IP checksum • Kernel can fragment raw packets exceeding outgoing MTU
Raw Socket Input • Received TCP / UDP NEVER passed to a raw socket. • Most ICMP packets are passed to a raw socket • All IGMP packets are passed to a raw socket • All IP datagrams with a protocol field that the kernel does not understand (process) are passed to a raw socket. • If packet has been fragmented, packet is reassembled before being passed to raw socket
The Making of a Sniffer • Create a raw socket – socket() • Set interface you want to sniff on in promiscuous mode • Bind raw socket to this interface – bind() • Receive packets on the socket – recvfrom() • Process received packets • Close the raw socket
Packet injector • Create a raw socket • Bind socket to the interface you want to send packets onto – bind() • Create a packet • Send the packet – sendto() • Close the socket
Limitations? • Raw sockets require root privileges. • No Automatic ICMP • Raw TCP / UDP unlikely
Raw TCP packets • TCP Packet = TCP Header + Data • But in order to send your packet over the network, you need add IP header in the front of TCP packet. • Once you construct your own TCP header, you can choose to either use kernel automatically constructed IP header or manually construct a IP header as well
Tell kernel you have your own IP Header //IP_HDRINCL to tell the kernel that headers are included in the packet int on= 1; const int *val = &on; if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (on)) < 0) { perror("Error setting IP_HDRINCL"); exit(0); }
Sinffer-exmaple.c • struct iphdr *iph; • struct tcphdr *tcph; • Reference link: http://www.binarytides.com/raw-sockets-c-code-linux/
IP Header construct iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr) + strlen(data); iph->id = htonl (54321); //Id of this packet iph->frag_off = 0; iph->ttl = 255; iph->protocol = IPPROTO_TCP; iph->check = 0; //Set to 0 before calculating checksum iph->saddr = inet_addr ( source_ip ); //Spoof the source ip address iph->daddr = sin.sin_addr.s_addr; iph->check = csum ((unsigned short *) datagram, iph->tot_len);
TCP header construct tcph->source = htons (1234); tcph->dest = htons (80); tcph->seq = 0; tcph->ack_seq = 0; tcph->doff = 5; //tcp header size tcph->fin=0; tcph->syn=1; tcph->rst=0; tcph->psh=0; tcph->ack=0; tcph->urg=0; tcph->window = htons (5840); /* maximum allowed window size */ tcph->check = 0; //leave checksum 0 now, filled later by pseudo header tcph->urg_ptr = 0;
Summary • Raw Sockets allow access to Protocols other than the standard TCP and UDP • Performance and capabilities may be OS dependent. • Some OSs block the ability to send packets that originate from raw sockets (although reception may be permitted). • Raw sockets remove the burden of the complex TCP/IP protocol stack, but they also remove the safeguards and support that those protocols provide