域渗透之SPN

文摘   其他   2024-02-25 13:00   陕西  

SPN是什么?

在我们了解SPN之前,我们需要了解Active Drietcory域中的服务是什么?

服务我们已经很熟悉了,比如说SMB服务,Web服务,HTTP服务,FTP服务,DNS服务,MYSQL服务等等这些我们都称之为服务!!!

那么同一个服务可以在不同的主机下运行,比如说打印机服务,它不是一个专属于任何人的服务,它可以应用于多个主机,可以给多个主机提供打印的服务,所以我们需要指定主机,而一台计算机是可以承载多个服务的,所以我们还需要去指定服务,这样的话,我们就可以准确的指定服务给那些计算机服务。

这两个合起来就是服务主体名称或者也可以叫做SPN。

我们来举一个现实中的例子。

当某个用户去访问数据库服务的时候,比如sqlserver或mysql服务,系统会以当前用户的身份向域控查询SPN为Mysql的记录,当找到该SPN的记录后,用户再次与KDC通信,将TGT发送给KDC,并将需要访问的SPN发送给KDC,KDC的TGS服务对TGT进行解密,解密之后确定无误的话,由TGS将一张允许访问该SPN所对应的服务的ST服务票据和该SPN所对应的服务的地址发送给用户,用户使用该ST服务票据来访问数据库服务。

那么我们再来看下SPN是如何命名的。

 服务类/主机名或者域名

这里的服务类实际上就是服务的一个通用名称,例如所有的web服务都归于www类,sql服务都归于Sqlserver类等等。

如果服务在自定义端口上运行的话,你可以将这个端口加到主机的后面。

例如:

服务类/主机名或者域名:端口

或者也可以命名SPN。

如果我们在上面指定了一个web服务,比如说主机名为:WEB-SERVER-01。

那么它的SPN就是这样的。这里的www就是服务类。这是以主机名进行命名的。

www/WEB-SERVER-01

如果以域名命名的话,那么将是这样的。

www/WEB-SERVER-01.relaysec.com

有大量的服务类,我们可以在微软这里进行参考:https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc772815(v=ws.10)#service-principal-names这里服务类中有例如CIFS与文件共享的服务,DNS 域名解析服务,spooler打印服务等等,但是这里面并不详细,例如没有SQLserver或者Ldap目录服务类。这些类通常可以在AD环境中找到。

SPN两种类型

SPN分为两种类型,一种是注册在活动目录的机器帐户(Computers)下,当一个服务的权限为 Local System 或 Network Service。一种是注册在活动目录的域用户帐户(Users)下,当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下。

在Windows域里,默认普通机器账号有权注册SPN:

比如说我们拿到一个机器将其提升到system权限之后,我们就有权注册SPN了。

setspn -A MSSQL/win2016.relaysec.com win2016

现在我们来到win2016机器的servicePrincipalNames属性查看

如上图可以看到已经注册进来了。

但是普通域内用户是不能注册SPN的。这样就会导致一个问题,如果SqlServer使用 Local SysTem account来启动的话,kerberos就能认证成功,这时候就可以在DC上注册SPN,如果用一个普通用户的话,kerberos就不能成功,因为这时候SPN注册不上去。

我们可以在DC中赋予域账号Read servicePrincipalName和WriteserverPrincipalName的权限,只要有这两个权限就可以注册。

现在我们已经知道了SPN是什么。我们来查找一下域内存在的SPN。

查找域内的SPN

使用过滤器进行查找(servicePrincipalName=*),也就是servicePrincipalName属性,也可以使用setSpn。

Setspn -Q */*

使用GetUsersSPNS.py

这个工具也可以查找SPN,这个工具可以说很舒服了,包括我们查找出来的SPN进行kerberoasting攻击都可以用到。

BloodHound

BloodHound我们前面一直在用,但是也一直没说,因为BloodHound有时候很不稳定,为什么说他不稳定,因为有时候你使用官方提供的exe导出的域内信息,我们无法将它导入到BloodHound中来解析。

所以这里我推荐一个方式,很简单不需要落地exe文件,我们直接使用python来进行导出。

这里直接使用kali的bloodhound-python来导出即可。

需要注意的是-ns这个参数,这个参数非常重要,指定的是DNS服务器的地址,如果不指定这个参数肯定是导不出来的。

bloodhound-python -u win2016 -p 'Admin123..' -d relaysec.com -ns 10.10.211.130 -c All

导出之后我们开启neo4j数据库,如果没有下载的话直接apt install即可。

sudo neo4j console

然后我们直接打开bloodhound即可,还是一样如果没有安装直接apt instll安装即可。

打开之后我们点击List All kerberoastable Accounts 就可以列出可以kerberoastable 攻击的账户了,可以看到如下图有3个账户,krbtgt账户我们肯定是不会考虑的,它生成的密码是非常复杂的,所以我们可以考虑剩余下来的两个账户。

kerberoasting攻击

kerberoastring攻击是出在TGS_REP阶段的,由于ST服务票据是使用服务账户的Hash进行加密的,所以如果我们能获取到ST服务票据,就可以对该ST服务票据进行暴力破解,得到服务的Hash,在TGS_REP这一阶段不会验证客户端是否有权限访问服务端,因此这一步无论用户也没有访问服务的权限,只要TGT正确,都会返回ST服务票据,这也就是kerberoasting能利用的原因,任何一个域内用户都是去请求任何一个服务的ST服务票据。

我们直接上实例来看下。

为了测试环境我将ceshi这个用户作为服务账户注册了一个SPN。

setspn -A MYSQL/dc.relaysec.com ceshi

然后我们使用impacket-GetUserSPNs进行枚举。

可以看到并没有枚举出来机器账户,只枚举出来了两个域用户。这是因为机器账户的密码非常复杂是破解不开的。所以一般都是使用域用户来进行kerberoasting攻击。

然后我们加上-request参数,它将申请一个ST服务票据,因为ST服务票据是使用服务账户的Hash进行加密的,所以我们可以直接使用hashcat进行破解。

可以看到成功获取到两个ST票据。

然后我们将第二个服务账户,也就是ceshi这个账户放到一个hash.txt文件中。

这里简单做了一个字典,里面的Admin123..是正确密码。

所以让我们使用hashcat对其进行破解把。

hashcat hash.txt password.txt --force

可以看到成功破解。

结束语

本次学习就先到这里 期待和您的下次相遇!!!

Relay学安全
这是一个纯分享技术的公众号,只想做安全圈的一股清流,不会发任何广告,不会接受任何广告,只会分享纯技术文章,欢迎各行各业的小伙伴关注。让我们一起提升技术。
 最新文章