linux下端口扫描程序(C)
来源:互联网 发布:ubuntu 服务管理 编辑:程序博客网 时间:2024/05/11 15:09
网络攻击第一步是扫描目标机的开放端口,其原理是(摘自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<stdlib.h>#include<stdio.h>#include<sys/socket.h>#include<netdb.h>#include<string.h>#include<unistd.h>#include<netinet/in.h>#include<arpa/inet.h>#include<fcntl.h>#include<time.h>#include<sys/types.h>#define TIMEOUT 5 //由于把socket设置为非阻塞,使用select函数,观察其 //5秒后的是否连接成功,连接不成功则认为其端口没有开放struct servenet{ char * s_name;char** s_aliases;int s_port;char* s_proto;};//参数是目标机的IPint 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;scanport<end_port;scanport++) { if (-1==(sockfd=socket(AF_INET,SOCK_STREAM,0))){perror("can not create socket\n");exit(1);}memset(&server,0,sizeof(struct sockaddr_in));server.sin_family = AF_INET;server.sin_addr.s_addr = inet_addr(argv[1]);server.sin_port = htons(scanport); int flag = fcntl(sockfd, F_GETFL,0);fcntl(sockfd,F_SETFL, flag|O_NONBLOCK);struct timeval tm;tm.tv_sec = TIMEOUT;tm.tv_usec = 0; //connect为非阻塞,连接不成功立即返回-1if (!connect(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr))){ sp=getservbyport(htons(scanport),"tcp"); printf("tcp port %d open:%s\n ",scanport,sp->s_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;}
- linux下端口扫描程序(C)
- linux c 简单端口扫描程序
- Linux下端口扫描程序nmap介绍
- linux下的connect端口扫描程序
- Linux下UDP端口扫描
- c语言实现端口扫描程序
- linux下的端口扫描工具
- 端口扫描程序
- c语言下的端口扫描代码
- LINUX下编译c程序
- Linux 下编译C程序
- Linux下编译C程序
- Linux下编译C程序
- linux下写c程序
- Linux下编译C程序
- linux下c程序调试
- linux下运行C程序
- linux下编译C程序
- TaskTracker节点上的HttpServer
- 为什么会有Diango这个项目
- Dojo 扩展 javascript 核心库 - dojo.hitch
- SHELL 脚本
- Effective C++读书笔记
- linux下端口扫描程序(C)
- request应用实例
- set集合
- HSRP和VRRP工作原理
- Vim使用笔记
- 一维数组
- stringstream的用法
- c_str的用法
- Android 调试工具集