端口扫描器的设计与实现.docx

上传人:b****3 文档编号:27395464 上传时间:2023-06-30 格式:DOCX 页数:21 大小:209.58KB
下载 相关 举报
端口扫描器的设计与实现.docx_第1页
第1页 / 共21页
端口扫描器的设计与实现.docx_第2页
第2页 / 共21页
端口扫描器的设计与实现.docx_第3页
第3页 / 共21页
端口扫描器的设计与实现.docx_第4页
第4页 / 共21页
端口扫描器的设计与实现.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

端口扫描器的设计与实现.docx

《端口扫描器的设计与实现.docx》由会员分享,可在线阅读,更多相关《端口扫描器的设计与实现.docx(21页珍藏版)》请在冰豆网上搜索。

端口扫描器的设计与实现.docx

端口扫描器的设计与实现

 

河南理工大学

计算机科学与技术学院

课程设计报告

2012—2013学年第二学期

 

课程名称计算机网络

设计题目简单端口扫描器

姓名杨鹏飞

学号311109050425

专业班级网信11-04

指导教师李莹莹

2013年6月19日

1.课程设计的目的........................................................

2.课程设计的要求........................................................

3.端口扫描器相关知识.................................................

3.1:

端口的基本概念...............................................

3.2:

常见的端口介绍...............................................

3.3:

端口扫描器基本原理.......................................

3.4:

端口扫描常用技术...........................................

4.实验流程....................................................................

4.1:

基本步骤.............................................................

4.2:

主要函数...............................................................

4.3流程图.....................................................................

5.实验结果.....................................................................

6.源程序.........................................................................

 

一:

课程设计的目的

扫描器是网络信息收集的一种方法,从功能上可分为漏洞扫描器和端口扫描器。

理解客户机-服务器与端口扫描的工作原理,实现对目标主机端口扫描的功能,即发现目标主机开启的端口信息。

 

二:

课程设计要求

本课程设计的目标是设计并实现一个网络扫描器,它通过与目标主机TCP/IP端口建立连接并请求某些服务,记录目标主机的应答,分析目标主机相关信息,从而发现目标主机某些内在的安全弱点。

扫描器通常分两类:

漏洞扫描器和端口扫描器。

端口扫描器用来扫描目标机开放的服务端口以及端口相关信息。

漏洞扫描器检查目标中可能包含的大量已知的漏洞,如果发现潜在的漏洞可能性,就报告给扫描者。

网络漏洞端口扫描器对目标系统进行检测时,首先探测目标系统的存活主机,对存活主机进行端口扫描,确定系统开放的端口,同时根据协议指纹技术识别出主机的操作系统类型。

然后扫描器对开放的端口进行网络服务类型的识别,确定其提供的网络服务。

漏洞扫描器根据目标系统的操作系统平台和提供的网络服务,调用漏洞资料库中已知的各种漏洞进行逐一检测,通过对探测响应数据包的分析判断是否存在漏洞。

在分析总结目前现有的扫描软件,在掌握扫描器的原理基础上,首先设计、实现一种端口扫描程序,存储扫描结果。

在此基础上,有余力的同学对已经开放的重要端口有具体漏洞分析检测。

程序具体要求实现以下任一程序:

高效端口扫描器设计与实现:

参照常见端口扫描器,在局域网内,能对所有计算机进行常用端口的高速扫描,给出扫描结果。

另外根据配置不同的网段,实现正对校园网络的基于网段的高速扫描。

高效的漏洞扫描器的设计与实现:

设计网络漏洞扫描仪的结构,建立常见的漏洞库,并基于该漏洞库,实现高效的基于网段的漏洞扫描器。

主机脆弱性分析系统:

将漏洞和端口扫描结合起来,实现针对主机的脆弱性分析系统。

三:

相关知识

1.端口的基本概念:

我们这里所说的端口,不是计算机硬件的i/o端口,而是软件形式上的概念。

服务器可以向外提供多种服务,比如,一台服务器可以同时是web服务器,也可以是ftp服务器,同时,它也可以是邮件服务器。

为什么一台服务器可以同时提供那么多的服务呢?

其中一个很主要的方面,就是各种服务采用不同的端口分别提供不同的服务。

根据提供服务类型的不同,端口分为两种,一种是tcp端口,一种是udp端口。

计算机之间相互通信的时候,分为两种方式:

