udp端口扫描 报告.docx

上传人:b****6 文档编号:7066327 上传时间:2023-01-16 格式:DOCX 页数:13 大小:131.21KB
下载 相关 举报
udp端口扫描 报告.docx_第1页
第1页 / 共13页
udp端口扫描 报告.docx_第2页
第2页 / 共13页
udp端口扫描 报告.docx_第3页
第3页 / 共13页
udp端口扫描 报告.docx_第4页
第4页 / 共13页
udp端口扫描 报告.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

udp端口扫描 报告.docx

《udp端口扫描 报告.docx》由会员分享,可在线阅读,更多相关《udp端口扫描 报告.docx(13页珍藏版)》请在冰豆网上搜索。

udp端口扫描 报告.docx

udp端口扫描报告

《网络协议分析》

利用UDP进行主机端口扫描

 

专业:

班级:

姓名:

学号:

日期:

 

1.任务题目及要求

1.1任务简介

UDP是TCP/IP协议族伟传输层设计的两个协议之一,它在进程与进程的通信过程中,提供了有限的差错校验功能,是一种无连接的,不可靠的协议。

UDP在一个较低的水平上完成进程之间的通信,在收到分组的时候没有流量控制机制也没有确认机制,适用于可靠性比较高的局域网。

由于UDP采用无连接的方式,因此协议简单,在一些特定的应用中协议运行效率高。

本次课程设计的目的主要是了解UDP协议的网络传输过程中的一些原理。

1.2任务要求

编写一个简单的主机端口扫描程序,要求能够探测目的主机的端口状态。

具体要求:

(1)要求用户可以在参数中输入需要扫描的目的主机的IP地址与端口,输出端口的状态信息。

(2)要求使用UDP协议进行端口的扫描过程。

(3)有良好的编程规范与注释信息。

2.课题成员及分工

本课题组员:

周均

负责全部工作。

3.相关知识简介

3.1课题的背景及意义

网络中每台计算机犹如一座城堡,这些城堡中,有些是对外完全开放的,有些却是大门紧闭的。

入侵者们是如何找到,并打开它们的城门呢?

这些城门究竟通向何处?

在网络中,把这些城堡的“城门”称之为计算机的“端口”。

端口扫描是入侵者搜索信息的几种常用方法之一,也正是这一种方法最容易暴露入侵者的身份和意图。

一般说来,扫描端口有以下目的:

判断目标主机上开放了哪些服务

判断目标主机的操作系统

如果入侵者掌握了目标主机开放了哪些服务,运行何种操作系统,他们就能使用相应的手段实现入侵。

而如果管理员先掌握了这些端口服务的安全漏洞,就能采取有效的安全措施,防范相应的入侵。

计算机信息网络的发展加速了信息化时代的进程,但是随着社会网络化程度的增加,对计算机网络的依赖也越来越大,网络安全问题也日益明显。

端口扫描技术是发现安全问题的重要手段之一。

一个端口就是一个潜在的通信通道,也就是一个入侵通道。

对目标计算机进行端口扫描,能得到许多有用的信息。

扫描器通过选用远程TCP/IP不同的端口的服务,并记录目标给予的回答,通过这种方法,可以搜集到很多关于目标主机的各种有用的信息,从而发现目标机的某些内在的弱点。

3.2关键技术

UDP是UserDatagramProtocol的简称,中文名是用户数据包协议,是OSI参考模型中一种无连接的传输协议,提供面向事务的简单不可靠信息传送服务,IETFRFC768是UDP的正式规范。

在大多数情况下,当向一个未开放的UDP端口发送数据时,其主机就会返回一个ICMP不可到达(ICMPPORTUNREACHABLE)的错误,因此大多数UDP端口扫描的方法就是向各个被扫描的UDP端口发送零字节的UDP数据包,如果收到一个ICMP不可到达的回应,那么则认为这个端口是关闭的,对于没有回应的端口则认为是开放的。

可是由于大部分系统都限制了ICMP差错报文的产生速度,所以针对特定主机的UDP大量端口扫描速度缓慢,此外由于UDP协议和ICMP协议都是不可靠协议,所以未收到回应可能由于数据包未送达造成,所以扫描程序需要针对同一端口多次尝试后才能确定其状态。

3.3关键API函数

3.3.1.WSAStarup函数

WSAStarup函数的格式如下:

intWSAStarup(WORDwVersionRequested,LPWSADATAlpWSAData);

程序在使用Socket之前必须使用WSAStarup函数。

该函数的第一个参数wVersionRequested:

