linux下端口扫描程序(C)

网络攻击第一步是扫描目标机的开放端口,其原理是(摘自 http://www.pconline.com.cn/pcjob/nettech/safe/others/0502/557020_1.html):

根据TCP协议规范,当一台计算机收到一个TCP连接建立请求报文(TCP SYN)的时候,做这样的处理:

  1、 如果请求的TCP端口是开放的,则回应一个TCP ACK报文,并建立TCP连接控制结构(TCB);
  2、 如果请求的TCP端口没有开放,则回应一个TCP RST(TCP头部中的RST标志设为1)报文,告诉发起计算机,该端口没有开放。

  相应地,如果IP协议栈收到一个UDP报文,做如下处理:

  1、 如果该报文的目标端口开放,则把该UDP报文送上层协议(UDP)处理,不回应任何报文(上层协议根据处理结果而回应的报文例外);
  2、 如果该报文的目标端口没有开放,则向发起者回应一个ICMP不可达报文,告诉发起者计算机该UDP报文的端口不可达。

  利用这个原理,攻击者计算机便可以通过发送合适的报文,判断目标计算机哪些TCP或UDP端口是开放的,过程如下:

  1、 发出端口号从0开始依次递增的TCP SYN或UDP报文(端口号是一个16比特的数字,这样最大为65535,数量很有限);
  2、 如果收到了针对这个TCP报文的RST报文,或针对这个UDP报文的ICMP不可达报文,则说明这个端口没有开放;
  3、 相反,如果收到了针对这个TCP SYN报文的ACK报文,或者没有接收到任何针对该UDP报文的ICMP报文,则说明该TCP端口是开放的,UDP端口可能开放(因为有的实现中可能不回应ICMP不可达报文,即使该UDP端口没有开放)。

  这样继续下去,便可以很容易的判断出目标计算机开放了哪些TCP或UDP端口,然后针对端口的具体数字,进行下一步攻击,这就是所谓的端口扫描攻击。

   根据以上原理,我编写了以下代码(只进行了TCP扫描):

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define TIMEOUT 5 //由于把socket设置为非阻塞,使用select函数,观察其
                //5秒后的是否连接成功,连接不成功则认为其端口没有开放



struct servenet{
    char * s_name;
	char** s_aliases;
	int    s_port;
	char*  s_proto;
};


//参数是目标机的IP
int main(int argc,char** argv)
{
	struct sockaddr_in server;
	int ret;
	int len;
	int scanport;
    int start_port=0;
    int end_port=1024;
	int sockfd;

	fd_set rset;
	fd_set wset; 
        struct servenet *sp;

	

       
    for(scanport=start_port;scanports_name);

			
                }//假如连接不成功,则运行select,直到超时
		else {
			FD_ZERO(&rset);
			FD_ZERO(&wset);
			FD_SET(sockfd, &rset);
			FD_SET(sockfd, &wset);
			int error; //错误代码
			int len = sizeof(error); 
			//5秒后查看socket的状态变化 
			if (select(sockfd+1,&rset,&wset,NULL,&tm)>0){
				getsockopt(sockfd, SOL_SOCKET, SO_ERROR,&error, &len );
				if(error == 0)
					printf("Port %d is opened\n", scanport);
			}
		
		}
		close(sockfd);

	}
		return 0;

}


你可能感兴趣的:(网络,端口扫描,TCP,网络攻击)