两年前的文章,贴过来充门面。
---------------------------------------------
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()函数进行进一步的测试。一切都由你自由发挥了。 由于我是菜鸟,或许有什么不对的地方。也可能一些细节我没有考虑到。如果你知道的话希望不惜指教。 |