Данная статья также содержит интересные примеры, как мы можем с пользой модифицировать передаваемые элементы HTTP сообщений. Последующие примеры не нужно расценивать как панацею для скрытой передачи данных — скорее, это необычные примеры использования, которые помогают лучше «прочувствовать» протокол HTTP.
Что касается сохранения других полей HTTP заголовка, то это в принципе возможно, но для этого необходимо включение и настройка модуля mod_log_forensic, это тоже бывает нечасто, плюс хранение большого количества практически ненужных данных.
Поэтому определённые резоны использовать HTTP заголовки для передачи данных есть, поскольку GET запросы сохраняются практически всегда, POST запросы сохраняются редко, а HTTP заголовки не сохраняются практически никогда.
Из популярных приложений, которые используют поле HTTP заголовка для передачи данных, на вскидку можно вспомнить PhpSploit — «скрытный фреймворк для последующей эксплуатации», если коротко, то троян, бэкдор на PHP для веб-серверов.
К примеру, если мы хотим передать странице localhost/headers.php заголовок с именем «Hackware» и со значением «Hello! How are you?», то достаточно выполнить следующую команду:
Я покажу пример обмена данных с локальным веб-сервером.
Если у вас Kali Linux (и вообще любые производные Debian), то для запуска веб-сервера выполните:
или для Arch Linux / BlackArch
Теперь создайте файл headers.php. Для этого в Kali Linux:
В Arch Linux / BlackArch:
И скопируйте в него следующее:
То есть скрипт просто выводит значение заголовка Hackware (если он получен).
Если открыть в веб-браузере адрес http://localhost/headers.php, то будет показана пустая страница — ничего не получено и, следовательно, ничего не выведено.
Давайте выполним уже рассмотренную выше команду, в которой мы передадим заголовок Hackware:
Обратите внимание на выведенную скриптом строку «Hello! How are you?» - это и есть отправленное значение заголовка.
Усовершенствуем наш скрипт, чтобы он отправлял ответ не в теле сообщения, а в заголовке:
Вновь выполняем нашу команду:
А в ответ получаем пустоту:
На самом деле, всё сработало как надо и ответное сообщение прислано, просто его можно увидеть только если включить показ заголовков. Добавим опцию -v:
Теперь мы видим и отправленный нами заголовок и полученный в ответ заголовок.
вызовет ошибку «403 Forbidden».
Команда
вызовет ошибку «501 Not Implemented».
Команда на этот же сервер, но на 443 порт вместо 80:
вызовет ошибку веб-сервера «502 Bad Gateway».
Но современные веб-серверы Apache 2.4 с настройками по умолчанию просто обрабатывают незнакомые методы как если бы это был GET.
Проверим на нашем локальном сервере:
Как можно убедиться, несмотря на то, что строка запроса стала такой:
Веб-сервер и скрипт корректно обработали этот запрос и прислали ожидаемые данные.
Кажется, что всё как обычно, но такой запрос уже невозможно найти в Wireshark по фильтру
Продемонстрируем это скриншотами.
Поиск по фильтру «http» после выполнения команды с запросом методом GET:
Всё как положено: HTTP запрос и ответ присутствуют.
Поиск по фильтру «http» после выполнения команды с запросом методом MIAL:
То есть ответ найден (потому что он обычный), а запрос уже нет.
Мы можем указать абсолютно любой статус ответа в диапазоне 100-599. Если указать статус 5xx, то веб-браузеры, поисковые системы и все остальные будут думать, что на сервере возникла ошибка — хотя на самом деле, никакой ошибки нет и наше сообщение успешно доставлено и успешно получен ответ.
Для демонстрации попробуем следующий код в нашем файле headers.php:
Откроем эту страницу в веб-браузере: http://localhost/headers.php
Как будто бы всё сломано и на сервере проблемы.
Но посмотрим в командной строке:
Как можно увидеть, наше сообщение доставлено и процитировано в ответе.
Строка со статусом ответа включает три элемента:
Отправляем в заголовке произвольную строку:
И получаем её в строке статуса:
Я хотел ещё поменять строку с версией «HTTP/1.1», но средствами cURL/PHP это, видимо, сделать невозможно. В принципе, можно подключиться к Ncat и отправить какую угодно строку статуса ответа, чтобы посмотреть, как на это прореагирует HTTP клиент (но скорее всего, просто напишет, что-то в духе «получен неверный ответ»).
Опции cURL в PHP устанавливаются с помощью curl_setopt. Подробную документацию вы найдёте по ссылке: https://www.php.net/manual/ru/function.curl-setopt.php
Многие заголовки имеют свои специальные названия параметров, например, CURLOPT_USERAGENT для User Agent, CURLOPT_REFERER для Referer и т. д. Но произвольные заголовки можно установить с помощью параметра CURLOPT_HTTPHEADER (смотрите документацию по ссылке выше).
Что касается использования методов, отличных от GET, то для метода POST есть специальный параметр CURLOPT_POST, для метода PUT есть CURLOPT_PUT.
Для DELETE, CONNECT, HEAD и других более редки либо просто произвольных методов запроса используйте CURLOPT_CUSTOMREQUEST следующим образом (замените «МЕТОД» на нужный вам):
Создадим теперь файл methods.php:
и скопируем в него:
Этот скрипт делает HTTP запрос указанным методом и показывает все полученные HTTP заголовки ответа.
Файл headers.php делаем таким:
Запустим methods.php прямо в командной строке:
В последнем примере мы добились:
Автор Alexey
источник hackware.ru
Зачем передавать данные в HTTP заголовках
Обычно в HTTP заголовках передаётся предсказуемая техническая информация, поэтому не все программы для ведения журналов и анализа трафика имеют функцию сохранения содержимого HTTP заголовков. Например, Apache обычно (это зависит от настройки формата логов) сохраняет такие поля HTTP заголовка как Referer и User-Agent. При желании, можно настроить Apache сохранять данные, переданные методом POST, но обычно это не делается, т. к. журналы начинают занимать слишком много места.Что касается сохранения других полей HTTP заголовка, то это в принципе возможно, но для этого необходимо включение и настройка модуля mod_log_forensic, это тоже бывает нечасто, плюс хранение большого количества практически ненужных данных.
Поэтому определённые резоны использовать HTTP заголовки для передачи данных есть, поскольку GET запросы сохраняются практически всегда, POST запросы сохраняются редко, а HTTP заголовки не сохраняются практически никогда.
Из популярных приложений, которые используют поле HTTP заголовка для передачи данных, на вскидку можно вспомнить PhpSploit — «скрытный фреймворк для последующей эксплуатации», если коротко, то троян, бэкдор на PHP для веб-серверов.
Как передавать данные в HTTP заголовках
HTTP заголовками можно манипулировать с помощью программы cURL, у которой есть опция -H 'ЗАГОЛОВОК: ЗНАЧЕНИЕ'.К примеру, если мы хотим передать странице localhost/headers.php заголовок с именем «Hackware» и со значением «Hello! How are you?», то достаточно выполнить следующую команду:
Код:
curl -H 'Hackware: Hello! How are you?' localhost/headers.php
Если у вас Kali Linux (и вообще любые производные Debian), то для запуска веб-сервера выполните:
Код:
sudo systemctl start apache2.service
Код:
sudo systemctl start httpd.service
Код:
sudo gedit /var/www/html/headers.php
Код:
sudo gedit /srv/http/headers.php
Код:
<?php
$headers = apache_request_headers();
if (isset($headers["Hackware"])) {
echo $headers["Hackware"];
}
Если открыть в веб-браузере адрес http://localhost/headers.php, то будет показана пустая страница — ничего не получено и, следовательно, ничего не выведено.
Давайте выполним уже рассмотренную выше команду, в которой мы передадим заголовок Hackware:
Код:
curl -H 'Hackware: Hello! How are you?' localhost/headers.php
Обратите внимание на выведенную скриптом строку «Hello! How are you?» - это и есть отправленное значение заголовка.
Усовершенствуем наш скрипт, чтобы он отправлял ответ не в теле сообщения, а в заголовке:
Код:
<?php
$headers = apache_request_headers();
if (isset($headers["Hackware"])) {
header ('HackWare: I got your message: ' . $headers["Hackware"]);
}
Код:
curl -H 'Hackware: Hello! How are you?' localhost/headers.php
На самом деле, всё сработало как надо и ответное сообщение прислано, просто его можно увидеть только если включить показ заголовков. Добавим опцию -v:
Код:
curl -v -H 'Hackware: Hello! How are you?' localhost/headers.php
Теперь мы видим и отправленный нами заголовок и полученный в ответ заголовок.
Использование произвольных методов HTTP запроса
Метод указывается после опции -X. Не все серверы одинаково реагируют на произвольные методы, например, команда:
Код:
curl -X 'HACK' -A 'Chrome' https://google.ru
Команда
Код:
curl -X 'HACK' -A 'Chrome' 87.236.16.208
Команда на этот же сервер, но на 443 порт вместо 80:
Код:
curl -X 'HACK' -A 'Chrome' https://87.236.16.208 -k
Но современные веб-серверы Apache 2.4 с настройками по умолчанию просто обрабатывают незнакомые методы как если бы это был GET.
Проверим на нашем локальном сервере:
Код:
curl -v -H 'Hackware: Hello! How are you?' -X 'MIAL' localhost/headers.php
Код:
MIAL /headers.php HTTP/1.1
Кажется, что всё как обычно, но такой запрос уже невозможно найти в Wireshark по фильтру
Код:
http
Поиск по фильтру «http» после выполнения команды с запросом методом GET:
Код:
curl -H 'Hackware: Hello! How are you?' localhost/headers.php
Всё как положено: HTTP запрос и ответ присутствуют.
Поиск по фильтру «http» после выполнения команды с запросом методом MIAL:
Код:
curl -H 'Hackware: Hello! How are you?' -X 'MIAL' localhost/headers.php
То есть ответ найден (потому что он обычный), а запрос уже нет.
Изменение кода статуса ответа и комментария статуса
В примерах выше статусом ответа был 200, и комментарий «OK».Мы можем указать абсолютно любой статус ответа в диапазоне 100-599. Если указать статус 5xx, то веб-браузеры, поисковые системы и все остальные будут думать, что на сервере возникла ошибка — хотя на самом деле, никакой ошибки нет и наше сообщение успешно доставлено и успешно получен ответ.
Для демонстрации попробуем следующий код в нашем файле headers.php:
Код:
<?php
header("HTTP/1.1 599 Damn, dude, you broke everything!");
$headers = apache_request_headers();
if (isset($headers["Hackware"])) {
header ('HackWare: I got your message: ' . $headers["Hackware"]);
}
Как будто бы всё сломано и на сервере проблемы.
Но посмотрим в командной строке:
Код:
curl -v -H 'Hackware: Hello! How are you?' localhost/headers.php
Как можно увидеть, наше сообщение доставлено и процитировано в ответе.
Строка со статусом ответа включает три элемента:
- номер HTTP версии (например, HTTP/1.1)
- номер статуса ответа (любые цифры от 100 до 599 — если использовать другие цифры, то можно получить «настоящий» статус 5xx)
- комментарий (например, для кода 200 комментарием является «OK») — здесь может быть что угодно
Код:
<?php
$headers = apache_request_headers();
if (isset($headers["Hackware"])) {
header('HTTP/1.1 599 ' . 'I got your message: ' . $headers["Hackware"]);
}
Код:
curl -v -H 'Hackware: Hello! How are you?' localhost/headers.php
Я хотел ещё поменять строку с версией «HTTP/1.1», но средствами cURL/PHP это, видимо, сделать невозможно. В принципе, можно подключиться к Ncat и отправить какую угодно строку статуса ответа, чтобы посмотреть, как на это прореагирует HTTP клиент (но скорее всего, просто напишет, что-то в духе «получен неверный ответ»).
Как в PHP поменять заголовки и метод HTTP запроса
В этой статье мы использовали утилиту cURL. Рассмотрим вариант, когда вы работаете с cURL через PHP — типичный случай для веб-серверов.Опции cURL в PHP устанавливаются с помощью curl_setopt. Подробную документацию вы найдёте по ссылке: https://www.php.net/manual/ru/function.curl-setopt.php
Многие заголовки имеют свои специальные названия параметров, например, CURLOPT_USERAGENT для User Agent, CURLOPT_REFERER для Referer и т. д. Но произвольные заголовки можно установить с помощью параметра CURLOPT_HTTPHEADER (смотрите документацию по ссылке выше).
Что касается использования методов, отличных от GET, то для метода POST есть специальный параметр CURLOPT_POST, для метода PUT есть CURLOPT_PUT.
Для DELETE, CONNECT, HEAD и других более редки либо просто произвольных методов запроса используйте CURLOPT_CUSTOMREQUEST следующим образом (замените «МЕТОД» на нужный вам):
Код:
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "МЕТОД");
Код:
sudo gedit /var/www/html/methods.php
Код:
<?php
$target_url = "localhost/headers.php";
$agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36';
//$referer = 'REFERER HERE';
$cookies = '';
$ch = curl_init($target_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "MIAL");
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
//curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 'true');
$response_data = curl_exec($ch);
if (curl_errno($ch) > 0) {
die(PHP_EOL . PHP_EOL . 'Ошибка curl: ' . curl_error($ch) . PHP_EOL . PHP_EOL . print_r(curl_getinfo($ch)) . PHP_EOL . PHP_EOL);
} elseif (empty($response_data)) {
die(PHP_EOL . PHP_EOL . 'Returned empty result: ' . print_r(curl_getinfo($ch)) . PHP_EOL . PHP_EOL);
}
curl_close($ch);
print_r (headers_list()) . PHP_EOL;
echo $response_data . PHP_EOL;
Файл headers.php делаем таким:
Код:
<?php
header('HTTP/1.1 599 ' . 'Just because we can!');
header ('HackWare: I am here!');
Код:
php /var/www/html/methods.php
В последнем примере мы добились:
- cURL в скрипте PHP использует пользовательский метод запроса MIAL — можно использовать для проверки, какие методы поддерживает сервер; ещё такие запросы не обнаруживаются фильтром «http» в Wireshark.
- ответ мы получили с произвольным комментарием в строке состояния и с заголовком с произвольным именем и содержанием.
Заключение
В первую очередь, это не инструкция по скрытности — это скорее упражнения по HTTP протоколу и практика работы с ним. Помните, что передаваемые таким образом данные не зашифрованы и при желании их можно найти и отфильтровать в трафике.Автор Alexey
источник hackware.ru