Original socket counterfeit packet sending

Source: Internet
Author: User
Tags htons

Here we will introduce some original information about Windows Sockets.Socket(Raw socket)Programming. Compared with winsock1, the most obvious difference is that raw Socket socket type is supported. Through the original socket, we can control multiple protocols in Windows more freely, it can also control the underlying transmission mechanism of the network.

1. Create an original socket and set the IP Address Header option.

Socket sock;
Sock = socket (af_inet, sock_raw, ipproto_ip );
Or:
S = wsasoccket (af_inet, sock_raw, ipproto_ip, null, 0, wsa_flag_overlapped );

In this example, the sock_raw flag is set to indicate that we declare an original socket type. After the original socket is created, the IP header will be included in the received data. If we set the ip_hdrincl option, we need to construct the IP header by ourselves. Note: If you set the ip_hdrincl option, you must have the Administrator permission, or you must modify the registry:
HKEY_LOCAL_MACHINE/system/CurrentControlSet/services/AFD/parameter/
Modify the key: disablerawsecurity (type: DWORD), and change the value to 1. If not, add it.

Bool blnflag = true;
Setsockopt (sock, ipproto_ip, ip_hdrincl, (char *) & blnflag, sizeof (blnflag );

When receiving data packets from the original socket, pay attention to the following points:
1. If the protocol type in the received datagram matches the defined original socket, all received data will be copied to the socket.
2. If a local address is bound, the received data is copied to the socket only when the remote address in the IP address header of the received data matches.
3. If an external address is defined, such as connect (), the received data will be copied to the socket only when the source address in the received data IP header matches.

2. Construct the IP header and TCP Header

Here, the structure of the IP header and TCP header is provided:
// Standard TCP flags
# Define URG 0x20
# Define ack 0x10
# Define PSH 0x08
# Define rst 0x04
# Define SYN 0x02
# Define fin 0x01
Typedef struct _ iphdr // defines the IP Header
{
Unsigned char h_lenver; // 4-bit Header Length + 4-bit IP version number
Unsigned char TOS; // an 8-bit service type TOS
Unsigned short total_len; // The total length of 16 bits (in bytes)
Unsigned short ident; // 16-bit ID
Unsigned short frag_and_flags; // 3-Bit Flag
Unsigned char TTL; // 8-bit TTL
Unsigned char proto; // 8-bit protocol (TCP, UDP, or other)
Unsigned short checksum; // 16-bit IP header checksum
Unsigned int sourceip; // 32-bit source IP address
Unsigned int destip; // 32-bit destination IP address
} Ip_header;

Typedef struct psd_hdr // defines the TCP pseudo Header
{
Unsigned long saddr; // Source Address
Unsigned long daddr; // Destination Address
Char mbz;
Char ptcl; // protocol type
Unsigned short tcpl; // TCP Length
} Psd_header;

Typedef struct _ tcphdr // defines the TCP Header
{
Ushort th_sport; // 16-bit Source Port
Ushort th_dport; // 16-bit destination port
Unsigned int th_seq; // 32-bit serial number
Unsigned int th_ack; // 32-bit confirmation number
Unsigned char th_lenres; // 4-bit header length/6-bit reserved words
Unsigned char th_flag; // 6-digit flag
Ushort th_win; // 16-bit window size
Ushort th_sum; // 16-bit checksum
Ushort th_urp; // 16-bit emergency data offset
} Tcp_header;

The TCP pseudo header does not actually exist, but is only used for computing verification. Checksum function:

Ushort checksum (ushort * buffer, int size)
{
Unsigned long cksum = 0;
While (size> 1)
{
Cksum + = * buffer ++;
Size-= sizeof (ushort );
}
If (size)
{
Cksum + = * (uchar *) buffer;
}
Cksum = (cksum> 16) + (cksum & 0 xFFFF );
Cksum + = (cksum> 16 );
Return (ushort )(~ Cksum );
}

When you need to fill in the IP and TCP headers, you also need to calculate their own checks.

3. Send original socket Datagram

Filling these headers is a little tricky, and sending is much easier. You only need to use sendto.

Sendto (sock, (char *) & tcpheader, sizeof (tcpheader), 0, (sockaddr *) & addr_in, sizeof (addr_in ));

The following is an example program that can be used as part of SYN scanning.

# Include <stdio. h>
# Include <winsock2.h>
# Include <ws2tcpip. h>

# Define source_port 7234
# Define max_receivebyte 255

Typedef struct ip_hdr // defines the IP Header
{
Unsigned char h_verlen; // 4-bit header length, 4-bit IP version number
Unsigned char TOS; // an 8-bit service type TOS
Unsigned short total_len; // The total length of 16 bits (in bytes)
Unsigned short ident; // 16-bit ID
Unsigned short frag_and_flags; // 3-Bit Flag
Unsigned char TTL; // 8-bit TTL
Unsigned char proto; // 8-bit protocol (TCP, UDP, or other)
Unsigned short checksum; // 16-bit IP header checksum
Unsigned int sourceip; // 32-bit source IP address
Unsigned int destip; // 32-bit destination IP address
} Ipheader;

Typedef struct tsd_hdr // defines the TCP pseudo Header
{
Unsigned long saddr; // Source Address
Unsigned long daddr; // Destination Address
Char mbz;
Char ptcl; // protocol type
Unsigned short tcpl; // TCP Length
} Psdheader;

Typedef struct tcp_hdr // defines the TCP Header
{
Ushort th_sport; // 16-bit Source Port
Ushort th_dport; // 16-bit destination port
Unsigned int th_seq; // 32-bit serial number
Unsigned int th_ack; // 32-bit confirmation number
Unsigned char th_lenres; // 4-bit header length/6-bit reserved words
Unsigned char th_flag; // 6-digit flag
Ushort th_win; // 16-bit window size
Ushort th_sum; // 16-bit checksum
Ushort th_urp; // 16-bit emergency data offset
} Tcpheader;

// Checksum: The subfunction used to calculate the checksum.
Ushort checksum (ushort * buffer, int size)
{
Unsigned long cksum = 0;
While (size> 1)
{
Cksum + = * buffer ++;
Size-= sizeof (ushort );
}
If (size)
{
Cksum + = * (uchar *) buffer;
}

Cksum = (cksum> 16) + (cksum & 0 xFFFF );
Cksum + = (cksum> 16 );
Return (ushort )(~ Cksum );
}

Void useage ()
{
Printf ("************************************* */N ");
Printf ("tcpping/N ");
Printf ("/T written by refdom/N ");
Printf ("/T Email: refdom@263.net/N ");
Printf ("useage: tcpping.exe target_ip target_port/N ");
Printf ("************************************* * *****/N ");
}

Int main (INT argc, char * argv [])
{
Wsadata;
Socket sock;
Sockaddr_in addr_in;
Ipheader;
Tcpheader;
Psdheader;

Char szsendbuf [60] = {0 };
Bool flag;
Int rect, ntimeover;

Useage ();

If (argc! = 3)
{Return false ;}

If (wsastartup (makeword (2, 2), & wsadata )! = 0)
{
Printf ("wsastartup error! /N ");
Return false;
}

If (sock = wsasocket (af_inet, sock_raw, ipproto_raw, null, 0, wsa_flag_overlapped) = invalid_socket)
{
Printf ("socket setup error! /N ");
Return false;
}
Flag = true;
If (setsockopt (sock, ipproto_ip, ip_hdrincl, (char *) & flag, sizeof (FLAG) = socket_error)
{
Printf ("setsockopt ip_hdrincl error! /N ");
Return false;
}

Ntimeover= 1000;
If (setsockopt (sock, sol_socket, so_sndtimeo, (char *) & ntimeover, sizeof (ntimeover) = socket_error)
{
Printf ("setsockopt so_sndtimeo error! /N ");
Return false;
}
Addr_in.sin_family = af_inet;
Addr_in.sin_port = htons (atoi (argv [2]);
Addr_in.sin_addr.s_un.s_addr = inet_addr (argv [1]);

//
//
// Fill in the IP Header
Ipheader. h_verlen = (4 <4 | sizeof (ipheader)/sizeof (unsigned long ));
// Ipheader. TOS = 0;
Ipheader. total_len = htons (sizeof (ipheader) + sizeof (tcpheader ));
Ipheader. ident = 1;
Ipheader. frag_and_flags = 0;
Ipheader. TTL = 128;
Ipheader. proto = ipproto_tcp;
Ipheader. checksum = 0;
Ipheader. sourceip = inet_addr ("local address ");
Ipheader. destip = inet_addr (argv [1]);

// Fill the TCP Header
Tcpheader. th_dport = htons (atoi (argv [2]);
Tcpheader. th_sport = htons (source_port); // source port number
Tcpheader. th_seq = htonl (0x12345678 );
Tcpheader. th_ack = 0;
Tcpheader. th_lenres = (sizeof (tcpheader)/4 <4 | 0 );
Tcpheader. th_flag = 2; // modify here to implement different flag detection, 2 is SYN, 1 is Fin, 16 is ack detection, etc.
Tcpheader. th_win = htons (512 );
Tcpheader. th_urp = 0;
Tcpheader. th_sum = 0;

Psdheader. saddr = ipheader. sourceip;
Psdheader. daddr = ipheader. destip;
Psdheader. mbz = 0;
Psdheader. ptcl = ipproto_tcp;
Psdheader. tcpl = htons (sizeof (tcpheader ));

// Calculate the checksum
Memcpy (szsendbuf, & psdheader, sizeof (psdheader ));
Memcpy (szsendbuf + sizeof (psdheader), & tcpheader, sizeof (tcpheader ));
Tcpheader. th_sum = checksum (ushort *) szsendbuf, sizeof (psdheader) + sizeof (tcpheader ));

Memcpy (szsendbuf, & ipheader, sizeof (ipheader ));
Memcpy (szsendbuf + sizeof (ipheader), & tcpheader, sizeof (tcpheader ));
Memset (szsendbuf + sizeof (ipheader) + sizeof (tcpheader), 0, 4 );
Ipheader. checksum = checksum (ushort *) szsendbuf, sizeof (ipheader) + sizeof (tcpheader ));

Memcpy (szsendbuf, & ipheader, sizeof (ipheader ));

Rect = sendto (sock, szsendbuf, sizeof (ipheader) + sizeof (tcpheader ),
0, (struct sockaddr *) & addr_in, sizeof (addr_in ));
If (rect = socket_error)
{
Printf ("send error! : % D/N ", wsagetlasterror ());
Return false;
}
Else
Printf ("Send OK! /N ");

Closesocket (sock );
Wsacleanup ();

Return 0;
}

4. receive data
Receiving is more difficult than sending original socket data. In win, we cannot use Recv () to receive data from raw sockets. This is because all IP packets are first submitted to the system core and then transmitted to the user program, when sending a raws socket package (such as SYN), the core does not know, nor does this data be sent or the record established by the connection. Therefore, when the remote host responds, the core of the system is to discard all these packages, so that the application cannot be reached. Therefore, you cannot simply use the receive function to receive these data packets.

To receive data, you must use sniffing to receive all the passed data packets, and then filter them, leaving the data that meets our needs. You can define another original socket to complete the task of receiving data. You need to set sio_rcvall to receive all the data.

Socket sniffersock;
Sniffsock = wsasocket (af_inet, sock_raw, ipproto_ip, null, 0, wsa_flag_overlapped );

DWORD lpvbuffer = 1;
DWORD maid = 0;
Wsaioctl (sniffersock, sio_rcvall, & lpvbuffer, sizeof (lpvbuffer), null, 0, & lpcbbytesreturned, null, null );

Create an original socket for receiving data. We can use the receiving function to receive data packets. Then, we use a filter function to filter data packets.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.