使用Wireshark抓包

前言

在正式开始本文前先来一段废话.

工作中经常会使用到自己没有接触过的技术, 而后不断的百度, 谷歌查询, 不断的摸索最终找到解决自己遇到的难题的解决方案. 每次都想写一些总结分享一下, 但是总觉得自己文笔不佳, 而相关技术的文章网络上多不胜数, 也不缺自己写的, 所以到最后总是不了了之

几个月后回头看一看自己做过的项目, 用过的技术, 觉得又熟悉又陌生, 用过却忘记了.

偶然听同事说的一句话很受感触: 写文章写总结并不一定要写的多好, 更重要的是将自己遇到过的难题以及解决方案分享, 这样当别的 IT Guys在遇到相同难题时, 能快速的定位和解决, 提高工作效率, 这才是分享精神. 想一下: 遇到个bug, 错误的时候, 还不是从其他伙伴的总结, 笔记里一个个方案摸索尝试, 最后解决问题的呢?

以上总结一句话就是: 写得不好, 不要吐槽我; 没帮上你, 别骂我

说明

  1. 本文是讲解如何以小白的姿势, 学习使用wireshark抓包, 本人是刚入门wireshark的使用, 想更深入了解的请自行查询其他资料;

  2. 本文重点讲解的是Wireshark的一些简单操作, 例如:

  • 如何抓取指定网络的数据包
  • 如果编写过滤表达式
  • 如何分析抓取到的数据
  1. 本文讲解如何抓取TCP和UDP协议的数据包; 使用电脑端和手机端互发消息, 然后抓取它们之间数据, 手机和电脑处于同一网段下(连着同一个路由器);
  • 电脑端使用Java编写的小程序, 用cmd 窗口做输入输出交互
  • 手机端使用安卓手机
  1. 本文演示的环境是Windows操作系统

软件安装

  1. 可以到百度上搜索 Wireshark, 然后点击下载即可

  2. 点击安装, 一路Next即可

界面操作

  1. 安装好Wireshark后, 进入软件, 你看到的是如下界面
wireshark_use_1.png

首先看到的是

  VirtualBox host-Only Network
  无线网络连接
  VirtualBox host-Only Network #2
  VirtualBox host-Only Network #4
  ....

上面显示的是当前操作系统连接了哪些网络, 这些和你的电脑上

控制面板/网络和Internet/网络连接是一一对应的
wireshark_use_2.png

现在, 我的手机和电脑同处于 无线网络连接 下, 我需要抓取这个网络的数据包, 鼠标选中 无线网络连接 后, 软件左上角出现了一个蓝色的弧形图标(文件) 下, 这个图片的含义就是开始捕获

wireshark_use_3.png

点击开始捕获后, 出现如下:

wireshark_use_4.png

可以看到, 软件显示数据模块被分成了三个部分, 我们可以称为 Top, Center和Bottom

  • Top显示当前网络中传递数据的记录的, 当前网络中每次传递的数据都会显示到上面
  • Center显示的是Top某一条记录的详细信息
  • Bottom则显示Center中某一项数据的具体数据

还可以看到另外一个重要的输入行: 在Top上 提示 "应用显示过滤器" 的输入框, 用于输入过滤表达式来从Top中海量的记录过滤出我们想要的信息


来看一则抓取到的TCP消息


wireshark_use_5.png

先来看看过滤表达式:

tcp and ((ip.src == 192.168.31.113 and ip.dst == 192.168.31.225)or(ip.dst == 192.168.31.113 and ip.src == 192.168.31.225))

PS: 上面的过滤表达式等同于:
tcp && ((ip.src == 192.168.31.113 && ip.dst == 192.168.31.225) || (ip.dst == 192.168.31.113 && ip.src == 192.168.31.225))

含义是: 
1. 当协议是TCP, 并且源地址IP是192.168.31.113, 目标地址IP是192.168.31.225时, 满足过滤条件
2. 当协议是TCP, 并且源地址IP是192.168.31.225, 目标地址IP是192.168.31.113时, 满足过滤条件

过滤出来的记录确实如此, Top中显示的记录:

Sourece表示是源地址IP
Destination表示的是目标地址IP
Protocol表示的是通信协议
Length表示的是数据长度(字节个数)
Info 表示的是数据的详细信息, 包含了协议的一些参数, 通信双方的端口号, 我们发送的数据等等

