基于主机的扫描器一般由电脑主机几个部分组成成

WinPcap开发(二):扫描探测
*本文原创作者:追影人
0&01 “主机发现”原理
0&02 基于ARP的主机发现
0&03基于ICMP的主机发现
0&04 端口扫描的原理
0&05 基于connect的端口扫描
0&06 基于SYN、FIN的端口扫描
0&08总结与预告
在上一章节,我们学习了winpcap入门知识,基本环境的搭建与基础程序的编写,本章我们将继续深入探索winpcap在各种应用场景下的强大魅力。本章节将详细介绍利用winpcap进行网络节点存活性探测及端口开放状态扫描的“姿势”。
0&01 主机发现”原理
网络节点存活性探测,又称“主机发现”,其目的在于确定目标主机是否在线。网络管理员通常使用其维护网络,确定网络中主机的通联状况,及时发现掉线或宕机的机器;而渗透测试人员则利用其确定目标网络拓扑及在线主机,根据绘制的在线网络拓扑进行渗透测试,如端口扫描、系统探测等,从而避免发送大量探测包到不在线的主机,提高探测效率。
通常我们都会使用系统自带的ping程序进行主机存活性探测。
使用wireshark进行抓包可以看出其使用的是ICMP协议
ICMP是(Internet Control Message
Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
从上图可以看出ICMP是在IP协议头后,但是需要注意,该协议是TCP/IP协议集中的一个子协议,属于网络层协议,也就是和IP协议属于同一层,并不是和TCP/UDP一样具有端口。从抓包数据可以看出,向目标主机发送ICMP
request请求包,目标主机收到后会进行reply回复。
有些同学会说,我用ping是下面这个样子。
这种情况的原因很可能是下列几种(排名分先后顺序):
1.目标主机不在线
2.本地主机与目标主机之间不通联
3.目标主机开启的防火墙过滤了ICMP协议
4.本地主机不在线
5.数据包被外星人抓走了。。。
6.。。。。。。。。。。。。。。。。。。。。。。
需要注意的是,windows防火墙在默认配置情况下开启,只会过滤request请求包的接收,所以本地主机的防火墙开启后不会影响到存活性探测。
0&02 基于ARP的主机发现
在介绍基于ICMP主机发现技术之前,先来回顾一下,在上一章节中我们介绍了ARP数据包的发送。
可以发现,我们可以利用ARP协议进行主机发现,针对目标主机IP广播ARP查询包,如果目标主机在线则会响应。
优点:防火墙不会对此进行过滤
缺点:ARP广播包不能跨网段,则该主机发现方法只适用于局域网内部
此处我们所用的代码依旧来源于ARPSPOOF源码,其中函数EnumLanHost(argv[2],
argv[3])用于局域网的ARP广播,该处调用了iphlpapi.dll中SendARP函数进行广播包的发送。关键代码如下:
// 网段内主机信息双向链表
typedef struct _LAN_HOST_INFO {
char IpAddr[4 * 4];
char HostName[25];
unsigned char ucMacAddr[4];
struct _LAN_HOST_INFO *
struct _LAN_HOST_INFO *next;
}LAN_HOST_INFO, *PLAN_HOST_INFO;
// 开始进行多线程ARP扫描,创建uHostNum个线程扫描
// 扫描端口范围 1 ~ uHostNum
for (i = 0, uHostByte ++; i & uHostN i ++, uHostByte ++)
// 构造IP地址
memset(TempIpAddr, 0, strlen(TempIpAddr));
sprintf(TempIpAddr, "%d.%d.%d.%d",&
(uHostByte & 0xff000000) && 0x18,
(uHostByte & 0x00ff0000) && 0x10,
(uHostByte & 0x0000ff00) && 0x08,
(uHostByte & 0x000000ff));
// 构造链表
pNextHostInfo = (PLAN_HOST_INFO) malloc(sizeof(LAN_HOST_INFO));
memset(pNextHostInfo, 0, sizeof(LAN_HOST_INFO));
memcpy(pLanHostInfo-&IpAddr, TempIpAddr, sizeof(TempIpAddr));
pLanHostInfo-&next = pNextHostI
pNextHostInfo-&prev = pLanHostI
pNextHostInfo-&next = NULL;
if ((hThread[i]=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) scan_lan,&
pLanHostInfo, 0, &dwThreadID))==NULL)
printf("[!] Create thread error! IP is %s\n",TempIpAddr);
pLanHostInfo = pLanHostInfo-&next;
Sleep(2); // 等待参数传递完毕,再重新赋值
// 等待线程返回,退出函数
WaitForMultipleObjects(uHostNum,hThread,TRUE,-1);
可以看到代码中为了加快发送速度,使用了多线程技术。
测试结果:
可以看到,扫描了192.168.0.1/24网段,共消耗了3982ms,一共发现11台主机,除去自身,共10台主机存活。下面我们再来看看ICMP的战绩。
0&03 基于ICMP的主机发现
在0&01节中,已经介绍了ICMP主机发现的基本原理,现利用这一原理进行实验测试。
优点:不局限与局域网,可探测任意可达网络内的主机
缺点:防火墙会针对ICMP协议进行过滤
为了与基于ARP的主机发现测试进行时间对比,此次测试我们同样扫描192.168.0.1/24网段程序原理:
调用winpcap针对网内所有IP地址发送ICMP request包,同时进行数据包的接收,筛选出ICMP
reply包,凡是有reply包的IP地址即为存活主机IP。
关键代码:
// 打开网卡
if ((adhandle = OpenAdapter(0, szIPSelf, ucSelf, szIPGate)) == NULL)
printf("[!] Open adatper error!\n");
return FALSE;
DWORD dwThreadID; // 线程ID
HANDLE hT //该线程用于ICMP的接收
if ((hThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) revICMPData,adhandle, 0, &dwThreadID))==NULL)
printf("[!] Create thread error! \n");
ICMPScan(adhandle);//该函数用于发送ICMP request探测包
WaitForSingleObject(hThread,INFINITE);//等待hThread线程终止
发送ICMP request包的关键代码
pcap_t *adhandle = (pcap_t *)p;
u_char ucFrame[ICMP_LEN];
//设置Ethernet头
ETHeader eh = { 0 };
memset(eh.dhost,0xff, 6);//目的MAC
memcpy(eh.shost, ucSelf, 6);//源MAC
eh.type = htons(ETHERTYPE_IP);//下层协议类型
memcpy(ucFrame, &eh, sizeof(eh));//将设置好的Ethernet头进行填充
//设置IP头
IPHeader ph = { 0 };
ph.iphVerLen=0x45;//版本号和头长度(各占4位)
ph.ipTOS=0;//服务类型&
ph.ipLength=htons(sizeof(IPHeader)+sizeof(ICMPHeader));//封包总长度,即整个IP报的长度
ph.ipID=htons(0x00a3);//封包标识,惟一标识发送的每一个数据报
ph.ipFlags=0;//标志
ph.ipTTL=128;//生存时间,就是TTL
ph.ipProtocol=1;//协议
ph.ipChecksum=0;//校验和置0
ph.ipSource = inet_addr(szIPSelf);//源IP地址
ph.ipDestination = inet_addr("192.168.0.10"); //目的IP地址
ph.ipChecksum=checkicmpsum((USHORT*)&ph,sizeof(IPHeader));//校验和计算
memcpy(&ucFrame[sizeof(ETHeader)], &ph, sizeof(ph));//将设置好的IP头进行填充
// 设置ICMP头
ICMPHeader ih = { 0 };
ih.i_cksum=0;//校验和置0
memcpy(ih.i_data,"abcdefghijklmnopqrstuvwabcdefghi",32);//填充数据
ih.i_seq=htons(0x0028);//序列号
ih.i_id =htons(1);//id
ih.i_code = 0;//代码
ih.i_type=8;//ICMP类型
ih.i_cksum= checkicmpsum((USHORT*)&ih, sizeof(ICMPHeader));//校验和计算
memcpy(&ucFrame[sizeof(ETHeader)+sizeof(IPHeader)], &ih, sizeof(ih));//填充
char IPbuf[20]={0};
//针对192.168.0.1/24网段内的所有IP地址进行探测
for(int i=1; i&&span class="hljs-number"&255 ; i++)
sprintf(IPbuf,"192.168.0.%d",i);
ph.ipDestination = inet_addr(IPbuf);&
ph.ipChecksum=0;
ph.ipChecksum=checkicmpsum((USHORT*)&ph,sizeof(IPHeader));
memcpy(&ucFrame[sizeof(ETHeader)], &ph, sizeof(ph));
if(pcap_sendpacket(adhandle, (const unsigned char *) ucFrame,ICMP_LEN) & 0)
printf("Send Packet Error\n");
从代码中可以看到,并未采用多线程来发送探测包,那此次测试与上一节的测试相比,会有优势吗?
测试结果:
82ms!!!!是的,你没有看错,完全秒杀上一节的测试。为了排除程序的不稳定性造成的时间误差,下面是两测试的五次实验时间的对比:
从上图可以清晰看出基于ARP的测试虽然采用多线程技术,但耗费时间依旧明显过长,经过对代码的分析,发现原因在于,基于ARP的测试虽然针对每个IP都开启一个线程进行请求,但是SendARP函数属于堵塞式函数,即需要得到回复结果或者超时才会返回,这意味着在探测不在线的主机时,需要等到函数超时才能返回,根据时间结果我们可以猜测到其函数超时限制大概在4秒。
而基于ICMP的测试,虽然只是利用1个线程在发送探测包,但是由于pcap_sendpacket发送函数不需要等待,所以瞬间会完全本网段数据包的发送,而在线主机在接收到数据包后也会立即作出响应,而使得接收数据包的函数快速捕获到ICMP
reply包。可以看出整个过程数据异步工作模式,极大提升效率。
0&04 &端口扫描的原理
在确定存活主机后,针对端口状态的探测也是一项重要工作,网络管理员可以根据端口开放状况确定对应的服务是否在正常运转,渗透测试员可根据主机的端口开发状况计划下一步的渗透计划。
本地利用Netstat程序可以列出端口开放状况
而针对远程主机的端口则需要从网络协议的角度出发,发送相关的探测数据包,根据响应确定端口状态。
熟悉socket编程的同学,在进行连接时均调用connect函数来建立TCP连接,下图为一次典型的TCP连接的建立和断开过程。
根据上图可以看出,如果端口处于开放,则在接收到连接请求后,会进行三次握手来建立连接,而端口关闭的话,则不会发送SYN/ACK确认包。根据这一特性,我们进行下面的实验测试。
0&05 &基于connect的端口扫描
利用套接字的connect函数,我们可以方便的确定端口是否开放。
关键代码:
&SOCKADDR_IN addrS
& & addrServ.sin_family=AF_INET;
& & addrServ.sin_addr.S_un.S_addr=inet_addr(szSelfIP);
addrServ.sin_port=htons(_port);
SOCKET sClient = NULL;
&if (sClient == NULL)
& & & & & & //创建套接字
& & & & & & sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
& & & & & & if(sClient==INVALID_SOCKET)
& & & & & & {
& & & & & & & & cout&&"创建客户端socket失败!"&&
& & & & & & & & return ;
& & & & & & }
//连接服务器
if(connect(sClient,(sockaddr *)&addrServ,sizeof(sockaddr))==SOCKET_ERROR)
//cout&&"port "&&ntohs(addrServ.sin_port)&&" is not open!"&&
& //closesocket(sClient);
//return 1;
cout&&"port "&&ntohs(addrServ.sin_port)&&" open on host!"&&
closesocket(sClient);
sClient = NULL;
先选用单线程进行扫描,即扫描完一个端口后再进行下一个端口的扫描。
在经过半分钟后,笔者已被这龟速深深伤害,毫不犹豫Ctrl+C结束了它的使命。上图可以看出,connect探测一个端口需要消耗1秒左右的时间,而端口的范围是0-65535,这样扫下去需要65535秒,也就是18小时!!!
为了加快速度,我们采用多线程技术进行测试,测试的端口范围0-1000
关键代码:
& & //初始化Windows Sockets 动态库
HANDLE *hT // 线程数组指针
DWORD dwThreadID; // 线程ID
int uPortNum = 1000;
& & WSADATA wsaD
& & if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
& & & & cout&&"找不到可使用的WinSock dll!"&&
& & & & return 1;
hThread = (HANDLE *)malloc(sizeof(HANDLE) * uPortNum);
int *lPort= (int *)malloc(sizeof(int) * uPortNum);
& & for (int _port = 0;_port
lPort[_port]=_
if ((hThread[_port]=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) connect_scan,&
&lPort[_port], 0, &dwThreadID))==NULL)
printf("[!] Create thread error! \n");
// 等待线程返回,退出函数
SyncWaitForMultipleObjs(hThread,uPortNum);
printf("finished! \n");
从实验结果可以看到,虽然采用了多线程技术,但是扫描1000个端口是速度依旧比较慢,耗费了15秒,这样的扫描速度对于大规模的网络探测依旧不够理想。此处的时间耗费和ARP实验类似,connect函数也属于阻塞函数,需要建立完整的连接或等待超时才可返回。
优点:直接调用winsock库套接字函数,开发方便
缺点:由于建立连接需要完成三次握手,则耗费时间久,数据量大,而且会被防火墙记录
0&06 &基于SYN、FIN的端口扫描
针对connect扫描的缺陷,可简化三次握手的步骤,直接发送SYN包进行探测,根据目标端口是否回复SYN/ACK确认包来判断端口的开放状况,这样会大大替身扫描速度,而且没有建立完整的三次握手,不会被防火墙进行记录。由于只是进行了建立连接的前半部分,所以SYN扫描又称“半开放式扫描”。
下图是目标端口80开放时,探测包的回应状况。
而对于未开放的端口,会收到RST/ACK的响应包断开连接。
SYN端口扫描关键代码:
//SYN探测包构建函数
unsigned char* BuildSYN(WORD dst_port)
static struct ip_s_packet syn_
static struct ps_s_tcp fake_
//以太网帧头
memcpy(syn_packet.eth.source_mac,szSelfmac,6); //本机mac
memcpy(syn_packet.eth.dest_mac,szdestmac,6);//目标mac
syn_packet.eth.eh_type = htons(0x0800);//协议类型,ip
syn_packet.ip.ver_ihl = 0x45; //协议版本及头长
syn_packet.ip.tos = 0x00;//服务类型
syn_packet.ip.tlen = htons(0x002c);//总长度
syn_packet.ip.identification = 123; & //标识
syn_packet.ip.flags_fo = 0x0000; //标志位,段偏移
syn_packet.ip.ttl = 128;
syn_packet.ip.proto = 0x06;
syn_packet.ip.crc = htons(0x0000);
syn_packet.ip.src_addr = &inet_addr(szSelfIP); &//源ip
syn_packet.ip.dst_addr = inet_addr(szDestIP);&
syn_packet.ip.crc = htons(IPcheck((unsigned char*)&syn_packet.ip));//ip头部校验和
srand(time(NULL));
syn_packet.tcp.s_port = htons(rand()e535);//源端口
syn_packet.tcp.d_port = htons(dst_port);//目标端口
syn_packet.tcp.sn = htonl(rand()e535);//序列号
syn_packet.tcp.an = 0; //确认号
syn_packet.tcp.other = htons(0x6002);//头长及六个标识位
syn_packet.tcp.window_size = htons(0x0c00);//窗口大小
syn_packet.tcp.check_sum = 0;//tcp校验和
syn_packet.tcp.urgent_pointer = 0;//紧急指针
//tcp伪头部
fake_tcp.source_address = syn_packet.ip.src_
fake_tcp.dest_address = syn_packet.ip.dst_
fake_tcp.placeholder = 0;
fake_tcp.protocol = syn_packet.ip.
fake_tcp.tcp_length = htons(sizeof(syn_packet.tcp));
fake_tcp.tcptou = syn_packet.
syn_packet.tcp.check_sum = TCPcheck((WORD*)&fake_tcp,36);
return (unsigned char*)&syn_
//探测包发送函数
void SYNScanSend(pcap_t * adhandle)
unsigned char *
WORD count = 65535 - 1;
WORD *Buf = Sort(1,65535);//端口生产函数
int i = 0;
while(i&=count) {
packet = BuildSYN(Buf[i]);
pcap_sendpacket(adhandle, packet, 58);
测试结果:
从测试结果可以明显看出,效率极高,扫描65535个端口只耗费了不到3秒。
SYN扫描优点:速度快、安全性强;
细心的同学在进行SYN扫描的时候会发现如下情况:
开放端口会重复发送SYN/ACK确认包,通常会发送3次确认包。这是因为我们并没有进行三次握手的第三个数据包的放松,所以目标端口会认为自己的包未送达,而进行了超时重传。
FIN端口扫描也是利用端口对FIN包的响应判断开放状态。如果发送一个FIN标志的TCP报文到一个关闭的端口,那么应该返回一个RST报文,如果发送到一个开放的端口,那么应该没有任何反应。如果收到ICMP端口不可达错误数据包,则不能确认是否开放或者关闭,把它称为状态未知端口。
关键代码:
//构建FIN包
//dst_port:目标端口
unsigned char* BuildFIN(WORD dst_port)
static struct ip_f_packet fin_
static struct ps_f_tcp fake_
//以太网帧头
memcpy(syn_packet.eth.source_mac,szSelfmac,6); //本机mac
memcpy(syn_packet.eth.dest_mac,szdestmac,6);//目标mac
syn_packet.eth.eh_type = htons(0x0800);//协议类型,ip
fin_packet.ip.ver_ihl = 0x45; //协议版本及头长
fin_packet.ip.tos = 0x00;//服务类型
fin_packet.ip.tlen = htons(0x0028);//总长度
fin_packet.ip.identification = 123; & //标识??????
fin_packet.ip.flags_fo = 0x0000; //标志位,段偏移
fin_packet.ip.ttl = 128;
fin_packet.ip.proto = 0x06;
fin_packet.ip.crc = htons(0x0000);
fin_packet.ip.src_addr = &inet_addr(szSelfIP); & //源ip??????????
fin_packet.ip.dst_addr = inet_addr(szDestIP);&
syn_packet.ip.op_pad 扫描包的ip选项部分为空
fin_packet.ip.crc = htons(IPcheck((unsigned char*)&fin_packet.ip));//ip头部校验和
srand(time(NULL));
fin_packet.tcp.s_port = htons(rand()e535);//源端口
fin_packet.tcp.d_port = htons(dst_port);//目标端口
fin_packet.tcp.sn = htonl(rand()e535);//序列号
fin_packet.tcp.an = 0; //确认号
fin_packet.tcp.other = htons(0x5001);//头长及六个标识位
fin_packet.tcp.window_size = htons(0x0c00);//窗口大小
fin_packet.tcp.check_sum = 0;//tcp校验和
fin_packet.tcp.urgent_pointer = 0x0000;//紧急指针
//tcp伪头部
fake_tcp.source_address = fin_packet.ip.src_
fake_tcp.dest_address = fin_packet.ip.dst_
fake_tcp.placeholder = 0;
fake_tcp.protocol = fin_packet.ip.
fake_tcp.tcp_length = htons(sizeof(fin_packet.tcp));
fake_tcp.tcptou = fin_packet.
fin_packet.tcp.check_sum = TCPcheck((WORD*)&fake_tcp,32);
return (unsigned char*)&fin_
需要注意,在发送FIN探测包后,如果收不到任何回复,并不代表端口一定是打开的,有可能由于网络环境的复杂性,或者防火墙或其他网络过滤设备,阻碍了正常的数据流程。
另外笔者在针对windows系统进行测试时,会发现所有的端口都不进行响应。
该方法是对windows系统无效的,只能针对类Unix操作系统。
除了上述方法外,我们可以充分利用TCP的标志位,进行其他类型的端口扫描,例如TCP ACK扫描、TCP NULL扫描、TCP
Xmas Tree扫描等等,有兴趣的同学可以查阅相关资料完成测试实验。
在进行主机发现过程中,由于受到防火墙等设备的影响,很可能阻断了ICMP包的传输,而影响到探测的准确度,所以有必要利用其他方法来拟补这一缺陷。
大名鼎鼎的Nmap在主机发现中采用的方法是,发送四种数据包探测目标主机是否在线:&
1.ICMPecho request&
2.TCP SYN packet to port 443&
3.TCP ACK packet to port 80&
4.ICMP timestamp request&
这种方法叫做“综合探测法”,结合可端口扫描的方法,对目标进行存活性探测,一定程度上规避了防火墙对测试结果的影响。
在端口扫描时,一次性向目标主机大量发送探测包势必会触发防火墙报警,所以有必要采取一些防范措施,在上面的测试中,探测包的源端口均采用随机数,而目标端口也并没有按照从0到65535进行顺序扫描,而是利用sort函数生存随机端口序列。
WORD* Sort(WORD Begin,WORD End)
WORD count = End - B//Begin:起始端口,End:结束端口,count:扫描的端口数
WORD i ,Temp,R
if(count&&span class="hljs-number"&0) return NULL;
srand(time(NULL));
for(i=0;i&=i++)//将端口号存入数组
buf[i]=Begin+i;
for(i=0;i&=i++)//将原端口位置与随机生成位置调换
Rand = rand()%
Temp = buf[i];
buf[i]=buf[Rand];
buf[Rand]=T
return (WORD *)
针对端口扫描,我们还可以整理一份常用端口列表,先扫描一些常用端口,从而尽快发现所需要的端口信息。在Nmap中,其端口扫描便是这样实现的。
0&08 总结与预告
在本章中,我们结合上一章的入门知识,深入学习了winpcap在扫描探测场景中的应用方法,理解了主机发现和端口扫描的原理,掌握了一些常用发放手段,并提出了优化建议。在下一章中,我们会学习如何利用winpcap进行ARP欺骗和中间人攻击。
*本文原创作者:追影人,本文属FreeBuf原创奖励计划,未经许可禁止转载
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。近几年,车联网一直占据热搜榜居高不下,随着BAT大佬们的……
电力改变了世界,也造福了我们的生产生活。电力安全大于……
近日尼吉康在北京召开了关于锂离子二次电池的新品发布会……
1968年大众在汽车上使用了一个ECU,用于发动机的电子燃油……
以&极致突破创新&为主题,在7月26日的吹田……
演讲人:Jim时间: 10:00:00
演讲人:李思齐时间: 10:00:00
演讲人:张厚新时间: 10:00:00
预算:¥10000预算:¥10000
上海市上海市
漏洞扫描原理及程序
[导读]  1 引言  网络扫描,是基于Internet的、探测远端网络或主机信息的一种技术,也是保证系统和网络安全必不可少的一种手段。主机扫描,是指对计算机主机或者其它网络设备进行安全性检测,以找出安全隐患和系统漏洞
  1 引言本文引用地址:
  网络扫描,是基于Internet的、探测远端网络或主机信息的一种技术,也是保证系统和网络安全必不可少的一种手段。主机扫描,是指对计算机主机或者其它网络设备进行安全性检测,以找出安全隐患和系统漏洞。总体而言,网络扫描和主机扫描都可归入漏洞扫描一类。漏洞扫描本质上是一把双刃剑:黑客利用它来寻找对网络或系统发起攻击的途径,而系统管理员则利用它来有效防范黑客入侵。通过漏洞扫描,扫描者能够发现远端网络或主机的配置信息、 TCP/UDP端口的分配、提供的网络服务、服务器的具体信息等。
  2 漏洞扫描原理
  可以划分为ping扫描、端口扫描、OS探测、脆弱点探测、防火墙扫描五种主要技术,每种技术实现的目标和运用的原理各不相同。按照 TCP/IP协议簇的结构,ping扫描工作在互联网络层:端口扫描、防火墙探测工作在传输层;0S探测、脆弱点探测工作在互联网络层、传输层、应用层。 ping扫描确定目标主机的IP地址,端口扫描探测目标主机所开放的端口,然后基于端口扫描的结果,进行OS探测和脆弱点扫描。
  2.1 Ping扫描
  ping扫描是指侦测主机IP地址的扫描。ping扫描的目的,就是确认目标主机的TCP/IP网络是否联通,即扫描的IP地址是否分配了主机。对没有任何预知信息的黑客而言,ping扫描是进行漏洞扫描及入侵的第一步;对已经了解网络整体IP划分的网络安全人员来讲,也可以借助ping扫描,对主机的IP分配有一个精确的定位。大体上,ping扫描是基于ICMP协议的。其主要思想,就是构造一个ICMP包,发送给目标主机,从得到的响应来进行判断。根据构造ICMP包的不同,分为ECH0扫描和non&ECHO扫描两种。
  2.1.1 ECH0扫描
  向目标IP地址发送一个ICMP ECHOREQUEST(ICMP type 8)的包,等待是否收至UICMP ECHO REPLY(ICMP type 0)。如果收到了ICMP ECHO REPLY,就表示目标IP上存在主机,否则就说明没有主机。值得注意的是,如果目标网络上的防火墙配置为阻止ICMP ECH0流量,ECH0扫描不能真实反映目标IP上是否存在主机。
  此外,如果向广播地址发送ICMPECHO REQUEST,网络中的unix主机会响应该请求,而windows主机不会生成响应,这也可以用来进行OS探测。
  2.1.2 non-ECH0扫描
  向目的IP地址发送一个ICMP TIMESTAMP REQUEST(ICMP type l3),或ICMP ADDRESS MASK REQUEST (ICMP type l7)的包,根据是否收到响应,可以确定目的主机是否存在。当目标网络上的防火墙配置为阻止ICMP ECH0流量时,则可以用non.ECH0扫描来进行主机探测。
  2.2端口扫描
  端口扫描用来探测主机所开放的端口。端口扫描通常只做最简单的端口联通性测试,不做进一步的数据分析,因此比较适合进行大范围的扫描:对指定 IP地址进行某个端口值段的扫描,或者指定端口值对某个IP地址段进行扫描。根据端口扫描使用的协议,分为TCP扫描和UDP扫描。
  2.2.1 TCP扫描
  主机间建立TCP连接分三步(也称三次握手):
  (1)请求端发送一个SYN包,指明打算连接的目的端口。
  (2)观察目的端返回的包:
  返回SYN/ACK包,说明目的端口处于侦听状态;
  返回RST/ACK包,说明目的端口没有侦听,连接重置。
  (3)若返回SYN/ACK包,则请求端向目的端口发送ACK包完成3次握手,TCP连接建立。
  根据TCP连接的建立步骤,TCP扫描主要包含两种方式:
  (1)TCP全连接和半连接扫描
  全连接扫描通过三次握手,与目的主机建立TCP连接,目的主机的log文件中将记录这次连接。而半连接扫描(也称TCP SYN扫描)并不完成TCP三次握手的全过程。扫描者发送SYN包开始三次握手,等待目的主机的响应。如果收到SYN/ACK包,则说明目标端口处于侦听状态,扫描者马上发送RST包,中止三次握手。因为半连接扫描并没有建立TCP连接,目的主机的log文件中可能不会记录此扫描。
  (2)TCP隐蔽扫描
  根据TCP协议,处于关闭状态的端口,在收到探测包时会响应RST包,而处于侦听状态的端口则忽略此探测包。根据探测包中各标志位设置的不同,TCP隐蔽扫描又分为SYN/ACK扫描、FIN扫描、XMAS(圣诞树)扫描和NULL扫描四种。
  SYN/ACK扫描和FIN扫描均绕过TCP三次握手过程的第一步,直接给目的端口发送SYN/ACK包或者FIN包。因为TCP是基于连接的协议,目标主机认为发送方在第一步中应该发送的SYN包没有送出,从而定义这次连接过程错误,会发送一个RST包以重置连接。而这正是扫描者需要的结果& 只要有响应,就说明目标系统存在,且目标端口处于关闭状态。
  XMAS扫描和NULL扫描:这两类扫描正好相反,XMAS扫描设置TCP包中所有标志位(URG、ACK、RST、PSH、SYN、FIN),而NULL扫描则关闭TCP包中的所有标志位。
  2.2.2 UDP端口扫描
  UDP协议是数据包协议,为了要发现正在服务的UDP端口,通常的扫描方式是构造一个内容为空的UDP数据包送往目的端口。若目的端口上有服务正在等待,则目的端口返回错误的消息;若目的端口处于关闭状态,则目的主机返回ICMP端口不可达消息。因为UDP端口扫描软件要计算传输中丢包的数量,所以UDP端口扫描的速度很慢。
  2.3 0S探测
  OS探测有双重目的:一是探测目标主机的0S信息,二是探测提供服务的计算机程序的信息。比如OS探测的结果是:OS是Windows XP sp3,服务器平台是IIS 4.0。
  2.3.1二进制信息探测
  通过登录目标主机,从主机返回的banner中得知OS类型、版本等,这是最简单的0S探测技术。
  图1 二进制信息
  从图l可以看出,在telnet连上FTP服务器后,服务器返回的banner已经提供了server的信息,在执行ftp的syst命令后可得到更具体的信息。
  2.3.2 HTTP响应分析
  在和目标主机建立HTTP连接后,可以分析服务器的响应包得出OS类型。比如响应包中可能包含如下信息:
  图2 响应包分析
  从图2中对响应包中的数据分析,可以得到server的信息。
  2.3.3栈指纹分析
  网络上的主机都会通过TCP/IP或类似的协议栈来互通互联。由于0S开发商不唯一,系统架构多样,甚至是软件版本的差异,都导致了协议栈具体实现上的不同。对错误包的响应,默认值等都可以作为区分0S的依据。
  (1)主动栈指纹探测
  主动栈指纹探测是主动向主机发起连接,并分析收到的响应,从而确定OS类型的技术。
  1)FIN探测。跳过TCP三次握手的顺序,给目标主机发送一个FIN包。RFC793规定,正确的处理是没有响应,但有些OS,如MS Windows,CISC0,HP/UX等会响应一个RST包。
  2)Bogus标志探测。某些OS会设置SYN包中TCP头的未定义位(一般为64或128),而某些0S在收到设置了这些Bogus位的SYN包后,会重置连接。
  3)统计ICMP ERROR报文。RFCl812中规定了ICMP ERROR消息的发送速度。Linux设定了目标不可达消息上限为80个/4秒。0S探测时可以向随机的高端UDP端口大量发包,然后统计收到的目标不可达消息。用此技术进行OS探测时时间会长一些,因为要大量发包,并且还要等待响应,同时也可能出现网络中丢包的情况。
  4)ICMPERROR报文引用。RFC文件中规定,ICMP ERROR消息要引用导致该消息的ICMP消息的部分内容。例如对于端口不可达消息,某些OS返回收到的IP头及后续的8个字节,Solaris返回的 ERROR消息中则引用内容更多一些,而Linux比Solaris还要多。
  (2)被动栈指纹探测
  被动栈指纹探测是在网络中监听,分析系统流量,用默认值来猜测0S类型的技术。
  1)TCP初始化窗口尺寸。通过分析响应中的初始窗口大小来猜测OS的技术比较可靠,因为很多0S的初始窗口尺寸不同。比如AIX设置的初始窗口尺寸是0x3F25,而Windows NT5、OpenBSD、FreeBSD设置的值是0x402E。
  2)Don&t Fragment位。为了增进性能,某些0S在发送的包中设置了DF位,可以从DF位的设置情况中做大概的判断。
  3)TCPISN采样。建立TCP连接时,SYN/ACK中初始序列号ISN的生成存在规律,比如固定不变、随机增加 (Solaris,FreeBSD等),真正的随机(Linux 2.0.*),而Windows使用的是时间相关模型,ISN在每个不同时间段都有固定的增量。
  2.4脆弱点扫描
  从对黑客攻击行为的分析和脆弱点的分类,绝大多数扫描都是针对特定操作系统中特定的网络服务来进行,即针对主机上的特定端口。脆弱点扫描使用的技术主要有基于脆弱点数据库和基于插件两种。
  2.4.1基于脆弱点数据库的扫描
  首先构造扫描的环境模型,对系统中可能存在的脆弱点、过往黑客攻击案例和系统管理员的安全配置进行建模与分析。其次基于分析的结果,生成一套标准的脆弱点数据库及匹配模式。最后由程序基于脆弱点数据库及匹配模式自动进行扫描工作。脆弱点扫描的准确性取决于脆弱点数据库的完整性及有效性。
  2.4.2基于插件的扫描
  插件是由脚本语言编写的子程序模块,扫描程序可以通过调用插件来执行扫描。添加新的功能插件可以使扫描程序增加新的功能,或者增加可扫描脆弱点的类型与数量。也可以升级插件来更新脆弱点的特征信息,从而得到更为准确的结果。插件技术使脆弱点扫描软件的升级维护变得相对简单,而专用脚本语言的使用也简化了编写新插件的编程工作,使弱点扫描软件具有很强的扩展性。
  2.5防火墙规则探测
  采用类似于traceroute的IP数据包分析法,检测能否给位于过滤设备后的主机发送一个特定的包,目的是便于漏洞扫描后的入侵或下次扫描的顺利进行。通过这种扫描,可以探测防火墙上打开或允许通过的端口,并且探测防火墙规则中是否允许带控制信息的包通过,更进一步,可以探测到位于数据包过滤设备后的路由器。
  3 常见漏洞扫描程序
  通常在制定漏洞扫描策略时,扫描者会考虑程序的操作系统、所应用的技术、易用性、准确性等因素。其中,程序的可用性是最重要的,也是最基本的,但是可控性和准确性同样不容忽视。
  3.1 Unix/Linux平台
  3.1.1 hping
  hping支持TCP、UDP、ICMP、RAW-IP多种协议。特点在于能进行ping扫描、端口扫描、0S探测、防火墙探测等多种扫描,并能自定义发送的ICMP/UDP/TCP包到目标地址并且显示响应信息。
  3.1.2 icmpush&icmpquery
  icmpush&icmpquery的特点在于完全应用了ICMP协议,可以定制ICMP包的结构以及种类。扫描者可以用这套工具把目标网络的各个子网全部查找出来,从而可以撇开广播地址而集中扫描某几个特定的子网。
  3.1.3 Xprobe 2
  是专业的端口扫描、OS探测程序。特点在于自身的0S特征数据库详细,进行OS探测的可靠性较好。
  3.1.4 THC-Anap
  OS探测程序。特点在于扫描速度快,扫描结果可靠。
  3.1.5 Whisker
  针对CGI的脆弱点探测程序。应用了多线程、多文件扫描技术,脆弱点数据库更新频繁,对扫描结果自行复核,从而扫描结果可靠性好。
  3.1.6 Nessus
  脆弱点探测程序。应用了主动扫描、高速扫描技术,可设置扫描过程。特点在于支持DMZ区以及多物理分区网络的大范围扫描。
  3.1.7 Firewalk
  防火墙探测程序。使用类似traceroute的技术来分析IP包的响应,从而测定防火墙的访问控制列表和绘制网络拓扑图。
  3.2 Windows平台
  3.2.1 Pinger
  是一个图形化的ping扫描工具。特点在于可以指定要ping的IP地址,以图形的形式显示扫描结果,并保存至文本文件。
  3.2.2 Fport
  是端口扫描程序。特点在于可以把扫描出的端口与使用该端口的程序相匹配,扫描速度快,匹配程度较好。
  3.2.3 SuperScan
  可以进行ping扫描、端口扫描、0S探测,并且白带一个木马端口列表,可以检测目标计算机是否有木马。
  3.2.4 GFILANguard
  脆弱点探测程序。特点在于集成了网络审计、补丁管理功能,可以自动生成网络拓扑图、自动补丁管理。
  上述漏洞扫描程序及特点如表1所示。
  4 结论
  一般而言,综合地应用多种扫描方法或扫描程序可以得到比较满意的结果。但是漏洞扫描从其技术原理上分析,有不可忽视的副作用。比如对大范围的 IP地址或者端口进行某种扫描,反复高速的发出特定的连接请求,所造成的结果就是目标网络及主机上存在大量的连接请求数据包,可以造成网络拥塞,主机无法正常使用,这正是DoS攻击的方法及表现。因此若要防范漏洞扫描以及可能的DoS攻击,要做到以下三点:
  1.在防火墙及过滤设备上采用严格的过滤规则,禁止扫描的数据包进入系统。
  2.主机系统除了必要的网络服务外,禁止其它的网络应用程序。
  3.对于只对内开放的网络服务,更改其提供服务的端口。
  此外,网络扫描时发送的数据或多或少都会含有扫描者自身相关信息,从而也可以抓取扫描时的数据包,对扫描者进行反向追踪,这也是一个值得研究的方向。
