一、引言:边界失守之后,真正的战场才刚开始

过去十年,红队的攻击重心发生了明显位移。

请添加图片描述

随着 EDR 覆盖率提升、WAF 语义分析成熟、云上边界收敛,从外网直接打穿一家企业的成本越来越高。攻击者与防守方都逐渐接受一个事实:外网打点只是入场券,内网才是决定成败的战场。

但内网渗透的难点,从来不是"某个工具不会用",而是流程的碎片化。很多初学者的状态是:会跑 fscan,会开 mimikatz,会背几条提权命令,但一旦面对一个真实的、有 3000 台主机、划分了十几个 VLAN、部署了终端管控和流量审计的内网,就完全不知道下一步该做什么。

问题的根源在于缺少一条清晰的主线。本文把内网渗透拆成四个有严格先后依赖的阶段:

  1. 主机发现——先搞清楚"有哪些资产活着";
  2. 服务与身份识别——搞清楚"活着的资产是什么、开了什么、是谁在跑";
  3. 凭据获取与横向移动——从"能访问"变成"能登录";
  4. 权限分析——从"普通用户"变成"管理员/域管",并把整条路径固化成可复现的攻击图。

本文所有技术内容仅用于已获得书面授权的渗透测试、企业内网自查与 CTF/靶场环境。未经授权对他人网络实施扫描、爆破、凭据窃取,在《刑法》第二百八十五条、第二百八十六条下有明确的刑事风险。

很多初学者容易陷入一个误区:把工具等同于能力。事实上,工具只是流程中的执行器,真正决定渗透深度的是信息收敛的顺序。例如,在没有摸清网段存活主机之前就盲目跑漏洞扫描,不仅浪费大量时间,还会产生海量告警;在没确认账户权限半径之前就尝试横向移动,往往会被锁定账户或触发 EDR。因此,本文的四个阶段不是并列关系,而是严格的串行依赖:前一步的输出是后一步的输入,任何跳跃都会导致后续动作失去目标。

二、核心原理:内网渗透的本质是"信息差收敛"

如果用一句话概括内网渗透的数学本质,那就是:不断缩小"攻击者已知信息"与"网络真实拓扑"之间的差集。

每一个阶段都在收敛这个差集:

阶段输入输出收敛的信息维度
主机发现网段存活 IP 列表空间维度
服务识别存活 IP端口/协议/中间件服务维度
凭据获取服务用户名/密码/哈希/票据身份维度
权限分析身份可提权路径、可达资产权限维度

理解这个模型的意义在于:当你在内网里"卡住"时,一定是某个维度的信息还没收敛完。比如横向失败,往往不是工具不行,而是你还不知道目标主机的域内角色、SMB 签名状态、或者手上这组凭据对应的账户是否被禁用。

另外必须强调:内网渗透是一个噪声与收益的博弈。每一次扫描、每一次认证尝试,都会在防火墙、IDS、EDR、域控日志里留下痕迹。成熟的测试者不是"扫得最多的人",而是"用最少流量换取最多有效信息的人"。

从信息论的角度看,内网渗透的每一步都是在降低系统的不确定性熵。初始状态下,攻击者对目标内网的认知熵极高;每完成一次主机发现,空间维度的熵下降;每识别一个服务,服务维度的熵下降;每获得一组凭据,身份维度的熵下降;每分析出一条提权路径,权限维度的熵下降。当所有维度的熵降到足以支撑达成目标时,渗透即告完成。因此,当行动受阻时,正确的做法不是重复执行同一种工具,而是回到当前熵最高的维度去补充信息。

噪声与收益的博弈还体现在 OPSEC(操作安全) 上。一个成熟的红队会遵循三条原则:最小权限——只用当前任务必需的权限,不随意提权;最小流量——优先使用被动信息收集,主动探测时控制并发和频率;最小痕迹——避免在目标主机上留下明显的工具文件、日志和注册表项。例如,一次全端口扫描可能瞬间触发 IPS 的端口扫描规则,而针对性的 445/3389/5985 探测则隐蔽得多。再比如,使用 net user /domain 查询域用户会留下 4661 日志,而通过已获得的域管凭据直接读取 AD 数据库则相对安静。这些取舍,正是内网渗透从"脚本小子"走向"专业测试"的分水岭。

