|
![]() | 作者: periscope [periscope]
![]() |
登录 |
本人所知道的端口扫描知识,贡献给大家。 使用扫描器你可以不动声色的发现远程主机处于listening状态的端口情况及操作系统类型。 扫描器并不是攻击程序,只是用于攻击前的探路。 编写扫描器需要: 1.至少熟练掌握一种语言,如C语言,C++,JAVA; 2.需要掌握在linux或windows下开发C/S应用程序的方法; 3.熟悉网络协议(特别是在做原始套接字编程时,需要特别熟悉网络协议); 4.信心和耐性。 常用扫描技术: 1.TCP connect() 技术 最基本的扫描方法。 如果端口处于侦听状态,那么connect()就能成功。否则,这个端口没有提供服务。这个方法不需要你一定是管理员权限。如果你是在liunx下则建议你调用多个进程同时扫描,如果你是在win32系统下,那么建议你多线程扫描。 2.TCP SYN扫描 一种较为隐蔽的扫描方法。实质上是在TCP connect技术的基础上,去掉了三次握手的最后一步。 这种扫描的程序实现较为复杂,需要使用原始套接字编程。但相对来说具有一定的隐蔽性。使用这个方法要求你必须是管理员。 3.TCP FIN 扫描 关闭的端口会用适当的RST来回复FIN数据包。另一方面,打开的端口会忽略对FIN数据包的回复。这种方法不一定适用于所有系统。需要使用原始套接字编程。这并不是一个可以信赖的扫描方法。 4.UDP 扫描 由于udp是一种无连接的数据报协议,所以扫描方法也比较简单。需要向目标的UDP端口任意发送一些数据,如果该端口没有开放,对方会发回一个“目标不可达”的ICMP包。 附录: /******************************************************************/ 我写的linux下的TCP connect技术多进程扫描工具,缺陷颇多,各位高手指导一下。 /********************************************************************/ #include "scanany.h" #include<time.h> int main(int argc,char *argv[]) { long START_PORT=0,END_PORT=10000; if(argv[1]=='\0'){ PRINTMESSAGE_1();exit(0);} if(argv[2]!='\0') START_PORT=atol(argv[2]); if(argv[2]!='\0') END_PORT=atol(argv[3]); int PORT,SIGN,NUM=0; int seconds_start,seconds_end, seconds_last,distance; char *TARGET_IP; TARGET_IP=argv[1]; int area=IP_SIGN(TARGET_IP); IP_CONVERT(TARGET_IP); PRINTMESSAGE_2(); int i=0; while(i<=area) { seconds_start = time((time_t*)NULL); PORT=START_PORT; while(PORT<=END_PORT) { if(vfork()!=0) { SIGN=function(PORT,TARGET_IP); PORT++; NUM=NUM+SIGN; seconds_end=time((time_t*)NULL); if((seconds_end-seconds_start)>=4&&NUM==0) {printf("由于长时间没有结果,程序认为该主机可能不存在,放弃扫描。\n"); break;} } else { SIGN=function(PORT,TARGET_IP); PORT++; NUM=NUM+SIGN;exit(0);} } seconds_last=time((time_t*)NULL); distance=seconds_last-seconds_start; printf("对IP:%s 扫描完毕.用时:%d 秒;获得 %d 个结果。\n\n",TARGET_IP, distance,NUM); IP_ADD(TARGET_IP); //确定下一个IP NUM=0; i++; } exit(0); } /*************************/ scanany.h /*************************/ #include<stdio.h> #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<stdlib.h> #include<string.h> //返回范围值 int IP_SIGN(char *IP) { int i=0,j=0; char data[3]; int length=strlen(IP); while(i<=length){ if(IP[i]=='+')break;i++;} int bp=i+1; while(j<=length){ data[j]=IP[bp];bp++;j++;} int number=atoi(data); return number; } //纠正IP值 char *IP_CONVERT(char *IP) { int i=0,j=0; int length=strlen(IP); while(i<=length){ if(IP[i]=='+')break;i++;} if(i<=length){ while(i<length){ IP[i]='\0';i++;}}; } //IP+1 char *IP_ADD(char *IP) { char F_IP[3]; int k=0; int length=strlen(IP); int i=length; while(i<=length) {if(IP[i]=='.')break;i--;} int begin=i+1; for(i=begin;i<=length;i++){F_IP[k]=IP[i];k++;} int a=atoi(F_IP); a++; gcvt(a,3,F_IP); k=0; for(i=begin;i<=length;i++){IP[i]=F_IP[k];k++;} } int function(int PORT,char *TARGET_IP) { int s,k=0; struct sockaddr_in addr; //建立TCP套接口 if((s = socket(AF_INET,SOCK_STREAM,0))<0){ perror("socket"); exit(1); } /* 填写sockaddr_in结构*/ bzero(&addr,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port=htons(PORT); addr.sin_addr.s_addr = inet_addr(TARGET_IP); /* 尝试连线*/ if(connect(s,&addr,sizeof(addr))==0){ if(PORT<=1023) printf("IP :%s Well Known Ports : %d\n",TARGET_IP,PORT); if(PORT>=1024&&PORT<=49151)printf("IP :%s Registered Ports : %d\n",TARGET_IP,PORT); if(PORT>=49151&PORT<=65535)printf("IP :%s Dynamic Ports : %d\n",TARGET_IP,PORT); k=1; } close(s); return k; } void PRINTMESSAGE_1() { printf("\n Scanany\n"); printf("\n Usage: scanany [IP] [+number] [start_port] [end_port] \n\n"); printf(" Example: scanany 127.0.0.1 扫描IP: 127.0.0.1\n\n"); printf(" scanany 192.168.0.1+5 扫描IP: 192.168.0.1 至 192.168.0.6\n\n"); printf(" scanany 192.168.0.1+5 0 1024 \n"); printf(" 扫描IP: 192.168.0.1至192.168.0.6 ; 端口区间为:0至1024\n\n"); printf("\n 建议您使用SHELL的重定向功能。\n"); printf(" 注:默认的端口区间为 0 至 10000\n\n"); } void PRINTMESSAGE_2() { printf(" \n注意: 对方有可能捕获您的IP地址\n"); printf("\n请等待.....\n"); printf("对方的以下端口处于Listening状态:\n\n"); } /*******************************************************/ 我写的linux下的监控程序 /*******************************************************/ #include <stdlib.h> #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<unistd.h> #define PORT 141 //陷阱端口。你可以修改这个值,但不要和已经使用的端口冲突. #define MAXSOCKFD 10 int main(int argc, char *argv[]) { int sockfd,newsockfd,is_connected[MAXSOCKFD],fd; struct sockaddr_in addr; int addr_len = sizeof(struct sockaddr_in); fd_set readfds; printf("\n Hunter\n"); printf("\n本程序将捕获攻击者的地址。如果您需要运行其他程序,请另外打开一个SHELL窗口,不要关闭该程序。\n"); //建立TCP套接口 if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0){ perror("socket"); exit(1); } //初始化结构体,并绑定端口 bzero(&addr,sizeof(addr)); addr.sin_family =AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); //绑定套接口 if(bind(sockfd,&addr,sizeof(addr))<0){ perror("connect"); exit(1); } //创建监听套接口 if(listen(sockfd,3)<0){ perror("listen"); exit(1); } for(fd=0;fd<MAXSOCKFD;fd++) is_connected[fd]=0; printf("请等待。。。。。。。。\n"); //等待扫描 while(1){ FD_ZERO(&readfds); //用来清除描述词组&readfds的全部位 FD_SET(sockfd,&readfds); //建立文件句柄sockfd与&readfds的联系 for(fd=0;fd<MAXSOCKFD;fd++)if(is_connected[fd]) FD_SET(fd,&readfds); if(!select(MAXSOCKFD,&readfds,NULL,NULL,NULL))continue; for(fd=0;fd<MAXSOCKFD;fd++) if(FD_ISSET(fd,&readfds)){ if(sockfd ==fd){ if((newsockfd=accept(sockfd,&addr,&addr_len))<0) perror("accept"); shutdown(sockfd,3); is_connected[newsockfd] =1; printf("\n扫描警告。 扫描方法:TCP Connect技术。扫描者来自 :%s\n",inet_ntoa(addr.sin_addr)); } } } exit(0); } /************************************************/ linux下的C/S实例 (来自函数库) /************************************************/ /* 利用socket的TCP client 此程序会连线TCP server,并将键盘输入的字符串传送给server。 */ #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #define PORT 1234 #define SERVER_IP "127.0.0.1" main() { int s; struct sockaddr_in addr; char buffer[256]; if((s = socket(AF_INET,SOCK_STREAM,0))<0){ perror("socket"); exit(1); } /* 填写sockaddr_in结构*/ bzero(&addr,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port=htons(PORT); addr.sin_addr.s_addr = inet_addr(SERVER_IP); /* 尝试连线*/ if(connect(s,&addr,sizeof(addr))<0){ perror("connect"); exit(1); } /* 接收由server端传来的信息*/ recv(s,buffer,sizeof(buffer),0); printf("%s\n",buffer); while(1){ bzero(buffer,sizeof(buffer)); /* 从标准输入设备取得字符串*/ read(STDIN_FILENO,buffer,sizeof(buffer)); /* 将字符串传给server端*/ if(send(s,buffer,sizeof(buffer),0)<0){ perror("send"); exit(1); } } } /* TCP server范例*/ #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<unistd.h> #define PORT 1234 #define MAXSOCKFD 10 main() { int sockfd,newsockfd,is_connected[MAXSOCKFD],fd; struct sockaddr_in addr; int addr_len = sizeof(struct sockaddr_in); fd_set readfds; char buffer[256]; char msg[ ] ="Welcome to server!"; if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0){ perror("socket"); exit(1); } bzero(&addr,sizeof(addr)); addr.sin_family =AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(sockfd,&addr,sizeof(addr))<0){ perror("connect"); exit(1); } if(listen(sockfd,3)<0){ perror("listen"); exit(1); } for(fd=0;fd<MAXSOCKFD;fd++) is_connected[fd]=0; while(1){ FD_ZERO(&readfds); FD_SET(sockfd,&readfds); for(fd=0;fd<MAXSOCKFD;fd++) if(is_connected[fd]) FD_SET(fd,&readfds); if(!select(MAXSOCKFD,&readfds,NULL,NULL,NULL))continue; for(fd=0;fd<MAXSOCKFD;fd++) if(FD_ISSET(fd,&readfds)){ if(sockfd = =fd){ if((newsockfd = accept (sockfd,&addr,&addr_len))<0) perror("accept"); write(newsockfd,msg,sizeof(msg)); is_connected[newsockfd] =1; printf("cnnect from %s\n",inet_ntoa(addr.sin_addr)); }else{ bzero(buffer,sizeof(buffer)); if(read(fd,buffer,sizeof(buffer))<=0){ printf("connect closed.\n"); is_connected[fd]=0; close(fd); }else printf("%s",buffer); } } } } |
地主 发表时间: 06-02-20 13:33 |
![]() | 回复: baiyeling [baiyeling] ![]() |
登录 |
Good![]() |
B1层 发表时间: 06-02-24 22:18 |
![]() | 回复: SysHu0teR [syshunter] ![]() |
登录 |
不错,鼓励下。/:strong 看了你的c/s的程序,谈下个人观点: recv(s,buffer,sizeof(buffer),0); printf("%s\n",buffer); 为了防止输出乱码,最好在printf之前加个buffer[strlen(buffer)]=0;当然更好的是在buffer定义的时候用char buffer[256]={0}; read(STDIN_FILENO,buffer,sizeof(buffer)); /* 将字符串传给server端*/ if(send(s,buffer,sizeof(buffer),0)<0){ 好象read返回的实际读取的字符数。如果是在某些要求效率的场合,可以 len=read(...); send(s,buffer,len) 不知道有没有看过《UNIX网络编程》,共三卷。如果看过那最好了,反正我是没看完 ![]() 现在就缺这样动手能力强的人 ![]() [此贴被 SysHu0teR(syshunter) 在 02月25日22时59分 编辑过] |
B2层 发表时间: 06-02-25 22:55 |
![]() | 回复: SysHu0teR [syshunter] ![]() |
登录 |
忘了说下,最好read和write配对、send和recv配对使用。 |
B3层 发表时间: 06-02-25 22:58 |
![]() | 回复: periscope [periscope] ![]() |
登录 |
多谢版主支持!我最近正在学习linux下的编程。现在正巩固操作系统基础。 |
B4层 发表时间: 06-03-11 11:09 |
![]() | 回复: periscope [periscope] ![]() |
登录 |
回复一下 百叶灵的问题: 这是Linux下的C语言程序。使用Gcc编译。 抱歉,回复的晚了点。 |
B5层 发表时间: 06-03-11 11:16 |
![]() | 回复: periscope [periscope] ![]() |
登录 |
版主和我的年龄好像相差不大,不知是否可以认识一下。 |
B6层 发表时间: 06-03-11 11:21 |
![]() | 回复: periscope [periscope] ![]() |
登录 |
声明一下: “linux下的C/S实例 (来自函数库)”不是在下作品,来自LinuxC函数库的范例,我贴在这里是为了给大家一个参考。 |
B7层 发表时间: 06-03-11 11:39 |
![]() | 回复: SysHu0teR [syshunter] ![]() |
登录 |
![]() |
B8层 发表时间: 06-03-11 19:20 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号