另外, 本次抓取到的数据, 其实是连接 TCP 的时候抓取到的, 我们都听闻过TCP是经过三次握手才建立连接, 今天终于见到它的庐山真面目

抓取TCP数据

本节来讲解如何抓取TCP协议的数据

  1. 将我的电脑作为服务端, 手机作为客户端, 手机去连接电脑, 连接成功后, 手机和电脑就可以相互发送消息了
  2. 电脑的IP是192.168.23.225, 端口号是23233
  3. 手机的IP是192.168.23.113, 随机分配端口 

在Wireshark中添加过滤表达式

tcp && ((ip.src == 192.168.31.113 && ip.dst == 192.168.31.225) || (ip.dst == 192.168.31.113 && ip.src == 192.168.31.225))

首先, 要使用TCP传递数据, 第一步是创建连接, PS: 以下代码只是演示使用

  • 首先需要先运行服务端程序
int serverPort = 23233;
ServerSocket serverSocket = new ServerSocket(serverPort);
Socket client = serverSocket.accept();  // 阻塞等待, 直到客户端连接成功
  • 客户端
Socket socket = new Socket();
String serverIp = "192.168.31.225";
InetAddress serverHost = InetAddress.getByName(serverIp);
int serverPort = 23233;
SocketAddress serverAddress = new InetSocketAddress(serverHost,serverPort);
socket.connect(serverAddress);    // 执行这个方法后, 如果不抛出异常, 则连接服务端成功, 
  • 如果连接服务端程序成功, 则Wireshark抓取到的消息如下
image.png

看到了建立TCP连接的时候的三次握手, 来看看有什么数据可能是我们需要的呢?

1. 看第一次握手的发起方是192.168.31.113(手机端), 接收方是192.168.31.225(电脑端)
2. 看第二次握手的时候, Center里的消息, 看到Src Port是23233(上面说了设置给服务端的端口号), Dst Port是客户端的端口号
3. 连接tcp的时候, 我们并没有去发送什么数据, 全部是协议底层自己实现的一些数据交互, 而这些数据我们不关心, 因此三次握手抓包意义应该不大 

客户端给服务端发送 "hello"

  • 客户端发送数据
// 获取与服务端的输入流
OutputStream os = socket.getOutputStream();
// 准备发送的信息
String msg = "hello";                           
// 给准备发送的数据加一个换行符, 服务端以 '行' 的方式来读取数据
msg += "\n";                                
// 以utf-8的编码写出数据    
os.write(msg.getBytes("UTF-8"));                
// 将数据刷进流中
os.flush();                                     
  • 服务端读取数据
// 获取与客户端的字节输入流
// 将字节输入流转成为编码为utf-8的字符输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(
                client.getInputStream(), "UTF-8"));
String line = null;
// 读取数据
while ((line = reader.readLine()) != null) {
    // 将接收到的数据打印到cmd控制台上
    System.out.println("receive msg: "+line);
}
  • 抓取到的包
image.png

1. 从top可看出第一份数据是客户端(ip:192.168.31.113,端口: 48983)发给服务端(ip:192.168.31.225,端口: 23233);
   服务端收到来自客户端的消息后也客户端反馈了一份数据(第二份数据)

2. 选中top中的第一份数据, 可以在center中看到数据的详细信息: 
    a. src.ip, dst.ip
    b. src.port, dst.port
    c. data, 数据(6个字节, 数据内容为6865566c6c6f0a)
          拆成字节数组就是[68,65,56,6c,6c,6f,0a], 在这里字节是以十六进制表示的, 转成十进制, 再转成对应的ascii码表上的字符, 数据就是['h','e','l','l','o','\n']
    总结一下: data: 6865566c6c6f0a --每两位为一个字节, 拆成字节数组-->[68,65,56,6c,6c,6f,0a]--将每个字节转成十进制, 再转成对应的ascii字符-->['h','e','l','l','o','\n']

是不是抓取到了TCP数据了呢?

抓取UDP数据:

本节来讲解如何抓取UDP协议的数据


UDP和TCP的传输方式不一样, 但是抓取的方式却是一样的, 只需要修改一下过滤表达式, 就可以帅选出UDP协议的数据包