三、主机发现:把看不见的资产摸清楚

3.1 三层发现与四层发现的取舍

主机发现技术按 OSI 层次分两类:

  • 三层(网络层)发现:ICMP Echo、ICMP Timestamp、ARP。同网段下 ARP 是最可靠的——因为交换机必须转发 ARP 广播,且几乎不存在"关闭 ARP 响应"的主机。跨网段时 ARP 失效,只能依赖 ICMP,而 Windows 防火墙默认丢弃外部 ICMP Echo。
  • 四层(传输层)发现:向常见端口发 TCP SYN/ACK/FIN,或 UDP 探测。优势是能穿透"禁 ICMP 但业务端口开放"的场景。代价是速度慢、容易被 IDS 判定为扫描。

实战策略是组合拳:同网段用 ARP 秒出结果,跨网段用 TCP 多端口(22/80/135/139/443/445/3389/5985)探测,ICMP 作为兜底。

深入一层看,ARP 扫描之所以在同网段近乎无敌,是因为它工作在数据链路层,不经过 IP 路由,也不依赖目标主机的 TCP/IP 协议栈配置。只要目标网卡启用了 ARP 协议(默认启用),交换机就会将 ARP 请求广播到所有端口,目标主机回复 ARP Reply,攻击者即可获得 IP 与 MAC 的映射。即使目标主机安装了个人防火墙,只要没有禁用 ARP 响应,仍然会被发现。这也是为什么在内网横向中,ARP 扫描往往是第一步。

ICMP 探测则要区分类型:Echo Request(Type 8)是最常见的,但 Windows 防火墙默认阻止;Timestamp Request(Type 13)有时能绕过某些防火墙策略;Address Mask Request(Type 17)在现代系统中基本被忽略。因此,单纯依赖 ping 扫描会漏掉大量 Windows 主机。TCP 探测则利用了目标主机必须响应 SYN 包的机制:如果端口开放,返回 SYN+ACK;如果关闭,返回 RST。即使防火墙过滤了 ICMP,只要业务端口开放,TCP 探测就能发现主机。但要注意,全连接扫描(connect())会完成三次握手,在目标主机上留下连接日志;半开扫描(SYN)则需要原始套接字权限,且容易被 IDS 检测。

3.2 Python 实现:ARP + TCP 混合发现

下面这个脚本用 Scapy 做 ARP 扫描,再用原生 socket 对 ARP 结果之外的可疑地址做 TCP 端口探测,最后合并去重。相比直接调 nmap -sn,它更容易嵌入到自动化流程中。

#!/usr/bin/env python3
# arp_tcp_discover.py —— 仅用于授权测试环境
import ipaddress
import socket
import sys
from concurrent.futures import ThreadPoolExecutor

from scapy.all import ARP, Ether, srp, conf

conf.verb = 0

TCP_PROBES = [445, 3389, 22, 80, 135, 5985]


def arp_scan(cidr: str, timeout: int = 3):
    """ARP 扫描:同网段最可靠的主机发现方式"""
    pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=cidr)
    answered, _ = srp(pkt, timeout=timeout, iface_hint=cidr)
    return {rcv.psrc: rcv.hwsrc for _, rcv in answered}


def tcp_probe(ip: str, ports=TCP_PROBES, timeout=0.8):
    """对单个 IP 做 TCP 连接探测,返回开放的端口列表"""
    open_ports = []
    for port in ports:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(timeout)
        try:
            if s.connect_ex((ip, port)) == 0:
                open_ports.append(port)
        except OSError:
            pass
        finally:
            s.close()
    return ip, open_ports


