【C#】浅析通过QQ电话获取目标IP地址

发布于 2024-02-03  3041 次阅读


使用的软件:

  • VisualStudio

使用的编程语言

  • C#

文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用

任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!


前言

其实很早之前应该就有很多人出过诸如“QQ获取对方IP”等等的文章,利用Wireshark抓包实现等等。在很久之前已经尝试过是个可行的办法,我猜测QQ电话也是使用类似打洞的方式进行数据传输,类似的软件还有TG电报、WX等等,使用同样方式的软件均可以使用上述方式抓包获得对方的IP。

本文不会过多赘述Wireshark如何实现获取IP这一过程,网上有太多文章做过解释。

只借次为题,重点尝试使用C#调用SharpPcap实现抓包和处理,获取对方的IP地址,并简单介绍一下QQ电话使用UDP协议发送的数据包结构,以重新复习C#和SharpPcap的使用方式,以及对wireshark数据包进行浅析。


1.使用Wireshark抓包浅析数据包结构

打开wireshark监听目标网卡,并向目标发出电话请求,可以看到捕获的长度为114byte的UDP协议数据包(Source为本机地址,Destination为目标地址)

需要注意,对方可以不接通本次电话,但需要目标在线,也就是需要对方能够响铃

点击单个数据包,大致可以分为以下四个部分,共同构成了114byte的数据包

以太帧:14byte

IPV4协议包:20byte

UDP协议包:8byte + UDP数据包 72byte

以太帧

简单解释一下以太帧

以太网上的其他网络适配器需要接收到以太帧,检查其中的目的地址。如果目的地址与网络适配器的地址相匹配,适配器软件就会处理接收到的帧,把数据传递给协议栈中较高的层。

结构如下

IPV4协议包

IPV4协议包中含有源IP地址和目标IP地址,我们一会儿就需要用到SharpPcap从IPV4协议包中获取Destination Address中的目标IP地址。

结构内容大致如下

Version: 4 //IP协议版本:4
Header Length: 20 bytes //头部长度:20byte
Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT) //服务类型:0x00
Total Length: 100 //总长度:100byte
Identification: 0x5884 (22660) //标识符:0x5884
Flags: 0x00 //标志:0x00
Time to live: 128 //存活时间:1218
Protocol: UDP(17) //协议类型:UDP 可以注意以下,UDP协议字段为17、TCP为6,还有诸如ICMP为1等

Source: 192.168.2.4 //源IP地址
Destination: 223.***.***.*** //目标IP地址

UDP协议数据包

最后是UDP协议数据包

UDP数据包结构分为两个主要部分:伪首部、数据

需要注意一下,目标IP地址只存在于IP协议包中,也就是在网络层中获取,二不是在UDP、TCP等传输层中。

2.代码部分

先在NuGet中安装SharpPcap,然后引入命名空间

using SharpPcap;
using SharpPcap.LibPcap;
using PacketDotNet;

获取本机网卡,选择正确的网卡启动监听,我当前的网卡是WLAN,也就是编号为4的网卡。所以只要获取devices[4],此处调试输出一下即可

var devices = LibPcapLiveDeviceList.Instance;
var device = devices[4];

设置网卡过滤模式

string filter = "udp";
device.Filter = filter;

此处filter使用的是libpcap过滤器语法,只获取UDP协议的数据包。

我觉得这里可以详细展开来说一说

libpcap过滤器语法:
首先你可以使用协议关键字来确定过滤的协议
如:
  1."tcp":匹配TCP协议的数据包。
  2."udp":匹配UDP协议的数据包。
  3."icmp":匹配ICMP协议的数据包。
其次如何过滤源IP和目标IP呢?
使用host关键字来获取IP,同时使用src和dst来表示源和目标的IP
如:
  1."src host 192.168.0.1":匹配源IP地址为192.168.0.1的数据包。
  2."dst host 10.0.0.1":匹配目标IP地址为10.0.0.1的数据包。
那么端口呢
我们刚刚有说host关键字是IP,那自然port关键字就是端口。所以同上
  1."src port 80":匹配源端口号为80的数据包。
  2."dst port 443":匹配目标端口号为443的数据包。
逻辑运算符
  1."and":用于组合多个条件,表示同时满足多个条件。
  2."or":用于组合多个条件,表示满足其中任意一个条件。
  3."not":用于否定一个条件,表示不满足该条件。
举个例子
  1."tcp and port 80":匹配TCP协议且目标或源端口号为80的数据包。
  2."udp and src host 192.168.0.1":匹配UDP协议且源IP地址为192.168.0.1的数据包。
  3."icmp or dst host 10.0.0.1":匹配ICMP协议或目标IP地址为10.0.0.1的数据包。

最后注册一个委托事件,让抓到包之后通过这个事件来执行操作

device.OnPacketArrival += new PacketArrivalEventHandler(PacketHandler);
device.StartCapture();

具体的内容我们就可以在PacketHandler函数中完成

我们的目的是获取目标的IP即可,上文说过目标IP存在于IPV4协议包中

var ent = EthernetPacket.ParsePacket(LinkLayers.Ethernet, e.Packet.Data);//获取以太帧
var ip = ent.PayloadPacket;//获取IP协议包
var udp = ip.PayloadPacket;//获取UDP协议包
var data_len = udp.PayloadData.Length;//读取UDP数据包Data的长度

通过正则过滤获得目标IP

Match match = Regex.Match(ip.ToString(), @"DestinationAddress=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})");
string DestinationAddress = match.Groups[1].Value;
Console.WriteLine("已捕获目标IP:" + DestinationAddress);

最后拿到IP还不行,因为我们此时只是获取了所有UDP数据包中的目标IP地址,怎么判断是不是QQ电话的数据包呢?

可以通过判断IPV4数据包长度:100

也可以通过判断UDP协议数据包长度:72

通常QQ电话中的UDP数据包长度是固定的,所以判断UDP协议数据包长度可信度会更高一些

if (data_len == 72 && !DestinationAddress.Contains("192.168"))
{
    Console.WriteLine("已捕获目标IP:" + DestinationAddress);
}

最终完成获取