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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2020-13277 — CVE-2020-13277 Полигон: логическая уязвимость Gitlab — несанкционированный доступ любого пользователя к приватным репозиториям | Kitploit
Инструменты/GitHubGitHub/exp-docs/cve-2020-13277
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеОбучение и ОбразованиеЛаборатории и Практика
GitHubexp-docs/cve-2020-13277

CVE-2020-13277

CVE-2020-13277 Полигон: логическая уязвимость Gitlab — несанкционированный доступ любого пользователя к приватным репозиториям

Репозиторий
2833 лет назадПроверено Kitploit

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться

CVE-2020-13277

CVE-2020-13277 Лаборатория: логическая уязвимость Gitlab — несанкционированный доступ любого пользователя к приватным репозиториям


0x10 Среда лаборатории

0x20 Структура каталогов

root@kitploit:~
CVE-2020-13277
├── README.md ............... [данный файл README]
├── imgs .................... [изображения, дополняющие описание в README]
├── gitlab .................. [каталог монтирования контейнера Gitlab]
│   ├── Dockerfile .......... [Docker-файл сборки Gitlab]
│   ├── config .............. [каталог монтирования конфигурации Gitlab]
│   ├── data ................ [каталог монтирования данных Gitlab]
│   ├── logs ................ [каталог монтирования журналов Gitlab]
│   ├── keys ................ [каталог хранения взломанной лицензии Gitlab]
│   └── runner .............. [каталог монтирования контейнера Runner]
├── license ................. [каталог сборки контейнера для взлома лицензии]
│   ├── Dockerfile .......... [Docker-файл сборки лицензии]
│   └── license.rb .......... [Ruby-скрипт генерации взломанной лицензии]
├── docker-compose.yml ...... [конфигурация сборки Docker]
├── keygen.ps1 .............. [Windows: создание взломанной лицензии одной командой]
├── keygen.sh ............... [Linux:   создание взломанной лицензии одной командой]
├── run.ps1 ................. [Windows: запуск лаборатории Gitlab одной командой]
├── run.sh .................. [Linux:   запуск лаборатории Gitlab одной командой]
├── register.ps1 ............ [Windows: регистрация Runner одной командой]
├── register.sh ............. [Linux:   регистрация Runner одной командой]
├── stop.ps1 ................ [Windows: остановка лаборатории Gitlab одной командой]
└── stop.sh ................. [Linux:   остановка лаборатории Gitlab одной командой]

0x30 Предварительные пояснения

Обоснование выбора версии Docker Image для лаборатории

Ядро данной уязвимости — использование функции зеркальной синхронизации и резервного копирования репозиториев Mirror Repository.

Направление синхронизации Mirror бывает двух видов:

  • Pull: втягивает содержимое указанного Repository в текущий Repository
  • Push: выталкивает содержимое текущего Repository в указанный Repository

Данная уязвимость использует Mirror Repository в направлении Pull

Следует знать, что Gitlab делится на два варианта: CE (бесплатная версия для сообщества) и EE (платная версия для предприятия), а Gitlab официально заявляет, что эта уязвимость затрагивает следующие версии как CE, так и EE:

  • >=10.6, <12.9.10
  • >=12.10, <12.10.11
  • >=13.0, <13.0.6

Но это не означает, что Gitlab Docker Image этих версий можно использовать для создания лаборатории, поскольку:

  • В CE-версии Mirror Repository доступен только в направлении Push
  • EE-версия, в свою очередь, делится на четыре издания: Core, Starter, Premium и Ultimate. Из официальной таблицы сравнения функций видно, что направление Pull отсутствует только в издании Core, а Docker Image для Gitlab-EE предоставляются исключительно в издании Core

Иными словами, для развёртывания лаборатории с помощью Docker остаётся только Gitlab-EE, который необходимо взломать (состоятельные также могут купить License), чтобы активировать функцию Mirror Repository - Pull.

Но даже после взлома Gitlab-EE, будь то 10.x, или , когда URL для Mirror Repository - Pull содержит локальный путь, появляется ошибка .

0x40 Развёртывание лаборатории