def main(cidr: str):
    print(f"[*] 目标网段: {cidr}")
    alive = arp_scan(cidr)
    print(f"[+] ARP 存活主机 {len(alive)} 台")

    # 对 ARP 未响应但可能有业务的主机做 TCP 兜底(示例:取网段前 256 个地址)
    net = ipaddress.ip_network(cidr, strict=False)
    candidates = [str(h) for h in net.hosts()][:256]
    with ThreadPoolExecutor(max_workers=128) as pool:
        results = list(pool.map(tcp_probe, candidates))

    merged = {ip: {"mac": alive.get(ip, "-"), "ports": ports}
              for ip, ports in results if ports or ip in alive}
    for ip in sorted(merged, key=lambda x: tuple(map(int, x.split(".")))):
        info = merged[ip]
        print(f"  {ip:<16} MAC={info['mac']:<18} TCP={info['ports']}")
    return merged


if __name__ == "__main__":
    main(sys.argv[1] if len(sys.argv) > 1 else "192.168.10.0/24")

几点工程细节值得注意:

  • srp 的 timeout 不建议低于 2 秒,否则跨交换机或虚拟化环境会漏报;
  • 线程数控制在 128~256,超过 512 很容易触发交换机的 ARP 风暴抑制或安全设备的"扫描行为"告警;
  • 生产环境中,先做小范围抽样(如 /28)验证网段可达性和噪声水平,再决定是否扩大扫描范围。

此外,代码中 srp 的 iface_hint 参数在部分 Scapy 版本中并不存在,实际应使用 iface 显式指定网卡,或直接省略让 Scapy 自动选择路由。如果运行时报 TypeError,请检查 Scapy 版本并改为 srp(pkt, timeout=timeout, iface="eth0")。另一个常见问题是权限:Scapy 发送原始帧需要 root 权限,Windows 下需要安装 Npcap 并以管理员身份运行。如果不想处理这些依赖,可以用 nmap -sn -PR 替代 ARP 扫描,但自动化集成度会下降。

对于 TCP 探测部分,connect_ex 返回 0 表示端口开放,但要注意目标可能部署了 SYN Cookie 或连接限制,短时间内大量连接可能导致误判。优化思路是:先对 ARP 结果做 TCP 端口识别,再对 ARP 无响应的地址做少量端口探测,而不是全量扫描。这样既保证了覆盖率,又控制了噪声。

如果只是快速摸清网段,fscan 依然是最省事的:

# 存活探测 + 常见漏洞 + 弱口令一把梭(授权环境下使用)
fscan -h 192.168.10.0/24 -np -p 22,80,135,139,443,445,1433,3306,3389,5985 \
       -o /tmp/fscan_result.txt

# 跨网段时通过已控主机建立 SOCKS5 代理,再由 proxychains 转发
ssh -N -D 1080 user@jump-host
proxychains4 -f ./proxychains.conf nmap -sT -Pn -n --open -p 445 10.10.20.0/24

注意 proxychains 只支持 TCP 全连接扫描(-sT),不能用于 SYN 扫描和 UDP,这是新手最常踩的坑之一。

fscan 的 -np 参数表示跳过存活探测直接扫描端口,适合已知网段有主机但 ICMP 被禁的情况;-p 指定端口列表可以大幅减少扫描时间。但要注意,fscan 的弱口令爆破模块默认会尝试常见用户名密码,这在授权测试中可能触发账户锁定策略。建议先使用 -nobr 关闭爆破,仅做服务识别,待确认目标锁定策略后再针对性爆破。跨网段代理时,proxychains 的 DNS 解析也容易出问题,建议在配置文件中使用 proxy_dns 并指定 remote_dns_subnet,或者直接用 IP 地址避免 DNS 泄漏。

四、凭据获取与横向移动:从"能访问"到"能登录"

