跳转到帖子

渗透工具实战:Kali 下用 Nmap、enum4linux-ng 与 smbclient 做授权内网 SMB 暴露面验证

精选回复

发布于

背景

在授权内网渗透测试里,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.00

SMBv1 本身不是“漏洞利用”结论,但它是高风险老协议,常与历史漏洞、弱加固和兼容性遗留问题有关,应建议关闭。

操作步骤:匿名枚举验证

接下来使用 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 就能完成一轮清晰的授权检查:先定位开放端口,再识别协议和安全模式,随后验证匿名枚举与共享权限,最后把原始输出整理成可复核证据。实际项目里,重点不是“扫到了什么”,而是把权限边界、验证方式、风险影响和修复路径写清楚,让运维能按证据完成整改。

服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意
补充一个实战里比较容易漏的点:做 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
这样结果更稳定,也比较符合授权验证的边界。

这个流程里有一个容易踩坑的地方:-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 端口是否还开放。

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。