
Образовательная демонстрация эксплуатации SQL-инъекции CVE-2014-2323 в mod_mysql_vhost веб-сервера lighttpd, с лабораторной средой на базе Docker для практического анализа уязвимости и её устранения.
title: Ep4 - Уязвимость, связанная с сетями members:
Связанная уязвимость:
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
Эксплуатируемый сервис — Lighttpd. Это веб-сервер с открытым исходным кодом (лицензия BSD), оптимизированный для лёгкости и скорости. Он появился как «proof-of-concept» знаменитой проблемы c10k (как справиться с 10 000 одновременных соединений на сервере) и приобрёл большую популярность в то время (2003); сейчас используется Whatsapp.com, Xkcd, а в прошлом — Youtube. Его позиция на рынке довольно интересна, как можно увидеть на графике:

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

Одна из особенностей lighty — простое управление виртуальными хостами.
Это метод, используемый для размещения нескольких доменных имён, которые разрешаются в один и тот же IP, что снижает затраты на хостинг для компаний, предлагающих веб-сайты, поскольку не нужно резервировать выделенный сервер для каждого сайта.
Метод может быть основан на IP (отдельный интерфейс для каждого хоста) или на имени (одно имя для каждого хоста при совместном использовании интерфейса) — рассматривается в этой презентации.
Name-Based
: использует «Hostname», предоставленный клиентом, чтобы определить, какой сервис использовать для ответа. Этот метод имеет две сложности: проблемы с безопасными сеансами (TLS) — рукопожатие должно выполняться до любой передачи заголовка, указывающего серверу Host, что усложняет определение того, какой сертификат предъявить при рукопожатии. Одно из решений этой проблемы — расширение TLS под названием Server Name Indication (SNI), которое позволяет передавать имя в начале рукопожатия, давая возможность выбрать правильный сертификат. Вторая проблема касается попытки соединения без корректно заданного заголовка Host, что приводит к неопределённости используемого сервиса.
IP-Based
: использует отдельные IP-адреса для каждого приложения. Веб-сервер настраивается на несколько физических сетевых интерфейсов (или виртуальных на одном интерфейсе) и отвечает соответствующим образом в зависимости от IP-адреса (назначения).
IP aliasing позволяет создавать виртуальные интерфейсы для каждого сервиса.
В случае крупной компании управление таким сопоставлением может стать сложным в зависимости от числа клиентов. Lighty, как мы покажем далее, поддерживает использование базы данных для этой цели.
Сначала посмотрим, как «вручную» настроить сервер, а затем добавить vhosting.
Подготовить базовый сервер lighttpd очень просто. Достаточно установить его и создать файл конфигурации, который определяет используемый порт, как отвечать на определённые запросы и другие настройки.
Можно подготовить пример конфигурации, которая обрабатывает только запросы статических файлов (.html или .txt):
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:
172.17.0.2 redes.io
172.17.0.2 mac0448.io
172.17.0.2 mac5910.io
Чтобы обслуживать разные сайты клиентов, разрешая их с одного IP, мы можем вручную настроить сервер:
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, отвечающей за такое сопоставление. Мы указываем имя базы данных, как найти её в нашей сети и какую команду использовать для поиска.
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 — это декларативный язык для управления реляционными базами данных, используемый (...) и т.д.
TODO
TODO
Проблемы возникают из-за того, что системы управления базами данных, использующие SQL, предполагают, что вводимые команды известны администратору и хорошо им управляются. Это предположение не всегда верно, поскольку ошибки в системах, взаимодействующих с СУБД, могут приводить к сбоям, особенно в вебе, где велико взаимодействие с пользователем.
Проблема с SQL-командами возникает, когда команды начинают строить из текста, введённого пользователем, будь то имя пользователя, пароль или любое другое динамическое содержимое.
(TODO)
Как решить? Экранированием.
В нашей конфигурации, например, есть большая брешь:
mysql-vhost.sql = "SELECT docroot FROM domains WHERE domain='?';"
поскольку возможно (и так было до версии 1.4.34) ? может быть заменён любой командой и затем выполнен MySQL.