Qt实现飞秋拦截助手—Mac地址扫描器

前言

准备好了就开干,利用业余时间,开始着手写 飞秋拦截助手,按照Qt:Qt实现飞秋拦截助手—介绍 中的4步骤来走。4步骤中,Mac地址扫描器是第一步,因为网络传输中 最底层协议 就是网卡层,得到了局域网中的所有IP和对应的物理地址 才会有攻击的目标,拦截的对象。后面的ARP欺骗和飞秋消息拦截和飞秋欺骗会在这个基础上添加。

效果

什么都不说,先看看MAC地址扫描器的效果。1.2本机无线网卡,1.6是虚拟机,1.4,1.3是2台手机,1.1是网关。

关于网卡信息

为啥要让用户选择网卡呢?因为一个主机可能有多个网卡,所以上网的网卡不定,给用户选择。本机网卡信息 怎样获取呢?请参考:C/C++:Windows编程—代码获取本地所有网卡信息(网卡描述,IP地址,子网掩码,MAC地址)

关于厂商MAC

这里为了方便知道联网的设备的一些信息,所以加了个网卡厂商,每台联网设备的物理地址的前3个字节 表示的是 生产该网卡的厂商,如何获取呢?http://standards.ieee.org/develop/regauth/oui/oui.txt 这个网站是最新的网卡厂商,这里更新厂商mac,就是从这里去下载厂商列表,然后解析成json文件,从而获取设备的网卡厂商。

关于Mac地址扫描器原理

这个仍然得从协议说起,因为网络协议是人为规定好的,必须遵守。在网络接口层中有一个ARP协议,叫做地址解析协议,比如说A 主机 想要和 C 主机通信,必须知道C主机的物理地址,主机A 就需要 发送一个ARP请求包,发送给C 然后C收到后 会给A回一个ARP应答包 会携带A的物理地址,这样主机A 的ARP缓存中就会存放 主机C的物理地址,下次发送信息的时候后,就会在以太网首部 填写主机C的物理地址,就 可以找到目的主机了。
那么我们给局域网的每个IP都发送一个ARP请求包,那么他们给了应答包了 我们不就得到了所有的IP对应的Mac地址了。
来,我们谈下具体细节了。

ARP报文结构

我们先ARP报文结构

我们代码中当然得按照报文结构进行组包。结构体设置如下:
这里我们字段类型最长的uint16_t是2个字节,刚好我们组包也是偶数个字节,根据字节对齐原理,结构体组包后是42字节。注意的是,我们的以太网的目的地址为二进制全1 表示广播地址,接受的主机 必须无条件接受 并应答,这就是协议 大家必须遵守的。还有字节序问题,2字节及以上才存在字节序问题。

// 以太网首部 12byte
typedef struct _ethhead{// 以太网目地址 6byteuint8_t destEthAddr[6];// 以太网源地址 6byteuint8_t srcEthAddr[6];// 帧类型 2byte ,ARP请求或应答uint16_t frameType;
}EthHead;// ARP请求和应答数据结构 28byte
typedef struct _arpstruct{// 硬件地址类型,1 表示以太网地址uint16_t hardType;// 映射的协议地址类型,0x0800 表示IP地址uint16_t protocolType;// 硬件地址长度uint8_t hardLen;// 协议地址长度uint8_t protocolLen;// 操作字段,ARP请求 1,ARP 应答 2,RARP请求 3,RARP应答 4uint16_t op;// 发送到以太网地址uint8_t srcEthAddr[6];// 发送端IP地址uint8_t srcIpAddr[4];// 目的端以太网地址uint8_t destEthAddr[6];// 目的端IP地址uint8_t destIpAddr[4];
}ArpStruct;// 以太网ARP请求或应答数据包 结构 42byte
typedef struct _arppackage{EthHead ethHead;ArpStruct arpBody;
}ArpPackage;

关于Windows下如何发送ARP报文

Windows API中没有提供接口直接操作网卡层的方法,最底层协议包 操作也只是到 网络层,那么怎么办呢?我也是后面发现Windows API 实现不了 才去找的,使用 WinPcap 库可以实现ARP报文的发送和接受。WinPcap中文技术文档。

关于使用WireShark抓包工具分析

这工具,博主在大学用过,当时觉得好难好难,这次写这个软件,遇到问题了必须分析报文,去用了下,还挺好使的,我们开发肯定不是一下就把报文包 组好然后 就成功的发送了,中间肯定会存在问题,这是需要结合抓包工具配合分析了。下面是成功发送的 ARP报文和ARP应答报文图。

核心代码

发送APR请求报文代码