一个WORD(双字节)型数值,指定了应用程序需要使用的Winsock规范的最高版本;第二个参数lpWSAData:

指向WSADATA数据结构的指针,用来接收WindowsSockets实现的细节。

函数执行成功后返回0.

3.3.2.WSACleanup函数

WSACleanup函数的格式如下:

intWSACleanup(void);

程序在完成对请求的Socket库的使用后,要调用WSACleanup函树来解除与Socket库的绑定并且释放Socket库所占用的系统资源。

3.3.3.socket函数

socket函数格式为:

socket(intaf,inttype,intprotocol)

第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET;第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM、原始套接字SOCK_RAW(WinSock接口并不适用某种特定的协议去封装它,而是由程序自行处理数据包以及协议首部);第三个参数指定应用程序所使用的通信协议,此参数可以指定单个协议系列中的不同传输协议,在Internet通讯域中,此参数一般取值为0,系统会根据套接字的类型决定应使用的传输层协议。

3.3.4.closesocket函数

closesocket函数的格式为:

closesocket(SOCKETs);

closesocket函数用来关闭一个描述符为s的套接字。

如果发生错误,则closesocket()返回0;否则的话,返回SOCKET_ERROR错误。

3.3.5.sendto函数

sendto函数的格式为:

sendto(SOCKETs,constcharFAR*buf,intlen,intflags,conststructsockaddrFAR*to,inttolen);

sendto函数用来向某个端口发送数据。

s:

一个标识套接口的描述字;buf:

包含待发送数据的缓冲区;len:

buf缓冲区中数据的长度;flags:

调用方式标志位;to:

(可选)指针,指向目的套接口的地址;tolen:

to所指地址的长度。

3.3.6.recvfrom函数

recvfrom函数的格式为:

recvfrom(ints,void*buf,intlen,unsignedintflags,structsockaddr*from,socket_t*fromlen)

recvfrom函数用来接收返回的ICMP包。

s:

标识一个已连接套接口的描述字;buf:

接收数据缓冲区;len:

缓冲区长度;flags:

调用操作方式;from:

(可选)指针,指向装有源地址的缓冲区;fromlen:

(可选)指针,指向from缓冲区长度值。

3.3.7.bind函数

bind函数的格式为:

intbind(SOCKETs,conststructsockaddrFAR*name,intnamelen)

bind函数用来给socket绑定一个IP地址和一个特定的端口号。

s:

标识一未捆绑套接口的描述字;name:

赋予套接口的地址;sockaddr结构定义如下:

structsockaddr{u_shortsa_family;charsa_data[14];};

namelen:

name名字的长度。

4.系统设计

4.1主要目标

本程序主要实现了:

UDP扫描功能;

能对单个指定的主机进行扫描或扫描指定网段内的主机;

能扫描特定的部分端口号或对指定的端口段内的端口进行逐个扫描;

4.2开发环境及工具

测试平台:

WindowsXPProfessional

使用软件:

VisualC++6.0

开发语言:

C语言

4.3功能模块与系统结构

作为端口扫描程序,首先需要完成的功能就是对于系统操作系统的服务端口进行扫描,返回扫描结果。

对于端口的扫描,包括对于本机系统服务端口,局域网内目标机系统,以及远程IP的系统服务端口进行扫描。

有些时候,用户并不需要去扫描整个系统的所有端口,因为这样的话不仅会浪费大量的时间,而且可能导致难以找到自己需要了解的端口的扫描结果。

所以,对于选择性地对端口进行扫描也非常重要。

这当然也是扫描程序需要实现的功能之一。

用户在等待扫描的时候,往往希望知道它的工作进度。

这样用户可以更好地控制自己的操作。

站在用户的角度思考,设置进度是程序需要完成的,这样就能知道程序扫描的进度。

系统必须提供的服务是功能需求的基本,本着站在用户角度思考的原则,做出如上叙述需求,从简列举如下:

扫描功能;

地址选择功能;

端口选择功能;

端口扫描程序功能模块如下图所示:

图1系统功能模块图

图2程序执行流程图

5.UDP扫描的实现

这种方法由于使用的是UDP协议。

由于这个协议很简单,所以扫描变得相对比较困难。

这是由于打开的端口对扫描探测并不发送一个确认,关闭的端口也并不需要发送一个错误数据包。

幸运的是,许多主机在你向一个未打开的UDP端口发送一个数据包时,会返回一个ICMP_PORT_UNREACH错误。

这样就能发现哪个端口是关闭的。

UDP和ICMP错误都不保证能到达,因此这种扫描就不那么可靠。