主机发现之后,真正决定渗透深度的是凭据。内网中的凭据来源远比想象中多:

  • Windows 内存:LSASS 进程中的明文密码、NTLM 哈希、Kerberos 票据(sekurlsa::logonpasswords);
  • 注册表与配置:HKLM\SAM、SECURITY 中的 LSA Secrets、组策略首选项 GPP 中的 cpassword;
  • 应用配置:Web 目录下的 web.config、application.yml、.env、Jenkins/GitLab 凭据;
  • 浏览器与终端工具:Xshell、SecureCRT、Navicat 的会话文件(这是国内内网横向成功率最高的路径之一)。

从形态上看,凭据可以分为三类:明文密码、NTLM 哈希、Kerberos 票据。明文密码可以直接用于所有认证协议,但获取难度最高,因为现代 Windows 默认开启 LSA Protection 和 Credential Guard,LSASS 内存中的明文密码会被加密或清除。NTLM 哈希可以用于哈希传递(PtH),但受 SMB 签名、NTLM 禁用策略影响。Kerberos 票据可以用于票据传递(PtT),包括黄金票据(伪造 TGT)和白银票据(伪造服务票据),但需要掌握 KRBTGT 哈希或服务账户哈希。

Windows 的凭据保护机制是横向移动的主要障碍。LSA Protection(RunAsPPL)会阻止非受保护进程读取 LSASS 内存;Credential Guard 使用虚拟化安全将凭据隔离在 VBS 中;AppLocker 和 WDAC 限制工具执行。绕过这些机制通常需要内核级漏洞或配置缺陷,例如通过 SeDebugPrivilege 配合 mimikatz 的 !+ 命令加载驱动,或者利用 procdump 转储 LSASS 后离线解析。在授权测试中,如果遇到 Credential Guard,应优先考虑从其他来源获取凭据,而不是强行突破,因为强行突破的噪声极大且可能造成系统不稳定。

Kerberos 攻击面同样值得关注。Kerberoasting 针对注册了 SPN 的服务账户,任何域用户都可以请求服务票据,离线破解其加密部分;AS-REP Roasting 针对未启用预认证的账户,直接请求 AS-REP 并离线破解;委派攻击利用非约束委派、约束委派和基于资源的约束委派,伪装成任意用户访问服务。这些攻击的共同特点是:不需要高权限,只需要一个普通域用户凭据,因此在内网渗透中极具价值。

NTLM Relay 是另一条高频路径,其前提是目标主机未开启 SMB 签名,且攻击者能诱使高权限用户或机器账户向攻击者控制的主机发起认证。常见组合是 Responder 捕获 NTLM 认证并转发到 ntlmrelayx,进而执行命令或转储域内哈希。防御措施包括启用 SMB 签名、禁用 NTLM、开启 LDAP 签名等。测试时可以通过 crackmapexec smb --gen-relay-list 快速筛选未签名的目标。

拿到 NTLM 哈希后,常见的选择是哈希传递(PtH),因为它不需要破解密码:

# 使用 impacket 验证凭据有效性,并批量测试可达主机的本地管理员权限
# (授权环境下使用,-hashes 格式为 LMHASH:NTHASH)
crackmapexec smb 192.168.10.0/24 -u administrator \
    -H 'aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0'

# 拿到本地管理员后,导出目标主机的 SAM / LSA / 域缓存凭据
impacket-secretsdump -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 \
    administrator@192.168.10.31 -just-dc-user krbtgt

这一阶段的核心判断是:这套凭据的"权限半径"有多大。同样是本地管理员,A 主机的本地管理员只能登录 A,而域管理员可以登录域内任意主机。判断依据是账户所在的组、是否有 SeDebugPrivilege、是否属于 Domain Admins / Enterprise Admins。

具体判断方法包括:使用 whoami /groups 查看当前令牌中的组;使用 net user /domain 查询域账户属性;使用 Get-ADUser -Identity <user> -Properties MemberOf 获取组成员关系;使用 BloodHound 分析 ACL 和会话。如果账户属于 Domain Admins,则可以直接登录域控;如果只是 Server Operators,则可能只能管理特定服务器;如果属于 Remote Desktop Users,则只能 RDP 登录。此外,还要检查账户是否被标记为“敏感账户,不能被委派”,以及是否受 LAPS 管理。这些细节决定了横向移动的目标选择。

