12 мая 2017

Zeronights 2016 HackQuest Day #7 Writeup


Хотел написать разбор на PHDays 2017 HackQuest и нашел этот в закладках.

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

Задание представляет собой сайт с названием «The First School of Bulimia» и из функциональности там только регистрация и аутентификация. После проверки стандартных векторов, единственное, за что можно было зацепиться – обработка поля «Вес» при регистрации.

При некорректном значении выдавало Exception:

Failed to convert property value of type java.lang.String to required type java.lang.Integer 
for property weight; nested exception is java.lang.NumberFormatException: For input string: "zdrxyhryy" 
Fill your weight. Weight has to be numeric value

В поле можно было использовать hex значения #FF или 0xFF. При значении ${0}, получилось следующее:

Failed to convert property value of type java.lang.String to required type java.lang.Integer 
for property weight; nested exception is java.lang.NumberFormatException: 
For input string: "$org.springframework.context.support.DefaultMessageSourceResolvable: 
codes [user.weight,weight]; arguments []; default message [weight]"

Прочитав несколько статей про Expression Language Injection, я понял, что это не совсем то, и что текст ошибки с указанным параметром попадает в MessageFormat. С помощью {0, number} можно вызвать приведение объекта-параметра с индексом 0 к числу и получить подробную ошибку с фрагментом исходного кода. Но, эта информация тоже ничего интересного не дала.

img1

Первая подсказка OTG-INFO-001 указывает на то, что сначала нужно было получить больше информации о задании. Помучив поисковые системы и веб-архивы удалось найти исходный код приложения на github.

https://github.com/search?q=The+First+School+of+Bulimia

Первая часть флага была указана в исходном коде:

private static String firstSecret="2TvoixPalca";

Вторая часть, судя по всему, получалась из файла конфигурации и ее можно было получить с помощью ${secondSecret}.
Оказалось, что почитать про Expression Language Injection было правильной идеей и можно сразу заметить в коде следующее:

<p><b>Твое имя:  <spring:message text="${user.name}" /></b></p>
<p><b>Твое вес:  <spring:message text="${user.weight}" /></b></p>

<spring:message> дважды обрабатывает Expression Language и инъекция через имя пользователя выглядит верным решением задания. Но необходимо придумать, как обойти регулярное выражение при регистрации:

if (user.getName() == null) {
  e.rejectValue("name", "null", "Fill your name");
} else if (!user.getName().matches("[0-9A-Za-z]+")) {
  e.rejectValue("name", "onlynumbersletters", "Only letters and numbers in your name");
}

Перепробовав все идеи, я решил обратиться к сценарию следующим образом
(к тому же похожая уязвимость была в первом web задании, которое я не дорешал):
http://45.55.216.88/home?name=<h1><s>123

img2

И только потом заметил следующее объявление метода:

@RequestMapping(value = "/home", method = RequestMethod.GET)
public String home(@ModelAttribute User user, Model model) {

ModelAttribute: Annotation that binds a method parameter or method return value to a named model attribute, exposed to a web view. Supported for controller classes with @RequestMapping methods.

Получаем вторую часть флага:

http://45.55.216.88/home?name=${secondSecret}

Флаг: 2TvoixPalcaVRot! (вторую часть в целом можно было и угадать)

Разбор уязвимости и самого задания от автора

Комментариев нет :

Отправить комментарий