而且这种扫描方法是很慢的,因为RFC对ICMP错误消息的产生速率做了规定,而且本程序的UDP扫描只支持单线程。

5.1基本原理

首先使用socket()函数创建套接字,再用bind()函数绑定套接字,然后向扫描的目的主机的目的端口发送UDP数据包,再等待目的主机的目的端口是否返回ICMP_PORT_UNREACH错误数据报,若收到返回的错误数据包,则说明该端口是关闭着的,否则该端口是打开的,再将打开的端口保存进静态数组中,以方便显示结果。

DoScanPort_UDP(LPVOIDlp)//UDPporttoscan

{

…………………………

sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);

………………………

if(bind(sockfd,(sockaddr*)&SOURCE_ADDR,sizeof(SOURCE_ADDR))==SOCKET_ERROR){…………………}

if(retval=dlg.Send_UDPinfo(S_ADDRESS,inet_addr(D_ADDRESS),Source_Port,PortToScan)==SEND_FAULT){…………………………}

elseif(retval==SEND_SET_ERROR){………………………………}

elseif(retval==SEND_OK)

{

if((retval=dlg.Get_ICMPinfo(sockfd,&DEST_ADDR))==1)

{

str.Format("%d",PortToScan);

showout_udp+=str+"|";

}

}

closesocket(sockfd);

return0;

}

5.2计算效验和

首先通过while循环,将各位相加求和,若为奇数个字节,则最后通过if循环将最后一个字节加完,再移位做位运算,最后取反得到效验和,再返回给调用函数。

//计算校验和

USHORTchecksum(USHORT*buffer,intsize)

{

unsignedlongcksum=0;

while(size>1)

{

cksum+=*buffer++;

size-=sizeof(USHORT);

}

if(size)

{

cksum+=*(UCHAR*)buffer;

}

cksum=(cksum>>16)+(cksum&0xffff);

cksum+=(cksum>>16);

return(USHORT)(~cksum);

}

5.3发送UDP数据包

先调用WSASocket()函数创建sock套接字,再调用setsockopt()函数设置套接字选项,再将UDP、IP头部填充好,最后调用sendto()函数将构造的数据包发送到目的IP地址的扫描的端口。

//发送TCP协议数据

//为了独立性协议的数据结构全部定义在内部

intSendUdpPacket(intPort,char*DestIp)

{……………………………………

if((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET){……………………}

if((Check_Ret=setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&FLAG,sizeof(FLAG)))<0){……………}

…………………填充UDP、IP头部………………

Send_info=sendto(sock,Packet_Buf,ipheader->total_len,0,(structsockaddr*)&DEST_ADDR,sizeof(DEST_ADDR));

closesocket(sock);

return0;

}

5.4接收ICMP数据包

首先定义一个套接字集合,并将其清空,再把读数据的套节字加入到套接字集合中,再通过select()函数检查套节字是否可读:

1.如果没有则返回1给主调函数,表示没有收到返回的ICMP_PORT_UNREACH错误数据报,则说明该端口是打开的。

2.如果有可读的套接字,就再通过FD_ISSET()函数检查需要读取的套接字是否在可读的套接字集合中:

(1)如果可读的套接字中没有需要读取的套接字,则返回1给主调函数,表示没有收到返回的ICMP_PORT_UNREACH错误数据报,则说明该端口是打开的。

(2)如果可读的套接字中有需要读取的套接字,则调用recvfrom()函数从套接口上接收数据,如果没有数据,则说明该套接口不是用来传送数据的,则可以判断为返回的ICMP_PORT_UNREACH错误数据报,则说明该端口是关闭的。

//数据包解析

//数据包解析

intPacketUDPICMPAnalyzer(intPort,char*PacketBuffer)