这是北京“近十年最宽松的落户政策”!消息在北京创投圈激起了涟漪。这些年,北京几乎聚集了中国数量最多顶尖的创业公司和创投机构,从IDG资本、红杉中国、经纬创投到百度、京东、美团、今日头条….浩浩荡荡数十万人。这一纸新规有望让他们落地生根。......关键字:
你对这些来自东方的程序员有没有一些总结性的看法和观点(比如:他们是否合作,是否能按时提交代码,写出的程序是否有质量?)。依据是什么?......关键字:
程序员们在 StackExchange 上有激烈的讨论,如果偷偷把自己的工作自动化,是不是不道德?......关键字:
据Businessinsider报道,在硅谷中想当一个出色的程序员,意味着与诸多精英面临直接竞争。公司给你开出了丰厚的薪水,免费的大餐,免费司机接送,硅谷的程序员在某种意义上就像是好莱坞的明星。Altay Guvench,曾经是一名程序员的......关键字:
日,一名为Laszlo Hanyecz的程序员用一万个比特币购买了两个披萨。当时一枚比特币价值仅为0.003美分,如今则是9669.27美元。......关键字:
我不算是聪明的人,经历也不算特别成功,但一步一步走来,我认为,我能做到的,你一定也能做到,而且应该还能做得比我更好。......关键字:
你对这些来自东方的程序员有没有一些总结性的看法和观点(比如:他们是否合作,是否能按时提交代码,写出的程序是否有质量?)。依据是什么?......关键字:
我 要 评 论
热门关键词
Cypress面议 | 上海市 浦东新区
Cypress面议 | 上海市 浦东新区
Cypress面议 | 上海市 浦东新区
Cypress面议 | 上海市 浦东新区
Cypress面议 | 上海市 浦东新区

我要回帖

更多关于 计算机结构中接口位于 的文章

 

随机推荐