UDP协议面向无连接, 所谓面向无连接, 也就是说不管对方存不存在, 它都可以向对方发送数据, 当然, 如果接收方不在, 数据就会被丢失了, 所以, 使用UDP发送数据, 没有三次握手, 也没有想TCP那样, 接收到消息后, 对方还会反馈一个数据


  • 首先来编写一个过滤表达式;
我要过滤所有发送给本机(ip:192.168.31.225, 端口号为10086)的udp数据
udp && ip.dst == 192.168.31.225 && udp.port == 10086
  • 接收端程序
int port = 10086;
DatagramSocket datagramSocket = new DatagramSocket(port);
byte[] buffer = new byte[1024 * 8];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
datagramSocket.receive(packet);  // 这个方法会阻塞直到接收到一个udp消息
byte[] data = packet.getData();
int length = packet.getLength();
int offset = packet.getOffset();
InetAddress remoteAddress = packet.getAddress();  // 远程发送端的ip地址
int remotePort = packet.getPort();    // 远程发送端的端口
System.out.println("remoteIp: " + remoteAddress.getHostAddress()
                + ", remotePort: " + remotePort 
                + ", Msg: " + (new String(data, offset, length)));
  • 发送端程序
DatagramSocket datagramSocket = new DatagramSocket();
String msg = "hello udp";
String toIp = "192.168.31.225";
int toPort = 10086; 
byte[] bytes = msg.getBytes();      
DatagramPacket packet = new DatagramPacket(
                bytes,0,bytes.length,           // 要发送的数据
                InetAddress.getByName(toIp),    // 要发送到哪个ip
                toPort);                        // 要发送到哪个端口上
datagramSocket.send(packet);
  • 抓包
image.png

可以看到,

  • top区显示的仅一条数据记录
  • udp发送端: ip: 192.168.31.214, 端口:16166
  • udp接收端: ip: 192.168.31.225, 端口:10086
  • center区显示接收到的数据具有9个字节, 数据是[68656c6c6f20756470]
  • bottom区可以看到数据是"hello udp"

编写过滤表达式

Wireshark的过滤表达式, 就和我们一般写的if语句的条件表达式一致
其中,

     and 和 && 含义一致, 表示 '并且'; 
     or 和 || 含义一致, 表示 '或者';
     udp 表示 udp协议
     tcp 表示 tcp协议
     udp.port == 10086 表示udp端口为10086
     tcp.port == 23233 表示tcp端口为23233
     ip.src == 192.168.31.225 数据发送端ip是192.168.31.225
     ip.dst == 192.168.31.113 数据接收端ip是192.168.31.113

来看几个例子

  • 过滤ip为192.168.31.225设备, 端口为23233, 协议为tcp的数据包和端口为10086, 协议为udp的数据包
(ip.src == 192.168.31.225 or ip.dst == 192.168.31.225) and ( ((tcp) and tcp.port == 23233) or((udp) and udp.port == 10086))

注意事项

  • 需要注意的是:
    Wireshark抓取的是经过本机网卡的数据, 无论tcp还是udp, 如果接收端和发送端都是本机, 那么是抓不到包的, 当然解决方案是有的,

  • 解决方案:
    使用管理员权限运行cmd, 执行命令

route add 本机ip mask 255.255.255.255 网关ip

发送数据的时候, ip地址必须添加本机的ip, 而不应该是127.0.0.1或localhost
当结束调试的时候, 需要将静态ip删除

route delete 本机ip mask 网关ip

总结

  • 本文介绍了Wireshark的简单用法, 并分别演示了抓取TCP, UDP数据
  • 本文从另一个角度去验证了TCP的三次握手连接, 以及发送消息时的连接(TCP发送消息时, 接收端也有反馈), 验证了UDP的面向无连接

后记

  • 使用Wireshark抓包并不是新技术, 也不是什么黑科技. 看似能抓取到数据, 不过现在传递的数据都是经过加密的, 即便抓取到数据了, 也无法解析出来.

  • 比较有用的场景, 例如你在研究一个设备(例如摄像头)与它的控制软件之间的通讯协议, 你使用Wireshark抓包, 然后反推出它们之间的通讯协议; 再实现自己的需求.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容