一种是发送信息以后,可以确认信息是否到达,也就是有应答的方式,这种方式大多采用tcp协议;一种是发送以后就不管了,不去确认信息是否到达,这种方式大多采用udp协议。

对应这两种协议的服务提供的端口,也就分为tcp端口和udp端口。

那么,如果攻击者使用软件扫描目标计算机,得到目标计算机打开的端口,也就了解了目标计算机提供了那些服务。

2.常见端口介绍

端口:

21服务:

FTP

说明:

FTP服务器所开放的端口,用于上传、下载。

最常见的攻击者用于寻找打开anonymous的FTP服务器的方法。

这些服务器带有可读写的目录。

木马DolyTrojan、Fore、Invisible、WinCrash和BladeRunner所开放的端口。

端口:

23服务:

Telnet

说明:

远程登录,入侵者在搜索远程登录UNIX的服务。

大多数情况下扫描这一端口是为了找到机器运行的*作系统。

还有使用其他技术,入侵者也会找到密码。

木马TinyTelnetServer就开放这个端口

端口:

25服务:

SMTP

说明:

SMTP服务器所开放的端口,用于发送邮件。

入侵者寻找SMTP服务器是为了传递他们的SPAM。

入侵者的帐户被关闭,他们需要连接到高带宽的E-MAIL服务器上,将简单的信息传递到不同的地址。

木马Antigen、EmailPasswordSender、HaebuCoceda、ShtrilitzStealth、WinPC、WinSpy都开放这个端口

端口:

80服务:

HTTP

说明:

用于网页浏览。

木马Executor开放此端口。

3.端口扫描器功能简介:

服务器上所开放的端口就是潜在的通信通道,也就是一个入侵通道。

对目标计算机进行端口扫描,能得到许多有用的信息,进行端口扫描的方法很多,可以是手工进行扫描、也可以用端口扫描软件进行。

扫描器通过选用远程TCP/IP不同的端口的服务,并记录目标给予的回答,通过这种方法可以搜集到很多关于目标主机的各种有用的信息,例如远程系统是否支持匿名登陆、是否存在可写的FTP目录、是否开放TELNET服务和HTTPD服务等。

4.常用端口扫描技术:

1、TCPconnect()扫描:

这是最基本的TCP扫描,操作系统提供的connect()系统调用可以用来与每一个感兴趣的目标计算机的端口进行连接。

如果端口处于侦听状态,那么connect()就能成功。

否则,这个端口是不能用的,即没有提供服务。

这个技术的一个最大的优点是,你不需要任何权限。

系统中的任何用户都有权利使用这个调用。

另一个好处就是速度,如果对每个目标端口以线性的方式,使用单独的connect()调用,那么将会花费相当长的时间,使用者可以通过同时打开多个套接字来加速扫描。

使用非阻塞I/O允许你设置一个低的时间用尽周期,同时观察多个套接字。

但这种方法的缺点是很容易被察觉,并且被防火墙将扫描信息包过滤掉。

目标计算机的logs文件会显示一连串的连接和连接出错消息,并且能很快使它关闭。

2、TCPSYN扫描:

这种技术通常认为是“半开放”扫描,这是因为扫描程序不必要打开一个完全的TCP连接。

扫描程序发送的是一个SYN数据包,好象准备打开一个实际的连接并等待反应一样(参考TCP的三次握手建立一个TCP连接的过程)。

一个SYN|ACK的返回信息表示端口处于侦听状态:

返回RST表示端口没有处于侦听态。

如果收到一个SYN|ACK,则扫描程序必须再发送一个RST信号,来关闭这个连接过程。

这种扫描技术的优点在于一般不会在目标计算机上留下记录,但这种方法的缺点是必须要有root权限才能建立自己的SYN数据包。

3、TCPFIN扫描:

SYN扫描虽然是“半开放”方式扫描,但在某些时候也不能完全隐藏扫描者的动作,防火墙和包过滤器会对管理员指定的端口进行监视,有的程序能检测到这些扫描。

相反,FIN数据包在扫描过程中却不会遇到过多问题,这种扫描方法的思想是关闭的端口会用适当的RST来回复FIN数据包。

另一方面,打开的端口会忽略对FIN数据包的回复。

这种方法和系统的实现有一定的关系,有的系统不管端口是否打开都会回复RST,在这种情况下此种扫描就不适用了。

另外这种扫描方法可以非常容易的区分服务器是运行Unix系统还是NT系统。

4、IP段扫描:

这种扫描方式并不是新技术,它并不是直接发送TCP探测数据包,而是将数据包分成两个较小的IP段。

这样就将一个TCP头分成好几个数据包,从而过滤器就很难探测到。

但必须小心:

一些程序在处理这些小数据包时会有些麻烦。

5、TCP反向ident扫描:

ident协议允许(rfc1413)看到通过TCP连接的任何进程的拥有者的用户名,即使这个连接不是由这个进程开始的。

例如扫描者可以连接到http端口,然后用identd来发现服务器是否正在以root权限运行。

这种方法只能在和目标端口建立了一个完整的TCP连接后才能看到。

6、FTP返回攻击:

FTP协议的一个有趣的特点是它支持代理(proxy)FTP连接,即入侵者可以从自己的计算机和目标主机的(协议解释器)连接,建立一个控制通信连接。

然后请求这个server-PI激活一个有效的server-DTP(数据传输进程)来给Internet上任何地方发送文件。

对于一个User-DTP,尽管RFC明确地定义请求一个服务器发送文件到另一个服务器是可以的,但现在这个方法并不是非常有效。

这个协议的缺点是“能用来发送不能跟踪的邮件和新闻,给许多服务器造成打击,用尽磁盘,企图越过防火墙”。

四:

实验流程

1步骤:

1.先输入想要扫描的网段;

2.然后将输入的网段转化为可排序的ip数组

3.建立多个线程,每个线程扫描一个ip。

每个线程内先建立数据流套接字,然后绑定ip端口进行扫描。

将扫描端口保存到g_map_ScanResult。

4.清理结束后进程,输出结果。

5.计算所用时间。

程序中主要的函数:

intmain()//主函数

InitProc();//初始化

UserInput();//输入

ScanIp(g_startIp,g_endIp,g_map_ScanResult);//开始扫描

CleanProc();//清理结束后进程

OutPutScanInfo();//输出结果

DWORDWINAPIThreadFunc(LPVOIDth_para)//扫描线程每一个ip

unsignedlongInvertIp(unsignedlongsrcIp)//将ip化为可比较的

intGetIpToScan(conststring&StartIp,conststring&EndIp,vector&vec_ip)//将所有ip排序放在一个数组内

2主流程图:

 

五:

结果

 

开始界面:

扫描界面:

结果界面:

六:

总结

通过这次端口扫描器的实验深化了信息对抗,信息安全的意识。

对于网络扫描器有了整体上的认识。

了解了socket函数的基本用法和端口扫描的基本原理,更加熟练掌握了c++语言。

在这次设计中在处理线程上遇到了很大麻烦,不过通过上网查找和书本,基本解决,还有就是刚开始在socket的运用上很是不懂,经过上网查找也顺利解决。

总之这次设计,不仅是对以前只是的巩固,也学习到了许多新知识。

七:

源程序

源程序:

#pragmacomment(lib,"ws2_32.lib")

#pragmawarning(disable:

4786)

#include

#include

#include

#include

#include

#include

#include

#include

//#include"IpScan.h"

usingnamespacestd;

//全局变量:

//待扫描的端口

shortg_portsTOscan[]={20,21,22,23,25,42,43,47,53,63,67,68,79,80,95,106,107,109,110,113,135,137,138,139,143,

144,161,162,443,445,1024,1080,1433,1434,1755,3306,4000,5010,5190,5631,5632,8000,8080};

constshortPORTSNUM=sizeof(g_portsTOscan)/sizeof(short);//端口个数

//等扫描的IP

vectorg_vec_IpToScan;

stringg_startIp;

stringg_endIp;

//开启的线程数,目前为1个IP1个线程

longg_runThreadNum;

//socket相关

TIMEVALg_timeout;//阻塞等待时间

//FD_SETg_mask;//socket模式设置,储存socket信息

constshortTIMEOUT=1;//阻塞等待时间

WSADATAg_wsadata;//socket版本信息

//线程中的互斥体

HANDLEg_PortMutex;

HANDLEg_ThreadNumMutex;

HANDLEg_ResultMutex;//输入结果的互斥量

//保存IP扫描的结果

multimapg_map_ScanResult;

//-------------------------------------------------------------------------------------------------------------------

//线程函数,扫描每一个IP

DWORDWINAPIThreadFunc(LPVOIDth_para)