{

Ip_Header*pIpheader;

intiProtocol,iTTL;

charprotocolstr[100]="\0";

charszSourceIP[16],szDestIP[16];

SOCKADDR_INsaSource,saDest;

pIpheader=(Ip_Header*)PacketBuffer;

HANDLEhCon=GetStdHandle(STD_OUTPUT_HANDLE);

//窗口缓冲区信息

CONSOLE_SCREEN_BUFFER_INFObInfo;

//获取窗口缓冲区信息

GetConsoleScreenBufferInfo(hCon,&bInfo);

iProtocol=pIpheader->Protocol;

//checksourceIP

saSource.sin_addr.s_addr=pIpheader->SourceAddr;

:

:

strcpy(szSourceIP,inet_ntoa(saSource.sin_addr));

//checkdestip

saDest.sin_addr.s_addr=pIpheader->DestinationAddr;

:

:

strcpy(szDestIP,inet_ntoa(saDest.sin_addr));

//ttl

iTTL=pIpheader->TTL;

//计算ip长度

intiIphLen=sizeof(unsignedlong)*(pIpheader->Version_HLen&0x0f);

//判断是否是正确的返回数据包

if(pIpheader->SourceAddr==inet_addr(DestIpAddr))

{

//判断是否是icmp协议数据

if(iProtocol==IPPROTO_ICMP)

{

//icmp头部

Icmp_Header*icmp;

//读取icmp数据

icmp=(Icmp_Header*)(PacketBuffer+sizeof(Ip_Header));

//判断是否是应答

if((icmp->i_type==3)&&(icmp->i_code==3))

{

//确定端口是关闭的

fprintf(output,"Port%dClose\n",Port);

//返回1表示成功

return1;

}

else

{

//端口开放状态未知

fprintf(output,"Port%dUnknown\n",Port);

return1;

}

}

elseif(iProtocol==IPPROTO_UDP)

{

//如果返回的是udp报文,则端口是开放的

fprintf(output,"Port%dOpen\n",Port);

//能够正确判断成功返回

return1;

}

else

{

//既不是icmp数据包又不是udp数据则表示不是想要的数据

//返回错误

return0;

}

}

else

{

//不是正确的返回数据包

return0;

}

//恢复原来的属性

SetConsoleTextAttribute(hCon,bInfo.wAttributes);

return1;

}

6.UDP扫描检测

图3扫描结果图

由于UDP协议是非面向连接的,对UDP端口的探测也就不可能像TCP端口的探测那样依赖于连接建立过程(不能使用telnet这种tcp协议类型命令),这也使得UDP端口扫描的可靠性不高。

所以虽然UDP协议较之TCP协议显得简单,但是对UDP端口的扫描却是相当困难的。

下面具体介绍一下UDP扫描方案:

优点:

可以完成对UDP端口的探测。

缺点:

需要系统管理员的权限。

扫描结果的可靠性不高。

因为当发出一个UDP数据报而没有收到任何的应答时,有可能因为这个UDP端口是开放的,也有可能是因为这个数据报在传输过程中丢失了。

另外,扫描的速度很慢。

原因是在RFC1812的中对ICMP错误报文的生成速度做出了限制。

例如Linux就将ICMP报文的生成速度限制为每4秒钟80个,当超出这个限制的时候,还要暂停1/4秒。

7.心得体会

本设计经过近1个多月的努力,基本满足了一个端口扫描程序的基本要求。

完成后的程序实现了TCPconnect()扫描和UDP扫描功能,TCP扫描支持多线程,能大大加快扫描速度。

能对单个指定的主机进行扫描或扫描指定网段内的主机。

能对指定的端口段内的端口进行逐个扫描,或扫描特定的部分端口号,以避免在不需要了解的端口号上浪费时间。

进度条显示,能方便用户随时知道扫描的进度。

系统设计期间,学习到很多课堂上没有的知识,还积累了很多实践经验,增强了动手能力和解决实际问题的能力。

通过这次的课程设计,对网络编程有了更深入的了解,进一步熟悉了TCP和UDP协议的内容,掌握了TCP、UDP扫描端口的基本原理,学会了运用sock套接字构造UDP数据包并发送,以及如何接收ICMP数据包。

对编程思想有了进一步的体会,养成了一些良好的编程习惯。

系统虽然完成,但还有很多不足之处,希望自己能不断学习和实践,争取以后做得更好。

虽然此软件实现了支持多线程的TCPconnect()扫描功能,和单线程的UDP扫描功能。

但也还有很多不足之处,如扫描功能单一:

不支持TCPSYN扫描、TCPFIN扫描以及IP段扫描等功能,对UDP扫描不支持多线程功能,而且在扫描主机前没有发送ICMP报文去判断主机是否在线,还需要进一步完善。

限于作者知识水平和经验有限,此程序还有许多有待完善和改正的地方,恳请各位老师和读者批评指正。

参考文献

[1]甘刚、闫丽丽、盛志伟、冼进.Linux/UNIX网络编程.中国水利水电出版社.2008年第1版

[2]范建华、胥光辉、张涛等译.TCP/IP详解卷1:

协议.机械工业出版社.2009年第1版

[3]黄维通.VisualC++面向对象与可视化程序设计(第2版).清华大学出版社.2007年第2版

[4]郑莉、董渊、张瑞丰.C++语言程序设计(第3版).清华大学出版社.2004年第3版

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

当前位置:首页 > 幼儿教育 > 幼儿读物

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

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