Windows内网协议学习Kerberos篇之PAC


Windows内网协议学习Kerberos篇之PAC

文章插图
 
前言这篇文章主要讲的内容是微软为了访问控制而引进的一个扩展PAC,以及PAC在历史上出现过的一个严重的,允许普通用户提升到域管的漏洞MS14068 。
 
一.PAC介绍网上很多版本的kerberos的流程是
1.用户向KDC发起AS_REQ,请求凭据是用户hash加密的时间戳,KDC使用用户hash进行解密,如果结果正确返回用krbtgt hash加密的TGT票据
 
2.用户凭借TGT票据向KDC发起针对特定服务的TGS_REQ请求,KDC使用krbtgt hash进行解密,如果结果正确,就返回用服务hash 加密的TGS票据
 
3.用户拿着TGS票据去请求服务,服务使用自己的hash解密TGS票据 。如果解密正确,就允许用户访问 。
上面这个流程看起来没错,却忽略一个最重要的因素,那就是用户有没有权限访问该服务,在上面的流程里面,只要用户的hash正确,那么就可以拿到TGT,有了TGT,就可以拿到TGS,有了TGS,就可以访问服务,任何一个用户都可以访问任何服务 。也就是说上面的流程解决了”Who am i?”的问题,并没有解决 “What can I do?”的问题 。
 
为了解决上面的这个问题,微软引进了PAC,引进PAC之后的kerberos流程变成
 
1.用户向KDC发起AS_REQ,请求凭据是用户hash加密的时间戳,KDC使用用户hash进行解密
如果结果正确返回用krbtgt hash加密的TGT票据,TGT里面包含PAC,PAC包含用户的sid,用户所在的组 。
Windows内网协议学习Kerberos篇之PAC

文章插图
 
2.用户凭借TGT票据向KDC发起针对特定服务的TGS_REQ请求,KDC使用krbtgt hash进行解密
如果结果正确,就返回用服务hash 加密的TGS票据(这一步不管用户有没有访问服务的权限,只要TGT正确,就返回TGS票据,这也是kerberoating能利用的原因
 
任何一个用户,只要hash正确
可以请求域内任何一个服务的TGS票据,具体内容可以参考windows内网协议学习Kerberos篇之TGSREQ& TGSREP)
 
3.用户拿着TGS票据去请求服务,服务使用自己的hash解密TGS票据 。
如果解密正确,就拿着PAC去KDC那边询问用户有没有访问权限,域控解密PAC 。
获取用户的sid,以及所在的组,再判断用户是否有访问服务的权限,有访问权限(有些服务并没有验证PAC这一步
这也是白银票据能成功的前提,因为就算拥有用户hash,可以制作TGS,也不能制作PAC,PAC当然也验证不成功,但是有些服务不去验证PAC,这是白银票据成功的前提)就允许用户访问 。
 
特别说明的是,PAC对于用户和服务全程都是不可见的 。只有KDC能制作和查看PAC 。
 
二.PAC结构PAC的结构如下图所示 。
Windows内网协议学习Kerberos篇之PAC

文章插图
 
PAC整体的结构上是一个AuthorizationData的结构
AuthorizationData ::= SEQUENCE OF SEQUENCE {ad-type [0] Int32,ad-data [1] OCTET STRING}AuthorizationData结构的ad-type主要有以下几个
AD-IF-RELEVANT 1AD-INTENDED-FOR-SERVER 2AD-INTENDED-FOR-AppLICATION-CLASS 3AD-KDC-ISSUED 4AD-AND-OR 5AD-MANDATORY-TICKET-EXTENSIONS 6AD-IN-TICKET-EXTENSIONS 7AD-MANDATORY-FOR-KDC 8Reserved values 9-63OSF-DCE 64SESAME 65AD-OSF-DCE-PKI-CERTID 66 (hemsath @us.ibm.com)AD-WIN2K-PAC 128 (jbrezak @exchange.microsoft.com)AD-ETYPE-NEGOTIATION 129 (lzhu @windows.microsoft.com)如上图所示,整个PAC最外层的ad-type为AD-IF-RELEVANT,ad-data还是一个AuthorizationData结构 。
这个AuthorizationData的ad-type 为AD-WIN2K-PAC,ad-data为一段连续的空间,
这段空间包含一个头部PACTYPE以及若干个PAC_INFO_BUFFER
头部PACTYPE包括cBuffers,版本以及缓冲区,PAC_INFO_BUFFER为key-value型的
key 的类型如下表所示
 
Windows内网协议学习Kerberos篇之PAC

文章插图
 

Windows内网协议学习Kerberos篇之PAC

文章插图
 
下面详细介绍四个比较重要的
 
0x00000001 KERBVALIDATIONINFO
这个结构是登录信息,也是整个PAC最重要的部分,整个PAC就靠它来验证用户身份了,是个结构体,如下
typedef struct _KERB_VALIDATION_INFO {FILETIME LogonTime;FILETIME LogoffTime;FILETIME KickOffTime;FILETIME PasswordLastSet;FILETIME PasswordCanChange;FILETIME PasswordMustChange;RPC_UNICODE_STRING EffectiveName;RPC_UNICODE_STRING FullName;RPC_UNICODE_STRING LogonScript;RPC_UNICODE_STRING ProfilePath;RPC_UNICODE_STRING HomeDirectory;RPC_UNICODE_STRING HomeDirectoryDrive;USHORT LogonCount;USHORT BadPasswordCount;ULONG UserId; //用户的sidULONG PrimaryGroupId;ULONG GroupCount;[size_is(GroupCount)] PGROUP_MEMBERSHIP GroupIds;//用户所在的组,如果我们可以篡改的这个的话,添加一个500(域管组),那用户就是域管了 。在ms14068 PAC签名被绕过,用户可以自己制作PAC的情况底下,pykek就是靠向这个地方写进域管组,成为使得改用户变成域管ULONG UserFlags;USER_SESSION_KEY UserSessionKey;RPC_UNICODE_STRING LogonServer;RPC_UNICODE_STRING LogonDomainName;PISID LogonDomainId;ULONG Reserved1[2];ULONG UserAccountControl;ULONG SubAuthStatus;FILETIME LastSuccessfulILogon;FILETIME LastFailedILogon;ULONG FailedILogonCount;ULONG Reserved3;ULONG SidCount;[size_is(SidCount)] PKERB_SID_AND_ATTRIBUTES ExtraSids;PISID ResourceGroupDomainSid;ULONG ResourceGroupCount;[size_is(ResourceGroupCount)] PGROUP_MEMBERSHIP ResourceGroupIds;} KERB_VALIDATION_INFO;


推荐阅读