发布于周六 18:492天前 背景在授权内网渗透测试里,SMB 服务通常是第一批需要确认的暴露面:445/139 端口是否开放、是否允许匿名枚举、共享目录权限是否过宽、是否存在旧协议或弱配置。本文只围绕 Kali 渗透工具的使用方法展开,场景是对客户授权网段做 SMB 暴露面验证,并输出可复核的证据与修复建议。测试前提:已取得书面授权;仅对授权网段和资产操作;不做破坏性写入,不上传可执行文件,不尝试横向扩散。测试场景假设授权范围为 192.168.56.0/24,目标是确认该网段中 Windows 主机的 SMB 服务配置情况,重点关注:哪些主机开放了 445/tcp 或 139/tcp;是否启用了 SMBv1;是否允许匿名会话枚举用户、组、共享;共享目录是否存在匿名读取或误配置写入;如何保留命令输出,便于报告复核和后续整改。工具准备Kali 默认通常已包含 Nmap 和 smbclient。enum4linux-ng 有些版本需要手动安装。建议先更新索引,再确认工具版本。sudo apt update sudo apt install -y nmap smbclient enum4linux-ng nmap --version smbclient --version enum4linux-ng -h | head建议为每次项目单独建立目录,避免混淆证据文件。mkdir -p ~/pt-smb-192.168.56/{scan,enum,share,notes} cd ~/pt-smb-192.168.56问题定位:先确认 SMB 存活面第一步不要直接做深度枚举,先快速确认哪些资产开放 SMB。这里使用 Nmap 的端口扫描,并将结果保存为普通文本、grepable 和 XML 三种格式,便于人工查看和后续导入工具。sudo nmap -Pn -n -p 139,445 --open \ -oA scan/smb_ports_192.168.56 \ 192.168.56.0/24参数说明:-Pn:不做主机发现,避免因 ICMP 被拦截漏掉主机;-n:不做 DNS 解析,提高速度,也减少无关查询;-p 139,445:只扫 SMB 相关端口;--open:只输出开放端口结果;-oA:同时输出 .nmap、.gnmap、.xml。从 gnmap 中提取开放 445 的 IP,后续逐台验证:awk '/445\/open/ {print $2}' scan/smb_ports_192.168.56.gnmap | sort -u > scan/smb_hosts.txt cat scan/smb_hosts.txt技术分析:识别 SMB 版本与基础信息确认存活面后,用 Nmap SMB 脚本获取协议、安全模式和系统信息。这里不使用破坏性脚本,只做配置识别。sudo nmap -Pn -n -p445 \ --script smb-protocols,smb-security-mode,smb2-security-mode,smb2-time,smb-os-discovery \ -iL scan/smb_hosts.txt \ -oA scan/smb_fingerprint重点看以下内容:SMBv1 是否出现在 smb-protocols 输出中;message signing 是否为 disabled 或 not required;系统版本、主机名、域信息是否能被匿名读取;时间偏差是否异常,时间不一致会影响 Kerberos、日志关联和取证。如果发现类似下面输出,需要在报告中单独标记:| smb-protocols: | dialects: | NT LM 0.12 (SMBv1) [dangerous, but default] | 2.02 | 2.10 |_ 3.00SMBv1 本身不是“漏洞利用”结论,但它是高风险老协议,常与历史漏洞、弱加固和兼容性遗留问题有关,应建议关闭。操作步骤:匿名枚举验证接下来使用 enum4linux-ng 对每台主机做匿名枚举验证。它比老版 enum4linux 输出更结构化,适合报告留痕。while read ip; do echo "[+] enum anonymous: $ip" enum4linux-ng -A -oJ enum/enum4linux-ng_$ip.json -oY enum/enum4linux-ng_$ip.yaml $ip \ | tee enum/enum4linux-ng_$ip.txt done < scan/smb_hosts.txt关注输出中的几类信息:sessions_possible:是否允许 null session;shares:共享列表是否可匿名获取;users:用户列表是否可匿名枚举;groups:组信息是否泄露;password_policy:密码策略是否可匿名读取。如果匿名枚举失败,不代表 SMB 配置安全,只能说明当前匿名路径不可用。授权测试中若客户提供普通域账号,还应在权限边界内补充认证枚举,但不要越权尝试管理员行为。操作步骤:共享目录权限验证共享目录权限验证建议分两步:先列共享,再只读访问。未经授权不要写入文件。即使要验证写权限,也应事先和客户约定测试文件名、内容和清理方式。# 匿名列共享 smbclient -L //192.168.56.20 -N # 使用授权账号列共享,注意不要在 shell 历史中留下明文密码 smbclient -L //192.168.56.20 -U 'DOMAIN\\audit.user'如果需要批量列共享,可以使用下面的方式。密码建议交互输入,不建议直接写在命令行参数中。while read ip; do echo "===== $ip =====" | tee -a share/smbclient_list.txt smbclient -L //$ip -N 2>&1 | tee -a share/smbclient_list.txt done < scan/smb_hosts.txt对发现的共享做只读验证,例如共享名为 Public:smbclient //192.168.56.20/Public -N -c 'pwd; ls' | tee share/192.168.56.20_Public_ls.txt如果客户明确授权验证写权限,可以使用无害文本文件,并测试后立即删除。文件内容应包含项目名、时间、测试人员标识,便于蓝队和运维识别。printf 'authorized smb write test, project=PT-2024, time=%s\n' "$(date -Is)" > /tmp/pt_smb_write_test.txt smbclient //192.168.56.20/Public -N \ -c 'put /tmp/pt_smb_write_test.txt pt_smb_write_test.txt; ls pt_smb_write_test.txt; del pt_smb_write_test.txt'这一步要谨慎:如果共享目录承载业务文件,误操作可能触发同步、备份、审计或杀软告警。能通过 ACL 证据确认的,不建议强行写入。日志留痕与证据整理渗透测试报告不是只写“存在风险”,要让运维能复现和定位。建议每个发现至少保留以下证据:扫描命令和执行时间;目标 IP、主机名、域信息;开放端口和协议版本;匿名枚举成功的原始输出;共享目录可访问证据;是否验证写权限,以及测试文件是否已清理。可以用以下命令生成简要索引,方便报告引用:date -Is | tee notes/test_time.txt printf 'Open SMB hosts:\n' > notes/summary.txt cat scan/smb_hosts.txt >> notes/summary.txt printf '\nPotential SMBv1 findings:\n' >> notes/summary.txt grep -R "SMBv1\|NT LM 0.12" scan/smb_fingerprint.nmap enum/*.txt 2>/dev/null >> notes/summary.txt printf '\nAnonymous share list evidence:\n' >> notes/summary.txt grep -R "Disk\|IPC\$\|Sharename" share/*.txt 2>/dev/null >> notes/summary.txt常见误判排查现象可能原因排查方法Nmap 显示 445 open,但 smbclient 连接失败防火墙、SMB 签名策略、协议版本不兼容使用 nmap --script smb-protocols 确认协议;尝试指定 SMB 协议版本匿名列共享失败禁用 null session,属于正常加固用授权账号复测,区分匿名不可用和服务不可用enum4linux-ng 输出用户为空目标禁用匿名 RID/LSA 枚举查看工具输出中的权限错误,不要直接判定不存在用户共享可列出但无法进入共享级可见,NTFS ACL 不允许访问分别记录共享列表和目录访问结果,避免混为一谈风险与修复建议针对测试中常见问题,整改建议可以按优先级给出:关闭 SMBv1:Windows Server 可通过组策略或 PowerShell 禁用 SMBv1,避免遗留协议暴露风险。禁用匿名枚举:限制 null session 访问,避免用户、组、共享和密码策略被未认证读取。收敛共享权限:共享权限和 NTFS 权限都要检查,避免 Everyone、Authenticated Users 过宽。启用 SMB 签名:关键服务器建议要求 SMB signing,降低中间人篡改风险。最小化暴露面:普通办公网段不应直接访问服务器管理共享;跨网段访问通过防火墙白名单控制。开启审计:记录共享访问、失败登录、对象访问事件,便于追踪异常枚举和批量访问行为。Windows 侧可参考以下检查命令,由运维在服务器本机或管理终端执行:# 查看 SMBv1 状态 Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol # 查看 SMB 服务端配置 Get-SmbServerConfiguration | Select EnableSMB1Protocol,EnableSMB2Protocol,RequireSecuritySignature,EnableSecuritySignature # 查看共享及权限 Get-SmbShare Get-SmbShareAccess -Name 'Public'总结SMB 暴露面验证不需要一上来就使用复杂工具链。Kali 下用 Nmap、enum4linux-ng、smbclient 就能完成一轮清晰的授权检查:先定位开放端口,再识别协议和安全模式,随后验证匿名枚举与共享权限,最后把原始输出整理成可复核证据。实际项目里,重点不是“扫到了什么”,而是把权限边界、验证方式、风险影响和修复路径写清楚,让运维能按证据完成整改。 服务器、云资产与权限边界梳理示意
周六 18:502天前 补充一个实战里比较容易漏的点:做 SMB 暴露面验证时,别只看 445 是否开放,建议把“匿名/来宾访问、SMB 签名、SMBv1、可写共享、域信息泄露”分开记录,不然后续整改很难落到具体项。 可以按这个流程跑一遍,输出也比较适合留痕: # 1. 先确认 SMB 相关端口与协议特征 nmap -Pn -p 139,445 --open -sV --version-all -oA smb_ports 10.0.0.0/24 # 2. 针对开放 445 的主机跑 SMB 脚本 awk '/445\/tcp open/{print $2}' smb_ports.gnmap > smb_hosts.txt nmap -Pn -p445 --script \ smb-protocols,smb-security-mode,smb2-security-mode,smb2-capabilities,smb2-time,smb-os-discovery \ -iL smb_hosts.txt -oA smb_nse_detail 重点看几类结果: - `smb-protocols`:是否还启用 `SMBv1` - `smb-security-mode` / `smb2-security-mode`:`message_signing: disabled` 或 `not required` - `smb-os-discovery`:是否暴露主机名、域名、系统版本等信息 - 是否能匿名枚举共享 匿名和来宾访问建议单独验证,不要完全依赖 enum4linux-ng 的汇总结果: # 匿名列共享 smbclient -L //10.0.0.10 -N # 指定空用户名测试 smbclient -L //10.0.0.10 -U ''%'' # 如果环境允许 guest smbclient -L //10.0.0.10 -U guest% 如果能列出共享,再逐个检查是否可读/可写: # 读取测试 smbclient //10.0.0.10/share -N -c 'ls' # 写入测试,注意只在授权范围内放置无害文件 echo "authorized smb write test" > smb_write_test.txt smbclient //10.0.0.10/share -N -c 'put smb_write_test.txt; ls; del smb_write_test.txt' enum4linux-ng 建议加上 JSON 输出,后面整理报告会省很多事: enum4linux-ng -A 10.0.0.10 -oJ enum_10.0.0.10.json 如果是域环境,用授权账号验证时可以明确区分“普通域用户能看到什么”和“匿名能看到什么”: # 匿名 enum4linux-ng -A 10.0.0.10 # 授权域账号 enum4linux-ng -A 10.0.0.10 -u 'DOMAIN\user' -p 'password' # smbclient 域账号列共享 smbclient -L //10.0.0.10 -U 'DOMAIN\user%password' 整改建议也可以按发现项对应写清楚: - 禁用 SMBv1:Windows 侧关闭 `SMB 1.0/CIFS File Sharing Support` - SMB 签名至少对域控和关键服务器设置为 required - 清理匿名/Guest 访问,尤其是 `Everyone`、`ANONYMOUS LOGON`、`Guest` - 对共享目录做最小权限,不要只看共享权限,还要看 NTFS 权限 - 对不需要 SMB 的服务器直接关闭 445 或通过防火墙限制访问源 最后提醒一下,内网扫 SMB 容易触发日志和告警,尤其是 `enum4linux-ng -A` 会做比较完整的枚举。授权测试前最好确认扫描窗口、源 IP 和速率,Nmap 可以适当加参数控制节奏: nmap -Pn -p445 --max-rate 50 --scan-delay 100ms -iL smb_hosts.txt -oA smb_safe_scan 这样结果更稳定,也比较符合授权验证的边界。
周六 18:532天前 这个流程里有一个容易踩坑的地方:-oA 生成的 .gnmap 格式不是 445/tcp open,而是类似 445/open/tcp//microsoft-ds///。所以原来的 awk 可能筛不出主机,建议直接按端口字段提取: grep 'Ports:.*445/open/tcp' smb_ports.gnmap \ | awk '{print $2}' \ | sort -u > smb_hosts.txt cat smb_hosts.txt 如果环境里主机名解析较多,也可以不依赖 gnmap,直接从 XML 结果提取: xmllint --xpath \ '//host[ports/port[@portid="445" and state/@state="open"]]/address[@addrtype="ipv4"]/@addr' \ smb_ports.xml 2>/dev/null \ | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' \ | sort -u > smb_hosts.txt 另外,NSE 脚本看到的是“协议和安全属性”,共享权限最好再用 enum4linux-ng 和 smbclient 做一次交叉验证。尤其要区分匿名会话、显式 guest 会话和已授权账号,三者结果不能混在一起。 # 匿名枚举,先只针对单台主机验证 enum4linux-ng -A 10.0.0.15 -oJ enum_10.0.0.15.json -oY enum_10.0.0.15.yaml # 不提供凭据列出共享 smbclient -L //10.0.0.15 -N # 明确使用 guest,便于和匿名结果区分 smbclient -L //10.0.0.15 -U 'guest%' # 使用授权测试账号时,建议避免把密码直接写进 shell 历史 smbclient -L //10.0.0.15 -U 'LAB\audit_user' 发现共享后,不要只记录“能列出”,还要记录进入共享时的实际权限: # 进入指定共享并查看目录 smbclient //10.0.0.15/public -N -c 'ls' # 通过授权账号验证 smbclient //10.0.0.15/public -U 'LAB\audit_user' -c 'ls' 可写性验证建议在明确授权、且有专用测试目录的情况下进行。不要直接向业务共享上传文件;如果必须验证,使用唯一测试文件并在确认写入后立即删除,同时保存返回码和服务器响应。很多时候“能看到共享”并不代表“能写”,而 NT_STATUS_ACCESS_DENIED、NT_STATUS_LOGON_FAILURE 和共享不存在也应分别记录。 最后,smb2-security-mode 显示的签名状态也建议注明是“支持”还是“强制”。只支持签名不等于客户端必须使用签名,整改项最好单独落成:最低 SMB 协议、签名要求、匿名/Guest 策略、共享 ACL,以及是否存在可写业务目录。这样后续复测时可以直接按项对比,而不是只看 445 端口是否还开放。
创建帐户或登录后发表意见