0x41 Сборка

  • На хосте должны быть предустановлены docker и docker-compose
  • Склонируйте этот репозиторий: git clone https://github.com/lyy289065406/CVE-2020-13277
  • Сгенерируйте ключевую пару для взлома: ./keygen.sh или ./keygen.ps1
  • Соберите и запустите Gitlab (убедитесь, что порт 80 свободен): ./run.sh или ./run.ps1
  • Примерно через 5 минут можно войти в Gitlab через браузер: http://127.0.0.1 (при первом входе потребуется сбросить пароль администратора root)

0x42 Взлом

При генерации ключевой пары для взлома открытый ключ уже был записан внутрь контейнера Gitlab; осталось загрузить закрытый ключ через веб-интерфейс, чтобы завершить взлом:

  • Ключевая пара создаётся в каталоге ./gitlab/keys/; скопируйте содержимое файла .gitlab-license (закрытый ключ)
  • Под пользователем root откройте страницу http://127.0.0.1/admin/license/new
  • Выберите Enter license key, вставьте закрытый ключ и нажмите кнопку Upload license — взлом завершён

На этом функция Mirror Repository - Pull активирована

0x43 Настройка исходящих запросов

  • Под пользователем root откройте страницу http://127.0.0.1/admin/application_settings
  • В самом низу найдите раздел Outbound requests, отметьте флажком Allow requests to the local network from hooks and services и сохраните изменения

На этом Mirror Repository - Pull поддерживает втягивание локальных Repository

0x44 Настройка Runner

  • Под пользователем root откройте страницу http://127.0.0.1/admin/runners
  • Найдите registration token и скопируйте его
  • Зарегистрируйте Runner: ./register.sh $TOKEN или ./register.ps1 $TOKEN

На этом все Repository смогут использовать этот Runner для выполнения CI-скриптов (Pipeline Jobs)

0x50 Проверка лаборатории

Процесс проверки можно подсмотреть в официальном Issue, однако приведённый ниже процесс проверки содержит небольшие корректировки некоторых шагов под данную лабораторию

0x51 Предварительное создание учётных записей для проверки

Под пользователем root откройте страницу http://127.0.0.1/admin/users и создайте 3 учётные записи:

  • victim: учётная запись жертвы
  • attacker1: учётная запись атакующего 1
  • attacker2: учётная запись атакующего 2

При создании учётной записи задать начальный пароль нельзя — Gitlab по умолчанию отправляет начальный пароль на указанный Email. Для удобства можно указать любой Email, создать учётную запись, а затем сразу же отредактировать её: в этом случае root сможет задать начальный пароль без обращения к Email

0x52 Предварительное создание репозитория жертвы

  • Войдите в Gitlab под учётной записью victim
  • Создайте новый репозиторий New Project:
    • Name: target
    • Visibility Level: Private
  • Создайте в репозитории файл README.md и задайте его содержимое, например mykey is abcxyz

Очевидно, target — приватный репозиторий victim, и наша цель — получить содержимое этого репозитория, используя уязвимость

0x53 Создание poc-репозитория атакующего

  • Войдите в Gitlab под учётной записью attacker1
  • Создайте новый репозиторий New Project:
    • Name: poc
    • Visibility Level: Public
  • Создайте в репозитории файл .gitlab-ci.yml со следующим содержимым:
root@kitploit:~
image: "ruby:2.6"

rspec:  
  script:  
    - git clone http://gitlab-ci-token:[email protected]/victim/target.git
    - cd target
    - ls -lah .  
    - cat README.md

【Цель】В ходе последующих операций с помощью некоторых приёмов victim, не подозревая об этом, выполнит данный CI-скрипт со своими правами.

Поскольку в текущей лаборатории не настроены сертификаты, доступен только протокол http; кроме того, 172.168.30.2 — это IP, назначенный контейнеру Gitlab в docker-compose.yml. Так как CI-скрипт в конечном счёте выполняется через Runner, а Runner и Gitlab в данной лаборатории находятся в разных контейнерах, нужно использовать IP-адрес, назначенный Docker.

0x53 Создание зеркального poc-репозитория атакующего

  • Войдите в Gitlab под учётной записью attacker2
  • Создайте новую группу New Group:
    • Name: test
    • Visibility Level: Public
  • Внутри группы test создайте полностью пустой репозиторий New Project:
    • Name: poc
    • Visibility Level: Public

