接到这个靶场任务的时候,手里只有一个 SMB 共享地址和一句“流量包在里面,自己翻”。真正上手才发现,这类场景在真实的内网分析里太常见了:攻击者把抓到的 pcap 文件丢在共享目录里,或者防守方从被控主机上把流量镜像导出来放到 SMB 共享,然后分析人员自己挂载进去拖回来。整个链路没什么高大上的东西,但每一步都讲究思路和细节,稍不注意就会在 Wireshark 里迷失。
这篇文章就以这个靶场为例,完整走一遍:Linux 下挂载 SMB 共享取回 pcap,用 Wireshark 打开流量包,通过协议统计和会话追踪还原攻击者的操作路径,最后把藏在流量里的传输载荷提取出来并做还原修复。内容偏实操,适合刚接触流量分析的安全初学者,也适合想系统梳理 pcap 分析流程的朋友。我会把每个关键操作背后的原因讲清楚,踩过的坑也一并列出来。
1. 靶场场景还原与整体分析思路
1.1 为什么攻击者会把 pcap 放到 SMB 共享里
先说场景。这个靶场模拟的是一台被攻陷的内网主机,攻击者在这台机器上抓了一段网络流量,并把它放进了主机的 SMB 共享目录里。分析人员的任务是从共享中把这个 pcap 拿回来,通过流量分析还原攻击者的行为,并提取出他在流量中传输的载荷。
这里有个很实际的问题:为什么是 SMB 共享,而不是 FTP、HTTP 或者直接放在磁盘里?
从攻击者的视角看,SMB 是 Windows 内网环境里默认开启、用得最多的文件共享协议。把文件放到共享目录里,既可以利用主机自身的文件服务能力,不太容易被当作异常行为,又能方便后续从另一台机器取回数据。从防守方的视角看,截获到内网主机上的 pcap 文件也很常见——EDR 或者流量镜像系统会把抓包结果输出到共享存储,分析人员同样要走 SMB 去取。所以不管从哪个角度,SMB 作为 pcap 的分发通道都足够真实。
靶场一般会把这个共享设置为允许匿名访问或者给一组弱口令。如果实战中遇到的是认证共享,可以用 smbclient 交互式输入密码,或者把密码写进命令行(注意 shell 历史记录问题,建议用环境变量的方式传入口令)。
1.2 拿到 pcap 后为什么不能急着打开 Wireshark
很多人拿到 pcap 的第一反应是双击打开,然后对着五彩斑斓的包列表发呆。我建议先冷静一下,按顺序做三件事:
第一,校验文件完整性。用file命令确认文件类型,用sha256sum计算哈希并和任务给定的哈希做比对,防止文件在传输过程中损坏或被恶意替换。这一步在靶场可能显得多余,但在真实的应急响应里非常重要。
第二,用capinfos读取 pcap 的元数据。这个工具是 Wireshark 自带的命令行程序,可以快速查看文件里的抓包时间范围、总包数、平均包速率、捕获长度等。拿到这些信息,你就能在打开 Wireshark 之前先有一个整体预期:这段流量是一分钟还是一小时?是小规模扫描还是大量数据回传?包长分布是否异常?
第三,想清楚分析目标。这个靶场的核心目标有三个:溯源攻击者、提取载荷、修复载荷。这三个目标对应的分析路径是不一样的。溯源攻击者关注 IP、协议特征、时间规律;提取载荷关注文件上传和数据外传;修复载荷关注编码格式、传输分片、加密/压缩处理。先明确目标再动手,后面才不会像无头苍蝇一样乱翻。
2. 挂载 SMB 共享并取回 pcap 文件
2.1 Linux 下用 smbclient 和 mount 连接 SMB 共享靶场环境里,分析机通常是 Kali 或者 Ubuntu,连接 SMB 共享有两种常用方式。
方式一:用 smbclient 直接交互,适合只下载单文件。
# 匿名访问 smbclient //192.168.10.20/share -U guest -N # 指定用户名密码 smbclient //192.168.10.20/share -U administrator%Passw0rd进入 SMB 交互界面后,用ls查看共享目录内容,get traffic.pcap下载文件,quit退出。smbclient 的优点是轻量,不需要 root 权限,缺点是每次只能操作单个文件,不适合批量操作。
方式二:用 mount.cifs 挂载成目录,适合需要浏览多个文件或做批量分析的场景。
# 安装 cifs-utils(如果没有的话) sudo apt install cifs-utils # 创建挂载点并挂载 sudo mkdir -p /mnt/smb_share sudo mount -t cifs //192.168.10.20/share /mnt/smb_share \ -o username=administrator,password=Passw0rd,vers=3.0 # 匿名访问可以用 guest sudo mount -t cifs //192.168.10.20/share /mnt/smb_share \ -o guest,vers=3.0挂载完成后,直接cp /mnt/smb_share/traffic.pcap ~/analysis/就可以复制文件。
这里说一下vers=3.0这个参数。老版本的 Linux 内核默认可能使用 SMB 1.0 协议连接,而很多新版 Windows Server 默认禁用了 SMB 1.0,这会导致挂载失败。显式指定vers=3.0是兼容性最稳妥的做法。如果连接报错提示协议协商失败,多半就是这个参数的问题。
2.2 文件基础检查:capinfos 和文件哈希
取回 pcap 后,按前面说的先做基础检查。
cd ~/analysis file traffic.pcap sha256sum traffic.pcap capinfos traffic.pcapcapinfos的输出信息非常有用,重点看这几项:
- Capture start time 和 Capture end time:确定抓包的时间窗口,结合攻击时间判断流量范围是否完整。
- Number of packets:包总量,判断流量规模。
- Data byte rate 和 Packet size limit:如果 packet size limit 显示 64/128 这类值,说明抓包时设置了 snaplen,包只有头部没有完整载荷,后续提取载荷就需要额外小心,因为应用层数据不完整。
我遇到过一种情况:靶场为了减小 pcap 体积,用 tcpdump 的-s 64参数只抓每个包的前 64 字节。这种文件做协议分析没问题,但如果想从 HTTP 响应里提取完整文件就做不到了。遇到这种限制,就要用状态机思路去分析,而不是直接等 Wireshark 给你完整对象。
3. Wireshark 打开 pcap:先看全局再追细节
3.1 调整显示选项:时间列和地址列
打开 pcap 后,第一件事不是点开某个包,而是配置好界面,让信息更直观。
时间格式建议改成“自参考时间起经过的时间”。在 Wireshark 的 View → Time Display Format 中选择Seconds Since Beginning of Capture,或者直接按快捷键 Ctrl+Alt+1。这个格式可以直观地看到每个包距离抓包起始时间的间隔,分析攻击行为的先后顺序和间隔规律比默认的绝对时间更有用。等需要和外部日志关联时,再切回 UTC 时间。
列配置上,我习惯保留 No.、Time、Source、Destination、Protocol、Length、Info 这几列。如果分析 HTTP 流量,可以右键任意包选择 Column Preferences,添加一个http.request.uri列,这样不用点开每个包就能看到请求路径,快速发现可疑 URL。
3.2 用协议分层统计快速锁定可疑流量
打开 Wireshark 的 Statistics → Protocol Hierarchy 窗口,可以看到各个协议在流量中的占比分布。这个窗口是效率神器,尤其是面对几千甚至几万条包的时候。
正常的靶场流量里,常见协议是 TCP、TLS、HTTP、SMB、DNS 这些。如果发现某个协议的包数量和流量占比异常高,比如一个内网抓包里居然有大几百条 SMB2 的 Write 请求,或者 DNS 查询的包数量明显超过正常水平,那这条线就值得深挖。
举个例子:有一次我打开一个 pcap,协议分层里显示 DNS 有 3000 多条查询,占比异常高。顺着 DNS 的上下行请求一看,发现是攻击者在用 DNS 隧道传数据。协议分层本身不会告诉你攻击者是谁,但会告诉你线索藏在哪个方向。
在这个靶场场景里,最优先关注的是 HTTP 和 SMB 两条线。HTTP 是 Web 攻击最常见的载体,而 SMB 既是文件共享协议,也可能被攻击者用来回传文件或执行远程操作。DNS 也值得扫一眼,看看有没有明显的长域名解析。
4. 攻击溯源:从会话特征还原攻击者的操作路径
4.1 用显示过滤器和“Follow TCP Stream”定位关键会话
协议统计只是方向,真正的溯源要靠会话级分析。Wireshark 的Follow TCP Stream(右键任意 TCP 包 → Follow → TCP Stream)是流量分析里最核心的功能之一。
先通过显示过滤器筛掉无关流量。靶场场景里我一般先用:
http.request || http.response把所有 HTTP 请求和响应过滤出来,然后一条条看请求路径、User-Agent、响应码。
有一个很容易被忽略的细节:攻击者的工具特征往往藏在 User-Agent 里。默认浏览器的 User-Agent 会包含 Mozilla、Chrome/Safari 等字段,而很多攻击脚本会用 python-requests、Go-http-client、curl/x.x 这类特征明显的内容。看到这类 UA,基本就能确定这不是正常用户访问。
看完 HTTP 请求后,针对某个可疑 IP 再追踪 TCP 流,按照流的内容继续判断。这里建议用 Wireshark 的 Follow TCP Stream 对话框里的Show data as Hex Dump模式,因为有些攻击者会在 HTTP 请求里混入二进制数据,普通文本模式会显示一堆乱码,十六进制模式下能看清真实内容。
4.2 通过时间线重建攻击顺序
溯源不是只看一条流,而是要把攻击者在流量里留下的所有痕迹串成一个时间线。用之前设置的“相对时间”列,你会发现攻击者通常有一个比较固定的行为序列:
前几秒内出现大量 TCP SYN 包,或者针对多个端口的高频连接尝试,这是扫描阶段;紧接着会有一次到某个 Web 路径的异常请求,返回 200,这是漏洞利用阶段;随后出现一个大小明显偏大的 POST 请求,或者多个分片数据包,这是载荷上传阶段;再往后有一段规律的客户端和服务端交互,包括命令执行和响应返回,这是控制阶段。
把这些关键节点的时间戳、源目的 IP、行为内容整理成表,攻击者的画像就出来了。这个时间线不是 Wireshark 自动生成的,而是要靠你结合过滤条件和会话追踪来整理。
深层的一个技巧:如果一个 HTTP 请求是 POST,但是响应体很短,而随后马上有一条从源 IP 到目标 IP 的长连接流量,协议是 TCP 且数据段字节数很大,那大概率攻击者是在做数据回传,传输的内容可能是一个压缩包,也可能是一个脚本的输出结果。不要只看 80 端口,回传的通道往往在高端口或反向连接里。
5. 传输载荷的提取与修复
5.1 用 Export Objects 提取常见协议的文件对象
当定位到载荷上传或下载的会话后,提取载荷就顺理成章了。
Wireshark 的 File → Export Objects → HTTP 可以把 HTTP 流里传输的文件对象一键导出。导出后会列出所有 HTTP 对象,包括请求和响应里的文件、脚本、图片等。可以先看大小排序,重点关注那些大小异常的项——攻击者上传的 WebShell 往往只有几 KB,但会被特意伪装成图片或静态资源。
靶场场景里,最常见的载荷提取对象有这几种:
- 一句话 WebShell,可能是 PHP、JSP、ASPX 文件;
- 攻击者上传的可执行文件,如 exe、elf、msi;
- PowerShell 脚本或 VBS 脚本;
- 包含压缩数据的响应体,比如 gzip 压缩后的内容。
导出这些对象后,先不要急着打开。先把文件file一下,看真实类型。比如导出的文件名是 upload.php,但file报出来是 ELF 64-bit executable,那说明这是伪装的二进制木马。
这里必须强调一个安全纪律:分析恶意载荷时,一定要在隔离环境里操作。推荐的流程是,导出的文件先用file和strings做基础检查,确认需要动态分析时,放到虚拟机或者沙箱里运行,不要在物理机上直接执行。
5.2 编码还原:Base64、URL 编码和 UTF-16 的处理
载荷并不总是直接以文件形式出现,很多时候攻击者会把载荷做编码处理,藏在一串字符串里。常见的三种编码方式:
第一种是 URL 编码。常见于 GET 请求的参数里,特征是出现大量的%20、%3C这类百分号转义。Wireshark 里可以直接右键相关字段选择 Copy → Value,然后用 Python 的urllib.parse.unquote或者 CyberChef 的 URL Decode 一键还原。
第二种是 Base64 编码。常用于 POST 请求体和响应文本中,特征是字符串末尾可能有=填充,字符集主要是大小写字母和数字加+和/。解码方式用命令行的 base64 工具即可:
echo 'Base64字符串' | base64 -d > decoded.bin file decoded.bin但这里有个大坑:很多攻击者会把多个编码叠加使用,比如先 Base64 再 URL 编码,或者先加密再 Base64。看到一个 Base64 字符串解出来还是乱码时,别急着放弃,把解码结果再做一次字符串分析。常见的叠加方式是用 CyberChef 的 Magic 功能自动识别解码链,非常高效。
第三种是 UTF-16LE 编码。PowerShell 命令如果通过命令行传输,往往会被编码成 UTF-16LE,在 Wireshark 的文本视图中显示成“每两个字节夹杂一个 0x00”,肉眼看起来就是P o w e r S h e l l这个样子。处理办法是用 iconv 做编码转换:
iconv -f UTF-16LE -t UTF-8 encoded.txt > decoded.txt或者直接在 Wireshark 的 Follow TCP Stream 设置里把 Stream 内容的字符编码改为 UTF-16LE 再查看,也能直接看到可读内容。
5.3 处理分片和分块传输的载荷
还有一种情况会让很多人头疼:载荷在传输过程中被拆成了多个 TCP 段或者多个 HTTP 分块。Wireshark 默认会对 TCP 流做重组,所以大部分场景下 Follow TCP Stream 能展示完整内容。但如果抓包时设置了 snaplen 导致部分包被截断,或者中间有丢包,那重组后的数据就是不完整的。
这时有几个判断和修复的办法:
先看载荷是不是“可视化完整”。如果 Follow TCP Stream 里的内容开头是MZ(Windows 可执行文件头)、7F 45 4C 46(ELF 头)、PK(zip 文件头),那这个文件在流层面就是完整的,直接存成二进制即可。
如果内容不完整,比如有大量的....或者流中途断开,那就要回到包列表,看这一段流的序列号是否有空隙,也就是有没有丢包。如果 TCP Seq 不连续,说明 pcap 本身就不完整,无法直接从这条流恢复完整文件。
那怎么办?找备份。攻击者上传载荷不一定只传一次,可能传了多个版本,也可能在同一条连接里用 Post 方法分段传输。把整个会话里所有 POST 请求的 data 部分拼接起来,按 Content-Length 字段计算偏移量,手动重组,是可以还原出完整载荷的。这个过程用 Python 处理会方便很多,核心思路是:每个 TCP 载荷的 Seq 序号对应它在原始文件中的偏移位置,用seq - 初始Seq就能把分散的字节拼回去。
5.4 实战演示:从 pcap 里提取并修复一个 PowerShell 载荷
这个靶场里遇到的载荷是一个比较典型的例子。我在 pcap 里追踪一条 HTTP 流,发现响应体是一长串 Base64 字符串,解码后是一段 PowerShell 命令,命令里还包含一个下载链接和一段加密的传输内容。
完整处理流程如下:
第一步,在 Wireshark 里找到可疑的 POST 请求,右键 Follow TCP Stream,将流内容保存为 raw 格式文件payload_raw.txt。
第二步,用 strings 或者直接看文本内容,定位 Base64 字符串。这里有个小技巧:先正则匹配出连续超过 200 字符的 Base64 片段,避免截取到中间断开的内容。
grep -oP '[A-Za-z0-9+/]{200,}={0,2}' payload_raw.txt > b64_payload.txt第三步,解码并查看真实内容。
base64 -d b64_payload.txt > decoded_1.bin file decoded_1.bin strings decoded_1.bin | head -50如果 file 显示是 ASCII text,再仔细看内容,如果看起来仍然像编码字符,继续解码。
第四步,如果内容是 UTF-16LE 编码的 PowerShell,继续处理。
iconv -f UTF-16LE -t UTF-8 decoded_1.bin > decoded_1.ps1第五步,检查脚本内容,提取出脚本内嵌的下载 URL 和 payload。把 URL 对应的内容从 pcap 里单独导出,和脚本里写的哈希值做比对,确认文件完整性。
这个流程的核心思想是:不要试图一次性解出最终结果,而是每一层解码后都停下来看文件类型和可读性,再决定下一步做什么。很多新手卡在“解了一次还是乱码”就放弃了,实际上只是编码层没有剥干净。
6. 常见问题与排查技巧实录
6.1 常见问题速查表
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| Wireshark 打开 pcap 报错格式不对 | 文件头损坏或并非 pcap 格式 | 用file和capinfos检查,尝试用 tshark 重新读取 |
| Follow TCP Stream 内容不完整 | 抓包时设置了 snaplen 导致载荷被截断 | 检查抓包文件名或 capinfos 里的 Packet size limit,确认后不可完整恢复 |
| HTTP 对象导出列表为空 | 流量经过了 TLS 加密,Wireshark 看不到明文 | 提供 SSLKEYLOGFILE 密钥文件,在 Preferences → Protocols → TLS 里配置 |
| Base64 解码后是乱码 | 编码层未剥干净,可能还有 UTF-16 或 gzip 压缩 | 继续看file判断,用 iconv 转码或 zlib 解压 |
| Wireshark 卡顿严重 | pcap 太大或载入了过多列 | 用 tshark 命令行做预处理,输出过滤后的精简 pcap |
| SMB 挂载连接失败 | SMB 协议版本不匹配或未装 cifs-utils | 显式指定vers=3.0,确认安装了 cifs-utils |
| 显示过滤器语法报错 | 字段名写错或没加引号 | 用 Wireshark 的“表达式”按钮插入字段名,避免手拼 |
6.2 tshark 作为预处理工具的使用建议
遇到上百 MB 的 pcap,先别急着用 Wireshark 打开。tshark 在性能上远优于 Wireshark 的 GUI 界面,用来做快速过滤和对象提取非常顺手。
比如要从 pcap 里快速导出所有 HTTP 对象:
tshark -r traffic.pcap --export-objects "http,exported_http" -q导出所有 DNS 查询:
tshark -r traffic.pcap -Y "dns.flags.response == 0" -T fields \ -e dns.qry.name | sort | uniq -c | sort -rn | head -20如果只想保留某个 IP 相关的流量,方便后续在 Wireshark 里细看:
tshark -r traffic.pcap -Y "ip.addr == 192.168.1.100" -w filtered.pcaptshark 的过滤语法和 Wireshark 显示过滤器完全一致,所以 ID 很平滑。熟练使用 tshark 能让分析效率提升一个档次,而且它很适合写进脚本,实现批量化的 pcap 分析流程。
6.3 分析工作区:保存过滤器、列配置和着色规则
分享一个能显著提升效率的习惯:把常用的过滤器、列配置和着色规则保存成 Wireshark 配置文件,之后每次分析直接加载。
我的常用配置里有几个固定的显示过滤器:
http.request && !(http.request.uri contains ".js" || http.request.uri contains ".css")过滤掉静态资源,只看动态请求。
tcp.flags.syn == 1 && tcp.flags.ack == 0只看 SYN 包,快速定位扫描行为。
data.len > 1000只看数据长度超过 1000 字节的包,用来发现大流量传输。
着色规则里,我把 HTTP 5xx 响应标红,4xx 标黄,含 webshell 关键词(如 cmd、eval、exec)的包单独标紫,这样打开 pcap 后能一眼扫到异常。
6.4 关于 pcap 分析的一个心态建议
流量分析最考验人的不是工具熟练度,而是耐心和排查意识。一个 pcap 文件可能包含几万条包,但真正关键的往往只有几条。判断“关键”的标准不是包的大小,而是它在整个攻击链中的位置。
溯源攻击者的时候,抓住一条验证成功的路径就够建时间线了;提取载荷的时候,找到一条完整的上传流就够分析了。不要被无关流量牵着走,也不要因为暂时没找到关键包就反复重扫同一个方向。停下来想想:攻击者在这个场景里最可能干什么?他上传的东西会以什么形式存在?这个问题的答案往往就是你该看的那条流。
我个人在实际操作中还有个体会:每次分析完 pcap,把关键会话的时间点、IP、URI、提取出的载荷哈希整理成一份简短报告,比什么都强。一方面方便自己复盘,另一方面如果这是一个团队靶场或应急项目,这份记录就是后续处置和溯源最宝贵的材料。分析流量永远是“做完不算完,能完整讲清楚才算真正掌握了”。