CSDN博客

img mikespook

linux下tcp connect扫描器的制作

发表于2004/6/25 13:51:00  1198人阅读

分类: 技术杂谈 临时 系统 编程 做人与编程

两年前的文章,贴过来充门面。

---------------------------------------------

linux下tcp connect扫描器的制作

( 作者:mikespook | 发布日期:2002-12-8 | 浏览次数:111 )

关键字:linux,网络,扫描,connect()
前言:
     本文章只是为了给广大和我一样的菜鸟一个指引。如果你是高手,或对编程毫无兴趣。建议请不要在此浪费时间。

     tcp connect扫描是一种最基本的扫描方式。通过connect()函数,与要扫描的目标主机建立可靠连接。访问指定端口。如果端口被监听就记录下来。否则转到下一个端口进行连接测试。它的优点是不需要任何特权。只要你是linux上的用户就可以运行。而且速度非常快。除了象本文这样逐一扫描外,还可以用非阻塞方式打开多个socket进行扫描。但是 tcp connect 有一个最大的缺点。它很容易被检测到,而且防备较好的主机还有可能对其进行过滤。系统日志会对其进行记录。
     扫描器的编制原理非常简单。下面我们就从原代码直接学习它的制作方法。

/*------------------------------scan.c-----------------------------------*/
/*gcc -O -o tcpscan scan.c*/
/*Unsafe Scan*/
/*For studing*/
/*mikespook*/
/*2002.5.18*/

#include
#include
#include
#include
#include
#include
/* 这个函数是用来检查输入的参数是IP地址还是主机名 */
int correcthost(const char *host, struct sockaddr_in *sock);

int main(int argc, int *argv[])
{
  /* 端口变量 */
  int n_port, n_begin_port, n_end_port;
  /* socket套接字 */
  int sock_id;
  int rtn_err;
  /* socket结构 */
  struct sockaddr_in remote_sock;

  if(argc != 4){
    printf("Usage: scan /n");
    printf("Writen by mikespook/n");
    printf("mikespook@hotmail.com/tWith subject:report for scan/n");
    exit(0);
  }

  n_begin_port = atoi(argv[2]);
  n_end_port = atoi(argv[3]);
  remote_sock.sin_family = AF_INET;
  rtn_err = correcthost((char *)argv[1], (struct sockaddr_in *)&remote_sock);

  if(rtn_err != 0)
    exit(1);
  /* 使用for循环逐一扫描端口 */
  for(n_port = n_begin_port; n_port <= n_end_port; n_port++){
    /* 为了保证在不同处理器上能够很好的运行,必须使用htons()函数处理传入的端口号 */
    remote_sock.sin_port = htons(n_port);

    sock_id = socket(AF_INET, SOCK_STREAM, 0);/* 初始化一个socket */
    /* 如果初始化失败就输出错误,并退出程序 */
    if(sock_id < 0){
      perror("/nsocket");
      exit(2);
    }
    /* 连接到主机上 */
    rtn_err = connect(sock_id, (struct sockaddr *)&remote_sock, sizeof(remote_sock));
    /* 如果连接成功就输出端口 */
    if(rtn_err < 0){
      fflush(stdout);
    }
    else{
      printf("%s:%d accepted./n", argv[1], n_port);
      /* 关闭输出、输入连接 */
      if(shutdown(sock_id, 2) < 0){
        perror("/nshutdown");
        exit(2);
      }
    }
    /* 关闭套接字。如果不关闭套接字或将这句放到循环外的话,会因为打开太多的套接字而操作失败。*/
    close(sock_id);
  }
  printf("Scan over!/n");
  exit(0);
}

/* 检查参数是IP还是主机名 */
int correcthost(const char *host, struct sockaddr_in *sock)
{
  struct hostent *struct_host;
  /* 如果输入的参数*host是数字则认为输入的是IP地址,否则认为输入的是主机名 */
  if(isdigit(*host))
    sock->sin_addr.s_addr = inet_addr(host);
  else{
    struct_host = gethostbyname(host);
    /* 如果成功取得主机名就将其传入 sockaddr_in 的结构中去,否则输出错误退出。*/
    if(struct_host != NULL){
      bcopy(struct_host->h_addr, (char *)&sock->sin_addr, struct_host->h_length);
    }
    else{
      printf("Get error with host name./n");
      return(-1);
    }
  }
  return(0);
}
-------------------------------------------------------------------------------
最后我还想说明一下,你还可以使用fork()进行多进程扫描。或开起多个socket然后分段用多个socket的非阻塞方式扫描。而且得到可用的PORT列表后还可以通过read()和write()函数进行进一步的测试。一切都由你自由发挥了。
由于我是菜鸟,或许有什么不对的地方。也可能一些细节我没有考虑到。如果你知道的话希望不惜指教。
阅读全文
0 0

相关文章推荐

img
取 消
img