Настройте зеркальный репозиторий в разделе Settings => Repository => Pull from a remote repository:

  • Mirror repository: установите флажок
  • Git repository URL: укажите http://GITLAB/attacker1/poc
  • Password: (оставьте пустым — репозиторий для Pull имеет уровень доступа Public, пароль не нужен)
  • Trigger pipelines for mirror updates: установите флажок (запуск CI-скриптов при синхронизации зеркала)

После успешной настройки каждые 30 минут будет проверяться, изменился ли исходный репозиторий; если изменения есть, выполняется принудительная синхронизация.

Git repository URL указывает на созданный ранее poc-репозиторий. 127.0.0.1 не используется, потому что Pull запрещает втягивание локальных репозиториев, но это можно обойти с помощью DNS: GITLAB — это hostname, назначенный контейнеру Gitlab в docker-compose.yml; по умолчанию он прописывается в /etc/hosts. Хотя хост-машина не может разрешить GITLAB, внутри контейнера это эквивалентно обращению к http://127.0.0.1/attacker1/poc

0x54 Принудительная передача владельца зеркального poc-репозитория жертве

  • Продолжайте работать под учётной записью attacker2
  • Откройте страницу http://127.0.0.1/groups/test/-/group_members, чтобы управлять пользователями группы test
  • Добавьте пользователя victim в группу:
    • Add new member to test: victim
    • Permissions: Owner
    • Expiration date: (оставьте пустым — без срока действия)
  • Нажмите на аватар учётной записи в правом верхнем углу => Setting => Account => Delete account, чтобы удалить текущую учётную запись (attacker2)

【Цель】В группе test есть только два Owner — victim и attacker2. После удаления пользователя attacker2 право владения группой test и всеми её репозиториями принудительно перейдёт к victim. Сейчас в группе test есть репозиторий test/poc, синхронизированный зеркалом из attacker1/poc, то есть репозиторий test/poc принудительно передаётся пользователю victim.

0x55 Запуск атаки

Сначала подведём итог текущей ситуации:

  • Атакующий принудительно и тайно создал для жертвы victim репозиторий test/poc
  • Содержимое репозитория test/poc синхронизируется зеркалом из attacker1/poc (каждые 30 минут проверяется, не изменился ли он и не нужна ли синхронизация)
  • Содержимое репозитория attacker1/poc, включая CI-скрипт .gitlab-ci.yml, контролируется атакующим
  • Поскольку для репозитория test/poc включён Trigger pipelines for mirror updates, при каждой синхронизации выполняется CI-скрипт
  • Поскольку Owner репозитория test/poc — victim, CI-скрипт выполняется с правами victim

Вспомним содержимое CI-скрипта .gitlab-ci.yml, заданного ранее: этот poc в Runner с правами victim обращается к структуре каталогов и README.md его Private-репозитория target:

root@kitploit:~
image: "ruby:2.6"

rspec:  
  script:  
    - git clone http://gitlab-ci-token:[email protected]/victim/target.git
    - cd target
    - ls -lah .  
    - cat README.md

После этого атакующему достаточно произвольно изменить какое-либо незначительное содержимое в репозитории attacker1/poc — в худшем случае просто подождать 30 минут, — и заданный CI-скрипт выполнится с правами victim.

Хотя атакующий не имеет прямого доступа к результатам выполнения Pipeline Jobs, достаточно изменить цель вывода скрипта — например, отправлять содержимое репозитория на указанный Email или FTP-сервер — и код репозитория будет похищен.

Скачать инструмент
12.x
13.x
Import url is blocked: Requests to localhost are not allowed

Хотя после установки параметра Allow requests to the local network from hooks and services в разделе Admin area => Settings => Network => Outbound requests локальный URL настроить можно, при синхронизации зеркала возникает ошибка 2:Fetching remote upstream failed: fatal: unable to access http://127.0.0.1/xxxx/: The requested URL returned error: 301. Иными словами, работать будет только Pull Remote Repository.

К счастью, хотя в 12.x и 13.x проверка локального URL очень строгая, в версии 10.x есть способ обойти её: при настройке Pull URL достаточно указать имя локально настроенного DNS-сервиса.

Таким образом, для построения данной лаборатории в итоге подходит только Docker Image версии gitlab-ee:10.6.0-ee.0.

Собственно, из описанного выше видно, что условия эксплуатации этой уязвимости довольно жёсткие, и в основном небогатым пользователям она вряд ли угрожает