ADCS实战小坑记录

ADCS实战小坑记录

周二爆出了域内的ADCS提权漏洞,这两天刚好在实战环境中遇到了,本来以为一帆风顺的梭哈环节却练练遭遇坑点,最后在和团长的讨论中一一解决,这里记录一下。

因为项目很多没截图,有些就不贴图了,大家脑补一下

踩坑开始

这个项目通过VPN连进了内网,想着也有好几个用户凭据,直接梭哈新洞美滋滋,没想到很快就来到了第一个问题。

ldap错误

我一开始是通过文章里的 Certipy 工具去尝试攻击的,这个攻击流程的第一步是添加用户,并更改他的一些属性,这一步是通过ldap的。我直接使用

1
Certipy account create "domain/xxx:asdasd@10.10.1.1" -user x -dns dc.x.x

结果第一步就出问题了

Certipy 直接报错超时了。显示的是 ldap 监听失败

怎么会这样呢,我试了一下,域控的389端口是开的。我去跟一遍了他的代码,发现他最后会去走 ldaps ,再一看,域控的636是没开的,怪不得会说超时,于是我强行把协议改成了 ldap ,又试了一次,结果又了报一个错:"strongerAuthRequired"

于是我单独用 ldap3 库尝试去连接试了试,终于有了详细的报错

1
ldap3.core.exceptions.LDAPBindError: automatic bind not successful - "strongerAuthRequired"

这下我又仔细看了一遍代码,发现原来是因为ldap请求报了这个错,所以自动换了ldaps。

我查了一下,网上也说这个报错是需要套用ssl,那就还是使用了ldaps,,但是636端口又没开放,难顶。

解决:Powermad

BUT ,我使用 adfind.exe 导域信息又能成功的导出,而且导出信息写的还是走的域控的389端口。那么分析一下,adfind是c++写的,调用的是微软的原生类。而python的ldap3是自己封装的数据包

于是我觉得应该是python的 ldap3 库的ldap实现比较老了,但是不管什么情况,可以确定一点,那就是原生的system空间下的类应该可以连接成功。

所以我开始尝试寻找 Certipy 的代替品。突然想到之前委派使用过的一个工具: Powermad

Powermad_logo

image-20220515003151301

这个工具是专门用来添加机器账户的,由powershell编写,支持指定域控和凭据,非常方便。

他的readme里推荐配合 runas 一起用,不过我还是使用了他支持的 $Credential 定义,一顿摸索下终于解决了ldap的问题,成功添加了用户,并修改了相应的属性。

1
2
3
4
5
6
7
8
9
10
11
12
# run as administrator
> Set-ExecutionPolicy RemoteSigned

> Import-Module .\Powermad.ps1

# new machine
> $User = "Cia\b1ue"
> $PassWord = ConvertTo-SecureString -String "Admin123..." -AsPlainText -Force
> $Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User, $PassWord
> New-MachineAccount -MachineAccount b1uetest -Password $(ConvertTo-SecureString 1qaz@WSX -AsPlainText -Force) -DomainController 10.10.1.1 -domain cia.local -Credential $Credential
> Set-MachineAccountAttribute -domain cia.local -Credential $Credential -DomainController 10.10.1.1 -MachineAccount b1uetest -Attribute ServicePrincipalName -Value "HOST/b1uetest"
> Set-MachineAccountAttribute -domain cia.local -Credential $Credential -DomainController 10.10.1.1 -MachineAccount b1uetest -Attribute dNSHostName -Value "dc.cia.local"

smb错误

第二个报错是当我使用 Certipy 去向域控请求证书的时候,它提示 445 连接失败。

Certipy请求走的是rpc和smb,而vpn没有给域控的445端口连接权限。

解决:在域内getshell并反代

其实本来是准备通过 80 端口 http://dc_ip/certsrv/ 去申请证书,但是改代码太麻烦了。

运气不错,通过 CVE getshell 了一台内网机器,发现他是通域控的445的,于是决定通过这台机器做反代连通域控。

寻找CA名

当成功解决了连接域控的问题后,又遇到新的问题

Certipy 请求证书的命令为

1
certipy req "cia/b1uetest$:1qaz@WSX@10.10.1.1" -ca CIA-DC-CA -template Machine

其中 -ca 参数指定的是CA票据颁布者的名字,我一开始以为这个值是固定的 域名-域控名-CA 的组合,结果后来查询发现原来这个值是可以自己设置的。请求的时候又开始报错,当时就觉得应该是请求的名字错了。

解决:在CA的web端

一通尝试无果后,团长发现,在CA的web端,页面的顶端是有这个名字的。

image-20220515004551712

当然后来查询资料得知,这个值在域信息中也是有的。

模板错误

我们使用了正确的CA名请求后,又给了我们一个新的报错

image-20220515004815423

说我当前用户没有权限请求这个模板,这个错误当时真的让我们很绝望,一度以为是这个漏洞被修补了,非常难受。我们当时猜测可能是管理员为了缓解这个漏洞,将 Machine 模板直接设置了不可请求,那这个洞也就彻底利用不了了。

我和团长相顾无言了数十分钟,一度准备放弃。但是我又考虑,如果真的修补了,为什么我还能修改机器的 dNSHostName 为域控,这个应该是最容易修补的地方才对。

我在我的实验环境里顺手又请求了一次,但是换了 User 凭证,然后他也报了同样的错。

这意味着,**如果请求错了模板类型,就会报这个错**

顺着这个思路我们想,难道是 Machine 类型错了,但是机器用户确实就应该是 Machine 类型。团长说可能他把 Machine 改名了。

解决:啼笑皆非

于是我决定去查询一下域内现有的模板,如果没有 Machine,那就印证了团长的猜测。

模板内容同样可以通过域信息查询,我直接使用 adexploer 查询

image-20220515010219124

就在 Configuration -> Services -> Public Key Service -> Certificate Templates 条目

我们发现确实有 Machine ,非常失望

就在准备关掉时,我突然发现了一个模板名:**电脑(新)**

image-20220602022754988

我抱着尝试一下的想法试了试,,,,**居然成功了**,,,,

结论是:**当报上述没有权限的错误时,记得去查看一下现有模板。**


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!