返回
顶部

国庆快乐!!!

image-20210930163736840

references:

前言

AD域内横向方式千千万,创建GPO算一个,但是这篇文章的主题并不是如何创建GPO,而是由创建GPO所引发的一系列问题

正文

在域内,我们用于横向的工具有很多,但是大部分工具在执行命令时的身份都是NT Authority\System,比如impacket工具包中的atexec.py

在本文中,当使用atexec创建GPO时,会出现如下报错

image-20210930164936525

从报错来看,我们遇到了认证错误,可是这条创建GPO的命令是使用atexec.py在DC上使用域管的凭证运行的,为什么还会出现认证错误呢?

这时候就需要通过审计Windows的安全日志来排查错误了,我的测试环境是两台DC,在运行命令的这台DC上我并没有发现什么可疑的登录记录,但是在另一台DC的安全日志上,我发现了下面这条日志:

image-20210930165503502

192.168.46.198是刚才执行创建GPO命令的那台DC的IP,可以看到进行认证的用户是该DC的机器账户WRSD$

那么问题是不是出在这里呢?

System账户在本地的权限固然无限大,它可以读写任意的对象,但是当访问网络资源时,它只是域内的一个机器账户

那么为什么在当前DC上创建GPO需要去访问另一台DC呢?

FSMO

所谓FSMO即Flexible Single Master Operations,灵活单主机操作模式

我们都知道,Windows AD是一个多主机环境,大的企业内网中可能同时存在数十台DC,每个DC都持有一个数据库,那么肯定就牵涉到同步问题,既然有同步那么就肯定会有冲突发生,某些对象的更新冲突可以通过算法来解决,但是有一些特定的对象的更新应该极力避免冲突的产生,GPO对象就是其中一种

这种对象只能够在众多DC中的一台上进行更新,其他DC只能够从该DC同步更新,而不能独自处理该对象的更新

这个就叫做单主机操作模式,它的存在就是为了规避冲突的产生,FSMO角色一共有五种:

  • Schema master FSMO
  • Domain naming master FSMO
  • RID master FSMO
  • PDC模拟器FSMO
  • infrastructure master FSMO

每种角色的具体功能XDM自行百度,不再赘述

我们关心的只有PDC模拟器FSMO角色,因为只有持有该角色的DC才能够对GPO进行更新,其他的DC要想对GPO进行更新必须要向该DC发起请求

这也是上面我们执行命令的DC为什么会向另一台DC发起登录请求的原因

可以使用netdom query fsmo命令查询域内的所有FSMO角色

image-20210930171225204

数据包分析

只凭一条日志我们并不能很明确地锁定问题根源,下面我们通过万能的Wireshark来分析一下网络数据包

通过创建计划任务来将用户身份提升为System账户

schtasks /create /tn gpo_create /tr "C:\1.bat" /sc monthly /d 15 /ru System

schtasks /run /tn gpo_create 

运行该计划任务后即可在Wireshark中看到数据包

1632993661448

可以看到,并没有获取Kerberos票据的数据包,而是直接使用ldap票据请求了PDC的LDAP服务,并且认证成功了(下面的响应包返回了success)

是不是很郁闷?它哪来的票据?

即使你执行一百遍klist purge来清除本地缓存的票据,你还是抓不到Kerberos数据包

其实原因很简单,klist purge清除的是当前用户的票据,而你需要清除的是计算机账户的票据

你需要的是下面这条命令

klist -li 0x3e7 purge

1632994031257

此时再重新抓包

1632994098516

由于计算机账户的本地票据缓存被清除,再次创建GPO时便会重新向KDC申请票据

Kerberos keytab

此时我们引入keytab文件对Kerberos数据包进行解密

keytabkey table(秘钥表)

众所周知,Kerberos协议的第一个包通常为AS-REQ,这个数据包向KDC证明自己的身份,KDC认证通过后,会通过AS-REP数据包返回session keytgt ticket,该数据包使用由用户密码生成的key进行加密

而keytab文件中就包含这一个key,有了这个key,Wireshark就可以解密AS-REP数据包中的session key,有了session key便可以对后续的TGS-REQAP-REQ数据包中的authenticator字段进行解密,这里对AP-REQ的解密还牵涉到另一个session key,具体细节XDM可以通过流程图自行分析

生成keytab的方法如下:

使用DC自带的ktpass.exe

  • 用户账户
ktpass -out Administrator.keytab -princ Administrator@MOTHER.FUCKER -mapUser Administrator@MOTHER.FUCKER -pass qwe123... -crypto all -ptype KRB5_NT_PRINCIPAL
  • 计算机账户
ktpass -out WIN-55D8GK824HO$.keytab -princ WIN-55D8GK824HO$@MOTHER.FUCKER -mapUser WIN-5D8GK824HO$@mother.fucker -pass "*" -crypto all -ptype KRB5_NT_PRINCIPAL setpass

计算机账户的密码可以通过dump lsass来获取到

最后加了一个setpass选项,不然会导致计算机账户重置,进而引起对应计算机与DC之间的NetLogon安全通道建立失败(计算机账户hash不一致),最后会由于信任关系建立失败而导致无法登录到该计算机

Capture

将生成好的keytab文件加载到wireshark进行解密,即可看到所有加密数据的内容

1632994971879

在解密后的authencator字段中可以看到账户名为计算机账户

1632995123288

在解密后的数据包中,我们可以看到计算机账户尝试创建GPO的整个过程(LDAP),最后由于权限不足创建失败

1632995224930