横向移动工具的选择也直接影响隐蔽性。PsExec 会创建服务并留下事件日志;WMI 执行命令相对安静但依赖 WMI 服务;WinRM 走 5985/5986 端口,日志记录在 WinRM 事件中;SMB 文件拷贝加计划任务则更灵活但步骤多。在授权测试中,建议根据目标主机的日志审计强度选择工具,并尽量复用已有会话,减少新进程创建。

五、权限分析:把"当前身份"与"目标资源"画成一张图

权限分析是内网渗透中最容易被忽视、却最决定成败的一步。它包含两个层次:

  1. 当前权限盘点:我现在是谁?有哪些特权?能读什么、写什么、执行什么?
  2. 提权路径分析:从当前身份到更高权限,有哪些可行路径?哪条路径噪声最小?

5.1 Linux 下的权限快速盘点

#!/usr/bin/env bash
# priv_audit.sh —— Linux 提权信息收集(授权环境使用)
echo "===== [1] 当前身份与组 ====="
id; sudo -n -l 2>/dev/null

echo "===== [2] SUID / SGID 文件 ====="
find / -perm -4000 -o -perm -2000 -type f 2>/dev/null | sort

echo "===== [3] Capabilities(易被忽视的提权面)====="
getcap -r / 2>/dev/null

echo "===== [4] 可写的计划任务与 systemd 单元 ====="
ls -la /etc/cron* /var/spool/cron 2>/dev/null
find /etc/systemd/system -writable -type f 2>/dev/null

echo "===== [5] 内核版本(用于比对已知 LPE 漏洞)====="
uname -a; cat /etc/os-release 2>/dev/null | head -n 3

echo "===== [6] 敏感文件可读性 ====="
for f in /etc/shadow /root/.ssh/id_rsa /home/*/.bash_history; do
    [ -r "$f" ] && echo "READABLE: $f"
done

这个脚本的设计思路值得说明:不要只盯着 SUID。现代 Linux 提权的高频入口其实是 sudo -l 的 NOPASSWD 规则、cap_dac_read_search 之类的 capability、以及可写的 systemd 单元文件。把检查项按"命中概率 × 利用难度"排序,能显著缩短从立足点到 root 的时间。

进一步细化,Linux 提权检查清单可以按以下优先级排列:

优先级检查项典型利用
1sudo -l NOPASSWD直接执行 sudo /bin/bash 或利用已知二进制
2SUID 二进制find / -perm -4000,对比 GTFOBins
3Capabilitiesgetcap -r /,如 cap_setuid+ep
4可写 cron / systemd修改脚本或单元文件,等待 root 执行
5内核漏洞uname -r 比对 DirtyPipe、PwnKit 等
6环境变量与 PATH劫持 root 调用的命令
7NFS 配置no_root_squash 可写共享
8Docker 组挂载宿主机根目录

实战中,sudo -l 的输出往往比 SUID 更直接。例如,如果发现 (ALL) NOPASSWD: /usr/bin/find,可以直接执行 sudo find / -exec /bin/bash \; -quit 获得 root。如果发现 (ALL) NOPASSWD: /usr/bin/vim,则 sudo vim -c ':!/bin/bash' 即可。这些技巧在 GTFOBins 网站上有完整列表,建议测试时随身参考。

5.2 Windows 下的提权路径判断

Windows 侧的核心是 whoami /priv。几个高频特权直接对应已知的提权技术:

| 特权 | 典型利用方式 |

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

更多硬核网安与AI工具包,请扫码获取完整源码!

| — | — |
| SeImpersonatePrivilege | JuicyPotato / RoguePotato / PrintSpoofer(IIS、MSSQL 服务账户默认具备) |
| SeBackupPrivilege | 通过 robocopy /b 或 diskshadow 读取 SAM/SYSTEM |

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