072_端口扫描与检测技术
1.无需注册登录,支付后按照提示操作即可获取该资料.
2.资料以网页介绍的为准,下载后不会有水印.资料仅供学习参考之用.
密 惠 保
5 检测端口扫描的实现
5.1 检测程序的设计原理
在检测端口扫描程序的设计与开发中,这里首先是采取通过套接字来进行数据包的捕获,再通过解IP包,然后对所解出的TCP包和UDP包分别再进行解包,并记录下到达的端口,以及源IP地址,目的IP地址,目的端口,再设计一种算法,通过算法对数据包进行统计分析,最后设定一个判断发生扫描行为的条件,当满足条件有三次及三次以上的相同源IP且到达端口的不同的数据包即判断发生端口扫描行为。
此检测端口扫描程序的设计不但可以检测一般的扫描和快速扫描,在一定的程度上也能检测慢速扫描。
以前的端口扫描检测方法都是采用在一个固定的时间窗T内查看从同一个源地址发起的连接数X , 如果X 超出了设定的阀值, 则判断为一次扫描。由于网络上的通信量非常大, 所以以前的端口扫描方法都会设定一个很小的时间窗T ,防止消耗掉过多的内存和CPU时间。由于本文提出的方法与时间窗无关, 所以在不降低系统整体性能的前提下,在慢速扫描发送探测性数据包时间间隔上不超出所设计程序所能记录数据包的最大上限的情况下仍能很好的检测慢速扫描。
【买计算机毕业论文就到计算机毕业论文网】 本文来自think58 [来源:http://www.think58.com]
5.2 程序流程图
如下图5所示,所开发的检测端口扫描程序基本流程图:
本文来自think58
[版权所有:http://think58.com]
[资料来源:www.THINK58.com]
图5 端口检测流程图
5.3 设计实现重点代码
在此端口扫描检测程序设计中,重点在于设计一个算法,用于研究是否存在端口扫描行为,算法是此设计的重点。
就此设计的检测程序来说,在捕获数据包后所解的TCP包和UDP包,由于在分析中要分别考虑TCP包和UDP包,但是对两种包的分析都是一样的,现我们只详细阐述分析TCP包的情况。
在所设计用于检测端口扫描的算法中,首先是一个统计函数,用于对通过套接字捕获数据包的统计:
void statistics(char szProtocol[],char szSourceIP[],int iSourcePort,char szDestIP[])
{ if(strcmp(szProtocol,"TCP"))
{
if(TCP_MAX==MAX_LEN_REC)
TCP_MAX=0;
if(TCP_MAX==0)
{ strcpy(TCP_REC[TCP_MAX].szProtocol,szProtocol); strcpy(TCP_REC[TCP_MAX].szSourceIP,szSourceIP); TCP_REC[TCP_MAX].iSourcePort=iSourcePort; strcpy(TCP_REC[TCP_MAX].szDestIP,szDestIP);
++TCP_MAX;
}else if(check(TCP_REC,szDestIP,iSourcePort,TCP_MAX-1)) //调用check函数
{
strcpy(TCP_REC[TCP_MAX].szProtocol,szProtocol); strcpy(TCP_REC[TCP_MAX].szSourceIP,szSourceIP); TCP_REC[TCP_MAX].iSourcePort=iSourcePort; strcpy(TCP_REC[TCP_MAX].szDestIP,szDestIP); think58
++TCP_MAX;
在统计的时候这里需要调用一个check函数即检测函数,此函数的作用是用于排除完全相同的数据包,由于在分析中不需要对完全相同的数据包进行分析,以免出现重复情况产生误判,所以在统计时候这里需要先把完全相同的数据包进行排除,以保证存入TCP_REC[]中的数据包是完全没有任何是一个是相同的。
bool check(STATISTIC TYPE[],char szDestIP[],int port,int count) //check函数,比较协议类型,目的IP,端口,计数(count)
{
int i=0; bool flag=true;
for(i=count;i>=0;i--)
{
if(!strcmp(TYPE[i].szDestIP,szDestIP)&&TYPE[i].iSourcePort==port) //比较TYPE[i].szDestIP与szDestIP的值在和TYPE[i].iSourcePort//的值做与运算,将得到的结果和port比较,是否相等
{
flag=false;
break;
}
}
return flag;
}
对所捕获的数据包进行统计后,接着是对所捕获的TCP包以及UDP数据包进行分析的分析函数,首先是一个用于存放不同IP的 rec[],在这里我们用到一个临时变量temp,用于帮助对不同IP的提取,最后再根据所记录的不同IP到TCP_REC[]中进行提取符合IP的数据包信息,再存入tcp_tem[]中,在tcp_tem[]中就是经过统计分析后的所捕获的探测性数据包。 内容来自think58
[资料来源:http://www.THINK58.com]
void analysis_tcp(STATISTIC tcp[])//对IP,端口进行分析的函数,判定是否为端口扫描行为
{
STATISTIC tcp_tem[MAX_LEN_REC],rec[MAX_LEN_REC],temp;
int i=0;int count=0,reccount=0;
strcpy(temp.szProtocol,tcp[0].szProtocol);
strcpy(temp.szSourceIP,tcp[0].szSourceIP);
temp.iSourcePort=tcp[0].iSourcePort;
strcpy(temp.szDestIP,tcp[0].szDestIP);
//临时变量记录第一条数据包的情况
strcpy(rec[reccount].szProtocol,tcp[0].szProtocol);
strcpy(rec[reccount].szSourceIP,tcp[0].szSourceIP);
rec[reccount].iSourcePort=tcp[0].iSourcePort;
strcpy(rec[reccount].szDestIP,tcp[0].szDestIP);
//将第一条记录保存到地址列表中
for(i=0;i<TCP_MAX;i++) //进入for循环,i=0,i小于TCP_MAX的值,i加1
{
if(strcmp(temp.szDestIP,tcp[i].szDestIP))//如果临时变量的地址和当前的地址不相同时
{
int t=0;bool flag=true;
strcpy(temp.szProtocol,tcp[i].szProtocol);
strcpy(temp.szSourceIP,tcp[i].szSourceIP);
temp.iSourcePort=tcp[i].iSourcePort;
内容来自think58 [资料来源:http://think58.com]
strcpy(temp.szDestIP,tcp[i].szDestIP);
//将该地址记录到临时变量
for(t=reccount;t>=0;t--) //进入for循环,将reccount的值赋给t,t大于等于0,t的值减1
{
if(!strcmp(temp.szDestIP,rec[t].szDestIP))
{
flag=false;
break;
}
}//反向搜索地址记录表如果有相同的则不记录
if(flag)
{
++reccount;
strcpy(rec[reccount].szProtocol,temp.szProtocol);
strcpy(rec[reccount].szSourceIP,temp.szSourceIP);
rec[reccount].iSourcePort,temp.iSourcePort;
strcpy(rec[reccount].szDestIP,temp.szDestIP);
//没有相同的则将该不同的地址记录到数组中
}
}//if条件判断
//如果相同则不记录
}//for循环
system("cls");
printf("\nTCP_REC 中的数据是:\n");
for(i=0;i<TCP_MAX;i++)
printf("%s:%d\n",TCP_REC[i].szDestIP,TCP_REC[i].iSourcePort);
for(i=0;i<=reccount;i++)
{
int j=0;count=0;
memset(tcp_tem,0,100*sizeof(STATISTIC));
for(j;j<TCP_MAX;j++) think58好,好think58
{
if(!strcmp(rec[i].szDestIP,tcp[j].szDestIP))
{
strcpy(tcp_tem[count].szProtocol,tcp[j].szProtocol);
strcpy(tcp_tem[count].szSourceIP,tcp[j].szSourceIP);
tcp_tem[count].iSourcePort=tcp[j].iSourcePort;
strcpy(tcp_tem[count].szDestIP,tcp[j].szDestIP);
++count;
}
在程序的最后,由于此设计是需要判断是否发生端口扫描行为,这里就需要设定一个条件来定义端口扫描行为。
在此设计中,我们定义扫描行为是当有3个或3个以上的探测性数据包且其源IP一致的数据包存在的时候就判断为端口扫描行为,当然在这里能够定义更多或者更少的探测性数据包为发生端口扫描行为条件,只要检测程序在当记录到有3个或3个以上的数据包且源IP一致的数据包对本机进行连接的时候能显示出来所发出的探测性数据包并判断为存在端口扫描行为,并显示出扫描者的IP信息以及对本机所扫描的端口。
此检测端口扫描程序设计对一般的以及快速扫描均能很好的扫描,在一定程度上能很好的检测慢速扫描,虽然并没有设定时间阈值,不会存在当设定的时间阈值大到一定程度时,需要从相当长时间的网络连接记录中找出扫描行为,系统资源消耗较大,无法适应宽带网络尤其是高速网络环境;但是毕竟所分析的数据包有个定量,扫描者总能以略大于系统设定数据包捕获定量的时间间隔进行端口扫描,所以说针对慢速扫描只能在一定程度上实现。 内容来自think58
内容来自think58
[资料来源:http://www.THINK58.com]