{

//获取需要扫描的IP

//char*pStrIp=(char*)th_para;

unsignedlongulScanIp=*(unsignedlong*)th_para;

intindex=0;//端口索引

SOCKETlink_sock;//SOCKET

FD_SETset_flag;//SOCKET描述

shortselect_ret;//select异步返回值

shortport;//正在扫描的端口

while(index

{

port=g_portsTOscan[index];

//创建数据流套接字

link_sock=socket(AF_INET,SOCK_STREAM,0);

if(link_sock==INVALID_SOCKET)

{

//cout<<"创建link_socksocket失败:

错误号为:

"<

WaitForSingleObject(g_ThreadNumMutex,INFINITE);

g_runThreadNum--;

ReleaseMutex(g_ThreadNumMutex);

//cout<<"***还有_"<

return-1;

}

FD_ZERO(&set_flag);//将指定文件描述符清空

FD_SET(link_sock,&set_flag);//用于在文件描述符集合中增加一个新的文件描述符

//设置连接地址

SOCKADDR_INscan_addr;

scan_addr.sin_family=AF_INET;

scan_addr.sin_addr.s_addr=ulScanIp;

scan_addr.sin_port=htons(port);

unsignedlongsock_set=1;

ioctlsocket(link_sock,FIONBIO,&sock_set);//设置套接字为非阻塞模式,第3个参数非0为非阻塞

connect(link_sock,(structsockaddr*)&scan_addr,sizeof(scan_addr));//连接指定IP端口

select_ret=select(0,NULL,&set_flag,NULL,&g_timeout);//异步返回值

if(select_ret==0||select_ret==-1)

{

++index;

continue;

}

else

{

strstreamstream_result;

structin_addripaddr;

ipaddr.s_addr=ulScanIp;

char*pStrIp=inet_ntoa(ipaddr);

stream_result<<"\t主机地址为:

"<

"<

stringstr_result(stream_result.str());

//将扫描结果储存到输出变量中去

WaitForSingleObject(g_ResultMutex,INFINITE);

g_map_ScanResult.insert(make_pair(ulScanIp,str_result));

ReleaseMutex(g_ResultMutex);

}

++index;

}

//扫描完一个线程

shutdown(link_sock,0);

closesocket(link_sock);

WaitForSingleObject(g_ThreadNumMutex,INFINITE);

g_runThreadNum--;

ReleaseMutex(g_ThreadNumMutex);

//cout<<"****还有_"<

return0;

}

//----------------------------------------------------------------------------------------------------------

//将IP转化成能直接递增和递减的地址

unsignedlongInvertIp(unsignedlongsrcIp)

{

unsignedcharfirst;

unsignedcharsecond;

unsignedcharthird;

unsignedcharfourth;

first=srcIp&0x00FF;

second=(srcIp>>8)&0x00FF;

third=(srcIp>>16)&0x00FF;

fourth=(srcIp>>24)&0x00FF;

return(first<<24)|(second<<16)|(third<<8)|fourth;

}

//------------------------------------------------------------------------------------------------

//将IP内的IP转化成一个一个unsignedlong类型存在数组中

intGetIpToScan(conststring&StartIp,conststring&EndIp,vector&vec_ip)

{

//判断输入的IP是否合法

unsignedlongulStartIp=inet_addr(StartIp.c_str());

unsignedlongulEndIp=inet_addr(EndIp.c_str());

if(

INADDR_NONE==ulStartIp

||

INADDR_NONE==ulEndIp

{

cout<<"请输入合法的IP"<

return-1;

}

//////////////判断查询的是一个IP还是IP段/////////////////////////////////////

if(ulStartIp==ulEndIp&&ulStartIp!

=0)

{

vec_ip.push_back(ulStartIp);

return0;

}

if(ulStartIp==0&&ulEndIp==0)

{

return0;

}

if(ulStartIp==0)

{

vec_ip.push_back(ulEndIp);

return0;

}

if(ulEndIp==0)

{

vec_ip.push_back(ulStartIp);

return0;

}

////////////////////////////////////////////////////////////////////////////

//将IP转换成可以递增比较的类型

ulStartIp=InvertIp(ulStartIp);

ulEndIp=InvertIp(ulEndIp);

//指定前后顺序,ulEndIp较大

unsignedlongmax_ip;

if(ulStartIp>ulEndIp)

{

max_ip=ulStartIp;

ulStartIp=ulEndIp;

ulEndIp=max_ip;

}

intipnums=ulEndIp-ulStartIp;

for(inti=0;i

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 计算机软件及应用

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1