// 发送ARP报文
void ArpSendThread::run()
{if( this->mAdapterHandle == nullptr){qDebug() << "网卡设备没有开启";return;}char tmp[18] = {0};Utils::macToHexString(this->mMacAddr,tmp);qDebug() <<"begin:" << tmp;// 构造ARP请求包 ,2字节及以上的 存在大小端对齐问题,需要转换为网络字节序ArpPackage package;// 以太网 头部uint64_t ethBroadcastAddr = 0xffffffffffff;// 6字节 以太网 广播地址,局域网主机无条件接受memcpy(package.ethHead.destEthAddr,&ethBroadcastAddr,6);memcpy(package.ethHead.srcEthAddr,this->mMacAddr,6);package.ethHead.frameType = htons(0x0806);memset(tmp,0,18);Utils::macToHexString(this->mMacAddr,tmp);qDebug() <<"origin:" << tmp;memset(tmp,0,18);Utils::macToHexString(package.ethHead.srcEthAddr,tmp);qDebug() <<"now:" << 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(1);memcpy(package.arpBody.srcEthAddr,this->mMacAddr,6);// 硬件厂商 Mac地址 http://standards-oui.ieee.org/oui/oui.txtUtils::htonN(reinterpret_cast<uint8_t*>(&(this->mCurIPAddr)),package.arpBody.srcIpAddr,4);memset(package.arpBody.destEthAddr,0,6);int i = 1;// 往当前局域网中所有IP发送 ARP报文for(uint32_t ipAddr = mNetworkAddr+1; ipAddr < mBroadcastAddr; ipAddr++,i++){if(this->isScan == false)break;if( ipAddr == this->mCurIPAddr)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.destIpAddr,4);int ret = pcap_sendpacket(this->mAdapterHandle,reinterpret_cast<unsigned char*>(&package),42);if( ret != 0){qDebug() << inet_ntoa( addr) << " 发送失败!" ;}emit sendOne(i);Sleep(100);}// 关闭设备pcap_close(this->mAdapterHandle);// arp数据包发送完毕,通知主线程emit sendDone();
}

接受ARP应答报文代码

void ArpAcceptThread::run(){if( this->mAdapterHandle == nullptr){qDebug() << "网卡设备没有开启";return;}int res;struct tm *ltime;char timestr[16];struct pcap_pkthdr *header;const u_char *pkt_data;time_t local_tv_sec;struct bpf_program fcode;QMap<QString,QString> info;// 表达式 (arp[16:2]&0x00010!=0) and (dst host 192.168.1.2)// (arp[6:2]&0x0002!=0) 过滤ARP应答// http://www.ferrisxu.com/WinPcap/html/group__language.html 过滤表达QString exp = QString("(arp[6:2]&0x0002!=0)");// compile the filterif (pcap_compile(this->mAdapterHandle, &fcode, exp.toStdString().c_str() , 1, 0) < 0){qDebug() << "pcap_compile error:" <<  pcap_geterr(this->mAdapterHandle);}// set the filterif (pcap_setfilter(this->mAdapterHandle, &fcode) < 0){qDebug() << "pcap_setfilter error";}// 获取数据包while((res = pcap_next_ex( this->mAdapterHandle, &header, &pkt_data)) >= 0){if( this->isAccept == false)break;if(res == 0)// 超时时间到continue;// 将时间戳转换成可识别的格式local_tv_sec = header->ts.tv_sec;ltime=localtime(&local_tv_sec);strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);fflush(stdout);const ArpPackage *package = reinterpret_cast<const ArpPackage*>(pkt_data);struct in_addr addr ;memcpy(&addr.S_un.S_addr,package->arpBody.srcIpAddr,4);info["ip"] = inet_ntoa(addr);qDebug() << "ip=" << inet_ntoa(addr);// 从视觉上看 macCh已经转为本地字节序char macCh[18] = {0};Utils::macToHexString(package->arpBody.srcEthAddr,macCh);qDebug() << "mac=" << macCh;info["mac"] = QString(macCh);emit acceptArp(info);}if(res == -1){qDebug() << "Error reading the packets: "<< pcap_geterr(this->mAdapterHandle);}emit acceptDone();
}

完整代码

总的代码还是挺多的,需要完整工程的点这里进行下载。

