freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

hackthebox vintage writeup
2024-12-08 22:08:32
所属地 山东省

文章的图片看的不太清楚,因为没法贴base64编码的img进来,好像也没办法引用外部图床的图片,只能将就用freebuf自己的图床了,看不清楚可以去我的github上看pdf():

这是个windows的靶场:

一开始常规的nmap扫描

1733665606_6755a34614d242f978c26.png!small

发现88端口开放,这很可能是个kdc兼domain的靶机,同时开放了ldap,smb服务。

在机器的描述中给出了一个用户的账户密码 P.Rosa / Rosaisbest123

尝试用nxc登录:

1733665610_6755a34ab0525ebb52002.png!small

登录出错,但是可以看到domain是vintage.htb

Google发现这个错误可能是kdc禁用了NTLM认证,这个是nxc的默认认证方式,实际上windows server的默认认证方式是Kerberos,只有启用了protocol transition才能用NTML访问需要Kerberos认证的服务,其中用到了委派机制,后面会展开讲讲。这也暗示了protocol

Transition是关闭的。

尝试用Kerberos认证:

1733665615_6755a34f30b7d2ce9caf7.png!small

已经登录成功

接下来是信息收集的环节

先在/etc/hosts中添加dc01.vintage.htb,

然后ldap查询所有用户:

1733665621_6755a35534094cef07230.png!small

这里有几个很有趣的用户:xxxx$,svc_xxx,gMSA01$,还有xxxx_adm,一个个来看看这些用户的组和description:

DC01$:

1733665629_6755a35da01f5a6d879be.png!small

DC01是domain controller

FS01$:

1733665637_6755a3656bd07cf500198.png!small

fs是pre2000用户,是在windows2000中预设的用户,意味着它的默认密码很可能是小写的用户名fs01:

1733665642_6755a36a231a088ed1ddd.png!small

尝试登录就会发现确实是这样,这个账户是属于computers CN,可以任意修改自己的ACL或者创建新的computer,目前不知道是否有用。

用户名svcxxx属于serviceaccounts,用户gmsa01属于Managed Service Accounts,C.Neri属于serviceaccountmanager,xxx_adm属于delegated admins

接下来需要了解一下这些用户和组之间的权限关系:

Servicemanager对serviceaccount具有大部分权限,以svc_sql为例:

1733665648_6755a3709178d41b2974f.png!small

查看delegated_admins的ACE:

1733665653_6755a375f1f30d2f9a983.png!small

Xxxx_adm对这个group具有写属性的权限

然后权限的事情暂时先放一边

先看看对哪些用户有控制,目前有fs01,P.Rosa,我们可以尝试去搜索一下有没有可以读取的密码:

基于fs01具有稍微高一点的权限,用fs01账号来搜索msds-managedpassword属性:

1733665659_6755a37bba41ca75077a9.png!small

确实找到了,去掉grep不难发现这是gmsa01的ntlm HASH,那么我们可以pass the ticket来获取GMSA01的TGT,GMSA01就是servieaccountmanager

现在的信息是否足以构成攻击链呢?

首先,protocol transition(PT)是关闭的,因此S4U2self永远返回的是没有forwardable flag的ST,几个著名的攻击方法

