文章的图片看的不太清楚,因为没法贴base64编码的img进来,好像也没办法引用外部图床的图片,只能将就用freebuf自己的图床了,看不清楚可以去我的github上看pdf():
这是个windows的靶场:
一开始常规的nmap扫描
发现88端口开放,这很可能是个kdc兼domain的靶机,同时开放了ldap,smb服务。
在机器的描述中给出了一个用户的账户密码 P.Rosa / Rosaisbest123
尝试用nxc登录:
登录出错,但是可以看到domain是vintage.htb
Google发现这个错误可能是kdc禁用了NTLM认证,这个是nxc的默认认证方式,实际上windows server的默认认证方式是Kerberos,只有启用了protocol transition才能用NTML访问需要Kerberos认证的服务,其中用到了委派机制,后面会展开讲讲。这也暗示了protocol
Transition是关闭的。
尝试用Kerberos认证:
已经登录成功
接下来是信息收集的环节
先在/etc/hosts中添加dc01.vintage.htb,
然后ldap查询所有用户:
这里有几个很有趣的用户:xxxx$,svc_xxx,gMSA01$,还有xxxx_adm,一个个来看看这些用户的组和description:
DC01是domain controller
FS01$:
fs是pre2000用户,是在windows2000中预设的用户,意味着它的默认密码很可能是小写的用户名fs01:
尝试登录就会发现确实是这样,这个账户是属于computers CN,可以任意修改自己的ACL或者创建新的computer,目前不知道是否有用。
用户名svcxxx属于serviceaccounts,用户gmsa01属于Managed Service Accounts,C.Neri属于serviceaccountmanager,xxx_adm属于delegated admins
接下来需要了解一下这些用户和组之间的权限关系:
Servicemanager对serviceaccount具有大部分权限,以svc_sql为例:
查看delegated_admins的ACE:
Xxxx_adm对这个group具有写属性的权限
然后权限的事情暂时先放一边
先看看对哪些用户有控制,目前有fs01,P.Rosa,我们可以尝试去搜索一下有没有可以读取的密码:
基于fs01具有稍微高一点的权限,用fs01账号来搜索msds-managedpassword属性:
确实找到了,去掉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),但是:
这是未配置的,还剩下一种RBCD ABUSE,是否可行?
先看这张攻击流程图
前置知识:
--------------------------------------------------------
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。注意:
- s1不会自己发送带上rbcd bit的请求,因此,攻击者需要有控制s1账户的能力,用impacket的getST的时候,这个bit会被自动设置RBCD_ABUSE
- 向kdc请求成功的s4u2proxy请求总是返回forwardable的st
(https://eladshamir.com/2019/01/28/Wagging-the-Dog.html#serendipity)
尝试找一下哪个用户设置了这个,确实可以找到:
一个是fs01的(应该是别人设置的,当然自己也可以设置),一个是dc01的
看看dc01的指向哪个对象:
是delegatedadmins,也就是说,如果能够控制一个delegatedadmin,我们可以直接获得最高权限。
现在尝试用smb能不能读C$:
不但不能读,其它文件夹也没有什么有用的文件
常规思路都不行,那么试试爆破吧,直接爆破肯定是不行的,用户很多,而且认证速度奇慢,存在一种叫做ASREPROAST的方法,这种方法的原理是,对于可以在object的uac对象设置DONT_REQ_PREAUTH位的账户(0x400000),在向服务器发起AS_REQ的时候服务器不会验证是否提供了正确的密码或者凭证,如果服务器支持RC4加密(在as_req指定),那么服务器会用NT HASH加密一个nonce发回来。如图:
这个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:
设置环境变量:
测试的时候发现GMSA自己移动到serviceaccountmanager组貌似不会继承这个组的权限,但是用P.Rosa或者fs01都可以:
导出userlist:
前面几行不管了,手动删除也可以,其实这里有几个用户没显示出来,比如fs01,但是不重要了,主要是svc_开头的
使用netexec去获得asreproast中用NTLM hash加密的部分,后续用jonh the ripper去爆破
这里不用指定-k,当然指定也可以,你会发现svc_sql不见了,其实是这个账户被禁用了:
’userAccountControl: 4260354的hex是0x410202
这里就可以看出来了,问题不大,我们权限足够,启用就可以:
动作要快,靶机有自动重置权限的脚本,一段时间就会自动运行一次
然后把流程重新走一遍就正常了:
结果:
这个账户的密码是得到了,但是它只是一个serviceaccount,rbcd abuse要求有一个被特权服务的msds-allowedtoactonbehalfofotherentity指定的服务,所以还是不满足要求,不过,我们可以用user.txt去试一下有没有其它用户和它密码是一样的,P.Rosa和fs01也可以一起试试,最终会发现C.Neri也是这个密码,这个技巧其实在htb是挺常见的
那么得到C.Neri / Zer0the0ne,这个用户有什么用?看看:
Remote managerment user,也就是可以远程登录ps,我们用winrm试试:
不要用impacket的psexxec或者winrmexec,它们会自动连接smb,会有权限问题
接下来尝试权限提升
你会发现所有上传的可执行文件似乎都被禁用了,实际上靶机是有杀软的(没去试免杀,但是免杀也难提权啊)。
执行whoami /priv你会发现这是个低权限用户,但是翻一下C.Neri用户的文件夹会发现roaming下有东西的:
Windows下有一个机制,我们经常看见浏览器自动填写账户密码,实际上它们被用用户的RSA keys加密后存放在credentials目录下,而这些RSA keys被放在protected目录下的{sid},这个文件中除了加密的RSA KEYS,还会有一个加密过的叫master key的对称密钥,可以解密RSA的私钥,因此,对protected目录有访问权限,并且有登录密码,意味着可以解密一些敏感数据:
其中就可能包括其它用户的远程登录密码
(https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/dpapi-extracting-passwords)
我们来尝试获取一下用户的私钥
直接用download会出现IOT错误,用base64编码后复制到本地:
导出密码:
看看credentials目录的内容:
不知道哪个主密钥是被用来加密它的,都试一下就好:
于是又得到了一个用户的密码,这个用户不是远程登录用户(远程登录用户必须是remote manager组,local admins,domain admins其中之一),因此没法evil-winrm
之前提到过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会失败:
C.Neri_adm对自己只有有read权限:
SPN的访问控制是更加精细的,添加spn需要validate-spn,比如fs就有(computer组都有这个权限):
或者,有self:
实际上,之前提到过,servicemanagers对serviceaccount有高权限,其中就包括self(其实是genericall包括了这个self):
现在有点尴尬了,有delegate flag的用户没有SPN,能添加SPN的用户不在delegatedadmins当中。
但是,我们可以用C.Neri对serviceaccount添加SPN(随便叫什么),然后用C.Neri_adm移动到delegated admins组,这样就可以用这个serviceaccount实现RBCD ABUSE(这个serviceaccount应该要是svc_sql,因为我们只知道它的密码):
防止之前启用的svc_sql被重置:
拿个TGT(可以跳过这步,但是后面得输入密码):
我们要代表谁去访问dc01的cifs呢?
当然要是高权限用户,administrator,dc01,L.Bianchi_adm(domainadmin)之一,以administrator为例:
上图中getST部分就是s4u2self+s4u2proxy的集成操作。获取ST后,可以访问cifs服务(注意,只能访问cifs服务,这是st和TGT的区别)。Cifs是基于smb,我们可以用smb来在C$读取root.txt,但是上面的读取失败了,因为administrator是被禁止访问cifs的,DC01也是一样的,但是L.Bianchi_adm可以:
然后
事实上不止可以读取文件,Smbexec还能用smb来实现远程的cmd.exe执行,我想说的是为什么cifs通过smb文件传输能够实现命令执行:
原理是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
就好..................
Asreproast一眼就看出来了...,省了前面很多分析的时间
你也会看到L.Bianchi_adm有dcsync的权限,但是没什么用,你只有L.Bianchi_adm对cifs的ST,访问不了RPC 的。
https://www.hackthebox.com/achievement/machine/2092385/637