Qt:Qt实现飞秋拦截助手—Mac地址扫描器相关推荐

  1. Qt:Qt实现飞秋拦截助手—ARP攻击

    Qt实现飞秋拦截助手-ARP攻击 前言 继续我们的飞秋拦截助手开发,上篇是Qt:Qt实现飞秋拦截助手-Mac地址扫描器 ,本篇将介绍 如何进行ARP攻击,也叫ARP欺骗. 我们知道本机有个ARP缓存表 ...

  2. Qt:Qt实现飞秋拦截助手—介绍

    Qt实现飞秋拦截助手-介绍 前言 以前看见有人在Linux下面实现过飞秋消息拦截.修改和转发功能,我呢 寻思在Windows平台使用Qt编写一个飞秋拦截工具,能够对飞秋消息进行拦截 转发,飞秋欺骗功能 ...

  3. 一款小巧好用的MAC地址扫描器

    针对局域网任一网段,高速扫描MAC地址并以列表显示. 转载于:https://blog.51cto.com/mycdsee/124210

  4. 【Linux网络编程】原始套接字实例:MAC 地址扫描器

    如果 A (192.168.1.1 )向 B (192.168.1.2 )发送一个数据包,那么需要的条件有 ip.port.使用的协议(TCP/UDP)之外还需要 MAC 地址,因为在以太网数据包中 ...

  5. Linux 网络编程——原始套接字实例:MAC 地址扫描器

    如果 A (192.168.1.1 )向 B (192.168.1.2 )发送一个数据包,那么需要的条件有 ip.port.使用的协议(TCP/UDP)之外还需要 MAC 地址,因为在以太网数据包中 ...

  6. 怎么扫描同网段mac地址linux,如何快速收集局域网内的IP+MAC信息?用这个扫描器分分钟搞定!!!...

    原标题:如何快速收集局域网内的IP+MAC信息?用这个扫描器分分钟搞定!!! 网 工 圈 中国圈内 最早的公益 公众号,本号已认证(关注近 5w+) 关注 科来MAC地址扫描器安装 1.右键" ...

  7. 广播的mac地址与我的电脑的mac地址一样的原因,及mac扫描器扫描不全面

    在mac扫描器这里我遇到了个很疑惑的问题,我用mac地址扫描器扫描我的电脑所在的网段,电脑连的wifi此时有三台手机和一台电脑,需要四个ip地址,在加上路由器要一个地址,所以总共是5太设备5个ip地址 ...

  8. QT获取本机的IP地址、mac地址、mask地址和广播IP(Ubuntu QT环境下实现)

    1.简介 用QT做网络通讯数据传输时,要先获取本机的网卡的IP地址.mac地址.mask地址和广播IP,以便创建socket进行通讯数据传输. 2.本博文主要封装函数: (1).getIP():获取本 ...

  9. QT实现CSDN上传资源管理助手Demo之(3)请求上传资源页面并解析

    欢迎关注公众号可以查看更多完整文章 QT实现CSDN上传资源管理助手Demo之(3)请求上传资源页面并解析 请求自己上传的资源页面,只需要请求http://download.csdn.net/my/u ...

最新文章

  1. 获取点击的键盘的keyCode
  2. python 3.0内置函数map、filter
  3. REUSE_ALV_GRID_DISPLAY事件子过程和cl_gui_grid类的事件对应关系
  4. 讲讲OC曲线是什么?
  5. 213. 打家劫舍 II golang 动态规划
  6. Hive分析窗口函数 NTILE,ROW_NUMBER,RANK,DENSE_RANK
  7. idea for循环快捷键_IDEA骚技巧,编码速度至少快一倍
  8. 【C语言】C语言Code的编译与执行
  9. 架构设计 | 分布式事务①概念简介和基础理论
  10. COM.MYSQL.JDBC.DRIVER 和 COM.MYSQL.CJ.JDBC.DRIVER的区别
  11. 建议检察院服务器服务器配置 显示器,切换器 键鼠
  12. 国内外cms网站大全
  13. Excel中怎么添加批注
  14. Kibana关联ES查询数据
  15. iPhone和iPad适配
  16. C语言——计算当前日期前/后N天的日期
  17. EfficientNet介绍
  18. linux 下安装apache 快速教程
  19. nodejs获取本地IP地址
  20. python 对数收益率_用python进行风险调整后的收益

热门文章

  1. Retouch Pro for Mac(ps图像修饰插件)支持ps 2021
  2. Mac如何快速导出保存Pages文档里的图片
  3. 中小学python、人工智能书籍(2022.02.02)
  4. java生成j动态页面_zk动态产生多个页面的例子代码
  5. python爱因斯坦的问题_爱因斯坦的思考题.py
  6. Tampermonkey笔记-脚本的搭建和基本使用
  7. Spring Boot中配置嵌入式Servlet容器修改配置
  8. Qt多线程端口扫描工具(开源)
  9. 前端笔记-使用JavaScript防止空表单提交
  10. MySQL入门之访问控制与安全