(ref https://www.thehacker.recipes/ad/movement/kerberos/delegations/constrained)

中比较有可行性的是KCD和RBCD ABUSE,因为KUD需要等待高权限用户主动访问service,但是高权限用户我们目前一个都没有,最高权限的就是GMSA01了,

因此不考虑。KCD需要msDS-AllowedToDelegateTo被设置为需要访问的service(通常是高权限用户的SPN),但是:

1733665670_6755a386d70f5ff80652a.png!small

这是未配置的,还剩下一种RBCD ABUSE,是否可行?

先看这张攻击流程图

1733665676_6755a38c024246dead2ff.png!small

前置知识:

--------------------------------------------------------

S4U2self:任意服务(具有spn)都可以随时向kdc发起S4U2self请求,这种请求的含义是“我想代表某个用户访问自己”,无论TrustedToAuthForDelegation,UserAccountControl flag 是否被设置,但是,如果PT未对该用户开启,或者上面提到的两个属性未被设置,这个请求的响应(含有对目标服务的ST)不会含有forwardable flag,也就是说这个ST在之后的S4U2proxy是无用的(kdc不会返回有效的ST)。(forwardable flag决定目标服务是否接受这个ST)

S4U2proxy:这个请求需要一个service持有一个具有forwardable flag的ST(通常是通过S4U2self获得的),kdc会返回一个ST,允许这个服务以之前的ST中它代表的用户访问其它服务,换句话说,假设有admin,S1(service),S2(特权服务),那么在S1开启了PT,设置了相应的属性的时候,S1向kdc请求ST(admin->s1) (这就是S4U2self),接着,S1向kdc请求ST(admin->s2),带上之前的ST(admin->s1)作为addition ST,验证成功kdc(需要forwardable设置,还需要S1被设置了allowtodelegateto)会返回一个ST(admin->s2) (这就是s4u2proxy,proxy就是s2),最后s1可以在不知道admin密码的情况下获得特权去访问s2

RBCD abuse攻击的原理:,S4U2proxy本来需要forwardable设置,还需要S1被设置了allowtodelegateto,但是ms2012之后出现了一种叫做RBCD的功能,只要s2设置了msDS-AllowedToActOnBehalfOfOtherIdentity属性,值为s1的nt-sec-desc,(有特定的格式,其中含有s1的sid),那么如果s1在向kdc的s4u2proxy请求中带上了rbcd bit,那么无论是否有forwardable或者s1有没有allowtodelegateto,kdc会接受s4u2self的st,并且返回一个forwardable的st用于访问s2。注意:

  1. s1不会自己发送带上rbcd bit的请求,因此,攻击者需要有控制s1账户的能力,用impacket的getST的时候,这个bit会被自动设置RBCD_ABUSE
  2. 向kdc请求成功的s4u2proxy请求总是返回forwardable的st

(https://eladshamir.com/2019/01/28/Wagging-the-Dog.html#serendipity)

尝试找一下哪个用户设置了这个,确实可以找到:

1733665686_6755a39672ec0f926d7f3.png!small

一个是fs01的(应该是别人设置的,当然自己也可以设置),一个是dc01的

1733665754_6755a3da402f489e949da.png!small

看看dc01的指向哪个对象:

1733665758_6755a3de19d3e19207216.png!small

是delegatedadmins,也就是说,如果能够控制一个delegatedadmin,我们可以直接获得最高权限。

现在尝试用smb能不能读C$:

1733665768_6755a3e8ae29f6e5cabeb.png!small

不但不能读,其它文件夹也没有什么有用的文件

常规思路都不行,那么试试爆破吧,直接爆破肯定是不行的,用户很多,而且认证速度奇慢,存在一种叫做ASREPROAST的方法,这种方法的原理是,对于可以在object的uac对象设置DONT_REQ_PREAUTH位的账户(0x400000),在向服务器发起AS_REQ的时候服务器不会验证是否提供了正确的密码或者凭证,如果服务器支持RC4加密(在as_req指定),那么服务器会用NT HASH加密一个nonce发回来。如图:

1733665774_6755a3ee2149ede27d50b.png!small

这个user hash就可以离线爆破,用hashcat或者jonh the ripper,字典通常用rockyou.txt

我们的目标是找到可以设置DONT_REQ_PREAUTH的账户,换句话说,要有某个账户,对一组账户具有write权限,这个账户目前只能是GMSA01,就像一开始说的serviceaccountmanager对service account具有写权限,serviceaccount以svc开头,而gmsa01可以把用户移动到非特权组,因此我们要把一个用户移动到serviceaccountmanager下,然后以对应用户的身份对这些serviceaccount设置相应flag,这可以用bloodyAD来完成。

先获得GMSA01$的TGT:

1733665778_6755a3f2bc08eab7355ec.png!small

设置环境变量:

1733665782_6755a3f6ac8c49650ad09.png!small

测试的时候发现GMSA自己移动到serviceaccountmanager组貌似不会继承这个组的权限,但是用P.Rosa或者fs01都可以:

1733665788_6755a3fc52db5e6861561.png!small

导出userlist:

1733665794_6755a402526e33d2919c5.png!small

前面几行不管了,手动删除也可以,其实这里有几个用户没显示出来,比如fs01,但是不重要了,主要是svc_开头的

使用netexec去获得asreproast中用NTLM hash加密的部分,后续用jonh the ripper去爆破

1733665800_6755a4085e5e8df3b4507.png!small

这里不用指定-k,当然指定也可以,你会发现svc_sql不见了,其实是这个账户被禁用了:

1733665809_6755a411465c6dd42e859.png!small

’userAccountControl: 4260354的hex是0x410202

1733665827_6755a42382353ef9af418.png!small

这里就可以看出来了,问题不大,我们权限足够,启用就可以:

动作要快,靶机有自动重置权限的脚本,一段时间就会自动运行一次

1733665939_6755a493d0c5ad1725e98.png!small

然后把流程重新走一遍就正常了:

1733665948_6755a49c73c63ddf0557b.png!small

结果:

1733665845_6755a4355cd84e43ce380.png!small

这个账户的密码是得到了,但是它只是一个serviceaccount,rbcd abuse要求有一个被特权服务的msds-allowedtoactonbehalfofotherentity指定的服务,所以还是不满足要求,不过,我们可以用user.txt去试一下有没有其它用户和它密码是一样的,P.Rosa和fs01也可以一起试试,最终会发现C.Neri也是这个密码,这个技巧其实在htb是挺常见的

1733665972_6755a4b4424ffa7ebe047.png!small

那么得到C.Neri / Zer0the0ne,这个用户有什么用?看看:

1733665977_6755a4b9b0604d43d56c1.png!small

Remote managerment user,也就是可以远程登录ps,我们用winrm试试:

1733665983_6755a4bfbe6194ded4ccb.png!small

不要用impacket的psexxec或者winrmexec,它们会自动连接smb,会有权限问题

接下来尝试权限提升

你会发现所有上传的可执行文件似乎都被禁用了,实际上靶机是有杀软的(没去试免杀,但是免杀也难提权啊)。

执行whoami /priv你会发现这是个低权限用户,但是翻一下C.Neri用户的文件夹会发现roaming下有东西的:

1733665996_6755a4ccc11f2d85ffd18.png!small

Windows下有一个机制,我们经常看见浏览器自动填写账户密码,实际上它们被用用户的RSA keys加密后存放在credentials目录下,而这些RSA keys被放在protected目录下的{sid},这个文件中除了加密的RSA KEYS,还会有一个加密过的叫master key的对称密钥,可以解密RSA的私钥,因此,对protected目录有访问权限,并且有登录密码,意味着可以解密一些敏感数据

1733666005_6755a4d53ff8a5391a40b.png!small

其中就可能包括其它用户的远程登录密码

(https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/dpapi-extracting-passwords)

我们来尝试获取一下用户的私钥

1733666017_6755a4e19fae4c3399b3b.png!small

直接用download会出现IOT错误,用base64编码后复制到本地:

1733666041_6755a4f9b81c685769a55.png!small

1733666046_6755a4fed297b8849a4d1.png!small

1733666058_6755a50a168ba7ddf4790.png!small

导出密码:

1733666031_6755a4ef178afe4522d20.png!small

看看credentials目录的内容:

1733666079_6755a51fb2869a04cc4f6.png!small

1733666083_6755a523dea9ec99be0e3.png!small

不知道哪个主密钥是被用来加密它的,都试一下就好:

1733666088_6755a528ee0c7b994fccd.png!small

于是又得到了一个用户的密码,这个用户不是远程登录用户(远程登录用户必须是remote manager组,local admins,domain admins其中之一),因此没法evil-winrm

1733666092_6755a52cd597c685fdcc9.png!small

之前提到过delegatedadmins和dc01的关系,delegatedadmins可以代表任何账户去访问dc01的所有服务,只要用RBCD ABUSE就可以了,但是delegatedadmins本身必须有SPN(serviePrincipleName),不然kdc会报错,C.Neri_adm本身是没有这个属性的(见上图),因此我们需要想办法添加这个属性,一但添加了这个属性,我们就有办法用控制的账户去访问DC01的服务,由于DC01是domain controller,这个靶机是单域的,因此就可以访问所有域上的服务,当然,这并不能直接拿到root权限,但是可以访问DC01的CIFS,这是smb的早期版本,我们可以用root的访问权限去读取c$中的root.txt(执行不了powershell,相当于是获得了在smb中活动的最高权限)。

但是,尝试给C.Neri_adm自己添加SPN会失败:

1733666100_6755a534228a9ce7998d0.png!small

C.Neri_adm对自己只有有read权限:

1733666104_6755a538475fe23b1ed69.png!small

SPN的访问控制是更加精细的,添加spn需要validate-spn,比如fs就有(computer组都有这个权限):

1733666109_6755a53d40d09119c23d9.png!small

或者,有self:

1733666115_6755a5436dcd31bb9201f.png!small

实际上,之前提到过,servicemanagers对serviceaccount有高权限,其中就包括self(其实是genericall包括了这个self):

1733666120_6755a54825ac4440e6f73.png!small

现在有点尴尬了,有delegate flag的用户没有SPN,能添加SPN的用户不在delegatedadmins当中。

但是,我们可以用C.Neri对serviceaccount添加SPN(随便叫什么),然后用C.Neri_adm移动到delegated admins组,这样就可以用这个serviceaccount实现RBCD ABUSE(这个serviceaccount应该要是svc_sql,因为我们只知道它的密码):

1733666125_6755a54d27731a2a3e80a.png!small

1733666129_6755a551ef54166c62829.png!small

防止之前启用的svc_sql被重置:

1733666137_6755a5591f220f9a28bcd.png!small

拿个TGT(可以跳过这步,但是后面得输入密码):

1733666141_6755a55de876c15ad54fc.png!small

我们要代表谁去访问dc01的cifs呢?

当然要是高权限用户,administrator,dc01,L.Bianchi_adm(domainadmin)之一,以administrator为例:

1733666157_6755a56d0927b9f71e225.png!small

上图中getST部分就是s4u2self+s4u2proxy的集成操作。获取ST后,可以访问cifs服务(注意,只能访问cifs服务,这是st和TGT的区别)。Cifs是基于smb,我们可以用smb来在C$读取root.txt,但是上面的读取失败了,因为administrator是被禁止访问cifs的,DC01也是一样的,但是L.Bianchi_adm可以:

1733666163_6755a57381237d38e1b66.png!small

然后

1733666169_6755a579ba746c7f07663.png!small

事实上不止可以读取文件,Smbexec还能用smb来实现远程的cmd.exe执行,我想说的是为什么cifs通过smb文件传输能够实现命令执行:

1733666179_6755a583a23a871a498d3.png!small

原理是Smbexec通过smb的$IP管道向远程windows服务器上注册服务,这个服务启动后会监听我们机器发送的指令并且用cmd.exe执行,然后把结果放在c:\__output,smbexec会读取并且显示结果,就像打开了远程shell一样,结束会话后这个文件会被删掉

(https://www.cybertriage.com/blog/dfir-breakdown-impacket-remote-execution-activity-smbexec/)

这个靶机smb足够了

后来发现信息搜集直接

bloodhound-python --zip -u P.Rosa -p 'Rosaisbest123' -d vintage.htb -c All -dc dc01.vintage.htb

就好..................

1733666191_6755a58f9a5b76fa86560.png!small

Asreproast一眼就看出来了...,省了前面很多分析的时间

1733666198_6755a5966dbb9abb2e5d5.png!small

你也会看到L.Bianchi_adm有dcsync的权限,但是没什么用,你只有L.Bianchi_adm对cifs的ST,访问不了RPC 的。

https://www.hackthebox.com/achievement/machine/2092385/637

1733666783_6755a7df9470b93f63575.png!small

# 网络安全 # web安全 # 内网渗透
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者