0x00
I've also been learning about Linux development recently, especially the network programming piece. Today, share the first few days of the simple SYN-port scan code, rather than simple, rather humble, but indeed a lot of harvest.
I'm not here. Full port scan, SYN scan is different from full-attached scan, because this scan does not need to establish a connection, so the speed of scanning is much faster than the full-connected scan speed, with a picture description:
TCP to establish a connection when the need to do three handshake, in general is the SYN--------->syn+ack------------>ack, as long as three handshake, then the connection will be allocated to the connection of the corresponding resources, such as buffer. And the SYN scan is obviously not to establish a full connection, when the second message is Syn+ack, on behalf of the server can be connected, or the port is open, this time to send a RST will disconnect the connection, because we have learned that the port is open. It is natural to scan in such a way that it is fast.
0x01
The idea is to construct the corresponding flag of the TCP message to send, if you receive syn+ack that the port is open, this time to send a RST disconnect to avoid consuming the resources of the swept host. If it is rst+ack, the port is not developed and continues to scan other ports.
In the implementation I also consulted a lot of information, the most important foundation of implementation is based on the original socket for the package, that is, to construct the corresponding IP or TCP messages, and then send, because the use of the system's bind connect that the set is unable to operate the TCP header field. The basics of programming for raw sockets I'm not going to introduce, because there are a lot of good blogs on the web. This is where the code is shared directly.
#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include < unistd.h> #include <netdb.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/ in.h> #include <netinet/ip.h> #include <errno.h> #include <arpa/inet.h> #include <linux/tcp.h > #include <pthread.h> #include <fcntl.h>/* * Author:exploit * This is a SYN scan of the demo * Problem: The speed of the contract to control or lose the packet is very Critical * But within the range of 60 ports * * *///define TCP pseudo-header typedef struct PSD_HDR {unsigned long saddr;//source address unsigned long daddr;//Purpose Address Char Mbz; Char PTCL; Protocol type unsigned short tcpl;
TCP length}psd_header; Defines the TCP header typedef struct _TCPHDR {unsigned short th_sport;//16-bit source port unsigned short th_dport;//16-bit destination port unsigned int th _seq; 32-bit serial number unsigned int th_ack; 32 Digit Confirmation Number unsigned char th_lenres; 4-bit header length/4-bit reserved word unsigned char th_flag; 6-bit flag bit unsigned short th_win; 16-bit window size unsigned short th_sum; 16-bit checksum unsigned short th_urp;
16-bit emergency data offset} Tcp_header;
Defines the IP header typedef struct _IPHDR {unsigned char h_lenver;//length plus version number unsigned char tos;
unsigned short total_len;
unsigned short ident;
unsigned short frag_and_flags;
unsigned char ttl;
unsigned char proto;
unsigned short checksum;
unsigned int sourceIP;
unsigned int destip;
} Ip_header;
/** * Calculate checksum */unsigned short checksum (unsigned short *addr,int len) {int nleft=len;
int sum=0;
unsigned short * W=ADDR;
unsigned 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 & 0xFFFF);
sum+= (SUM>>16);
Answer=~sum;
return (answer);
}/* Attack target */struct sockaddr_in target;
struct sockaddr_in myaddr;
int sockfd;
pthread_t PTH;
void Tcp_send (int port,unsigned char flag);
void* recvpackage (VOID*ARG); int main (int args,char* argv[]) {//Parameter check if (argS < 4) {printf ("Usage:shit targetip startport endport\n");
Exit (-1); } Char ip[32];
Target IP strcpy (ip,argv[1]);
int startport = atoi (argv[2]);
int endport = atoi (argv[3]);
if ((Endport-startport) >) {printf ("The port range must be within considering your bandwith....\n");
Exit (-1);
} target.sin_family = Af_inet;
TARGET.SIN_ADDR.S_ADDR = inet_addr (IP);
myaddr.sin_family = af_inet;
Myaddr.sin_port = htons (60000);
MYADDR.SIN_ADDR.S_ADDR = inet_addr ("10.10.10.132");
Socket SOCKFD for TCP messages = socket (AF_INET,SOCK_RAW,IPPROTO_TCP);
if (SOCKFD = =-1) {printf ("Socket error:%s\n", strerror (errno));
Exit (-1);
} int i, count=1;
for (i=startport;i<endport;i++) {tcp_send (i,2);
} pthread_create (&pth,null,recvpackage,null);
Pthread_join (Pth,null);
Close (SOCKFD);
return 0;
} void Tcp_send (int port,unsigned char flag) {//Set destination port Target.sin_port = htons (port);
Construction package Char buffer[256];
memset (buffer,0,256); STruct _TCPHDR Tcpheader;
struct PSD_HDR psdheader;
Fill TCP//destination Port Tcpheader.th_dport = htons (port);
SOURCE Port Tcpheader.th_sport = htons (60000);
Serial number..
Tcpheader.th_seq = htonl (0x1245678);
Confirmation number Tcpheader.th_ack = 0;
(4-bit header length/4-bit reserved word) Tcpheader.th_lenres = (sizeof (tcpheader)/4 << 4 | 0);
SYN flag Tcpheader.th_flag = flag;//syn//sliding window Tcpheader.th_win = htons (16384);
16-bit emergency data offset tcpheader.th_urp = 0;
16-bit checksum tcpheader.th_sum = 0;
Psdheader psdheader.saddr = myaddr.sin_addr.s_addr;
PSDHEADER.DADDR = target.sin_addr.s_addr; PSDHEADER.MBZ = 0; MBZ = must be zero, used to fill the alignment psdheader.ptcl = ipproto_tcp;
8-bit protocol number psdheader.tcpl = htons (sizeof (Tcpheader));
The set checksum computes the TCP checksum memcpy (buffer,&psdheader,sizeof (psdheader)) using pseudo-headers;
memcpy (Buffer+sizeof (Psdheader), &tcpheader,sizeof (Tcpheader));
Tcpheader.th_sum = Checksum ((unsigned short*) buffer,sizeof (psdheader) +sizeof (Tcpheader)); The final package (TCP+IP) MEMCPY (buffer,&tcpheader,sizeof (Tcpheader)); The process of sending due to the IP protocol is a non-connected protocol so you can use sendto int ret = sendto (sockfd,buffer,sizeof (Tcpheader), 0, (struct sockaddr*) &target,
sizeof (target));
if (ret = =-1) {printf ("Send Error!:%s\n", Strerror (errno));
Exit (-1);
}else{//printf ("Send ok\n");
}}/* * Thread callback function * */void* Recvpackage (void*arg) {//Received process Recvfrom printf ("Thread starting...\n");
struct _tcphdr* testtcp;
Char msg[1024];
int len = sizeof (MYADDR);
int count, size;
while (1) {memset (msg,0,1024);
Size = Recvfrom (sockfd,msg,sizeof (msg), 0, (struct sockaddr*) &myaddr,&len);
if (size = =-1) break;
The pointer here is pointing to the first field of the IP header, so get the TCP header with the corresponding offset of 20byte testtcp = (struct _tcphdr*) (msg + sizeof (struct _IPHDR));
if (Size < (20 + 20)) {/* The data read out is less than the minimum length of two heads if continue*/continue;
} if (Ntohs (testtcp->th_dport)! = 60000) {continue;
} if (Testtcp->th_flag = =) {printf ("%d port not open \ n", Ntohs (Testtcp->th_sport));
Continue;
} if (Testtcp->th_flag = =) {Tcp_send (Ntohs (Testtcp->th_sport), 4); printf ("%d ports open.
ACK + syn....\n ", Ntohs (Testtcp->th_sport));
Continue;
}
}
}
There is a big drawback here is that there will be a lot of drops (1M network, using Wireshark experiment). Supposedly TCP should automatically control the speed of the contract ... If you know how to better control and can achieve the best results, please leave a message.
0x02
Test the effect:
Using the original socket can do a lot of things, such as the implementation of Ping tunnel to steal information, such as the implementation of large-scale leakage, it is really should be a good look at the next ~
If there is a wrong place, also hope to leave a message.