论坛: 编程破解 标题: 端口扫描知识 复制本贴地址    
作者: 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 但我不是很清楚,你能不能说一下:这是那个版本的C语言,虽然我学过C但不知道是那个版本滴?!

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号