首页
社区
课程
招聘
[原创]简单的网络端口扫描器源码_新手学习
发表于: 2017-6-30 08:43 2779

[原创]简单的网络端口扫描器源码_新手学习

2017-6-30 08:43
2779

/*****************************************************************************************
 *
 *    Function    :   简单的端口扫描控制台程序
 *    Author      :  JNU
 *                    2017.3.3
 *
 *****************************************************************************************/
#include   "stdio.h"
#include   "winsock2.h"
//注意所有的程序在选择网络适配器时,只能选择有限网卡适配器,无线网卡适配器的不行
//加载dll的链接文件
#pragma   comment(lib,"ws2_32")
//该应用程序在cmd命令窗口的使用说明
void   usage(char *name)
{
	printf("Usage:%s  192.168.1.100 1 65536\n",name);
	printf("Usage:%s  IP   StartPort  EndPort\n",name);
}
int main(int argc,char *argv[])
{
	//判断传参个数是不是4 错误处理
	if(argc != 4)
	{
		//传入应用程序全路径
		usage(argv[0]);         
		return -1;
	}
	//初始化Socket版本
	WSADATA wsa;
	if(WSAStartup(MAKEWORD(2,2),&wsa) != 0)
	{
		printf("Winsock Dll initial Failed!初始化sock失败\n");
		return -1;
	}
	//当前连接的目标端口号
	int  nowport;
	//统计打开的端口号
	int  count=0;
	//获取扫面的初始端口号和结束端口号
	int  startport = atoi(argv[2]);
	int  endport = atoi(argv[3]);
	//判断输入端口号是否正确
	if(endport < startport)
	{
		printf("don't&#39;t doing ,endport < startport 端口输入错误\n");
		return -1;
	}
	//设置扫描起始端口号
	nowport = startport;
	printf("Port Start Scan......\n");
	 // Socket address, internet style.
	struct sockaddr_in  sa;
	for( nowport; nowport < endport;nowport++)//起始端口到结束端口循环
	{
		//设置目标主机信息
		sa.sin_family = AF_INET;                        //设置为TCP/IP协议族类型
		sa.sin_port = htons(nowport);                   //设置端口号
		sa.sin_addr.S_un.S_addr = inet_addr(argv[1]);   //设置IP地址
		//创建客户端Socket套接字
		SOCKET sockFD =socket(AF_INET,SOCK_STREAM,0);         //创建一个Socket对象
		if(sockFD == INVALID_SOCKET)
		{
			printf("Socket Craete Error!创建sock套接字错误\n");
			return -1;
		}
		//设置接收超时(ms)
		int iTimeOut =3000;
		setsockopt(sockFD,SOL_SOCKET,SO_RCVTIMEO,(char *)&iTimeOut,sizeof(iTimeOut));
		setsockopt(sockFD,SOL_SOCKET,SO_SNDTIMEO,(char*)&iTimeOut,sizeof(iTimeOut));   
		//设置为非堵塞
		unsigned long  flag = 1;
		ioctlsocket (sockFD, FIONBIO, &flag);
		//超时设置,不能太短,不然扫描不到端口。太长,扫描慢
		struct timeval tm;
		tm.tv_sec = 0;          //s  
		tm.tv_usec = 30000;     //us  10ms
		//用于判断是否连接成功
		int ret = -1;
		//尝试连接服务器
		if(connect(sockFD,(struct sockaddr *)&sa,sizeof(sa)) != SOCKET_ERROR)    //连接失败  连接端口号 ip
		{
			ret = 0;//连接成功
		}
		else{      //错误了                                             
			fd_set set;//套接字集合
			FD_ZERO(&set);
			FD_SET(sockFD,&set);//加入不同的套接字
			//select去轮询套接口,而select的轮询超时时间可以根据自己的需要去设置,最主要的是轮询的集合
			//一定要是读和写的集合,即select的第二和第三个参数要赋值,待select返回就可以去判断返回值来确定connect的进程状态
			if (select(-1, NULL, &set, NULL, &tm) <= 0)          //连接错误或者超时
			{
				ret = -1;
			}else{
				int error = -1;  
				int optLen = sizeof(int);  
				getsockopt(sockFD, SOL_SOCKET, SO_ERROR, (char*)&error, &optLen);//检索错误状态并清除
				// 之所以下面的程序不写成三目运算符的形式, 是为了更直观, 便于注释  
				if (0 != error)  
				{  
				   ret =-1; // 有错误  
				}  
				else                 //连接成功
				{  
					ret = 0;			
				}  
			}	
	
		}
		flag = 0;  
		ioctlsocket(sockFD, FIONBIO, &flag); // 设回为阻塞socket  
		//连接成功
		if(ret == 0)
		{
			count++;
			printf("%s Find %d Port is Opened\n",argv[0],nowport);  // 无错误  
			//如果是21端口,则显示Banner
			if(nowport == 135)
			{
				char buff[2048] = {0};
				char hello[5] = {"test"};
				//向目标主机发送数据
				send(sockFD,hello,sizeof(hello),0);
			    //从目标主机接收数据
				recv(sockFD,buff,sizeof(buff),0);
				printf("FTP Banner: %s\n",buff);
			}else if(nowport == 80){
				//如果是21端口,则显示Banner
				char buff[2048] = {0};
				char get[30] = {"GET HTTP 1.0/1.1\n\n\r\r\r"};
				//向目标主机发送数据
				send(sockFD,get,sizeof(get),0);
			    //从目标主机接收数据
				recv(sockFD,buff,sizeof(buff),0);
				printf("The Server is %s\n",buff);				
		    }
		}
		closesocket(sockFD);
	}//for
	printf("Scan End.......\nFind %d Port is Opened!\n",count);
    //卸载dll
	WSACleanup();
	return -1;
}


cmd运行  exe  后面 跟 3个参数   192.168.1.100 1 65536
不会用的  看截图  新手学习之用 简单

QQ群582865430 过游戏驱动保护 研究 修改内核 写外挂 交流


[课程]FART 脱壳王!加量不加价!FART作者讲授!

最后于 2018-8-17 16:45 被神大蛇编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//