Exploiting CVE-2024-37148
Intro When it comes to input sanitisation, who is responsible, the function or the caller ? Or both ? And if no one does, hoping that the other one will do t...
I won’t insult you by explaining once again what JSON Web Tokens (JWTs) are, and how to attack them. A plethora of awesome articles exists on the Web, describing attacks such as none
algorithm, algorithm confusion, JWK header injection, and friends … No, I would like to tell you about something a little bit different, akin to a jku
header injection, turning what was looking like an SSRF into an application compromise.
Once upon a time, there was a C# single-page application using JWTs for both authentication and authorisation, being managed by the service Auth0. To make things more flexible, the address of the validator was not hardcoded, but dynamically retrieved with something like this:
var jwt = new JwtSecurityTokenHandler().ReadToken(token);
var iss = jwt.Claims.FirstOrDefault(x => x.Type == "iss");
...
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{iss}/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
var openIdConfig = configManager.GetConfigurationAsync().Result;
var signingKeys = new[]{openIdConfig.JsonWebKeySet.GetSigningKey().FirstOrDefault(x => x.KeyId == kid)} ;
var tokenParams = new Microsoft.IdentityModel.TokensTokenValidationParameters() {
...
IssuerSigningKeyResolver = signingKeys
}
var claims = jwt.ValidateToken(jwttoken, tokenParams, out var tokenout)
For those who get pimples while reading C#, this code can be summarised as follows: the URL of the issuer (and thus the verifier) is extracted from the token, and used to build the URL to the OIDC configuration. From there, public keys are fetched, in order to use them for token verification. In other words, it is like having a token claiming “Hey app, go ask this server to verify that I am valid !”. I should have been able to sign a token with my private key, and instruct the vulnerable app to fetch my public key to verify. But of course, there was a catch …
By taking a look at a genuine token, I saw what the kid
was supposed to be (let’s say that "kid": "wow-I-am-the-keyid"
). I then created a fake configuration like this, based on the genuine one, and hosted it on my server (notice the jwks_uri
)
openid-configuration
{
"issuer":"https://v1ct1m.auth0.com/",
"authorization_endpoint":"https://v1ct1m.auth0.com/authorize",
"token_endpoint":"https://v1ct1m.auth0.com/oauth/token",
"device_authorization_endpoint":"https://v1ct1m.auth0.com/oauth/device/code",
"userinfo_endpoint":"https://v1ct1m.auth0.com/userinfo",
"mfa_challenge_endpoint":"https://v1ct1m.auth0.com/mfa/challenge",
"jwks_uri":"https://4tt4ck3r.com/jwks.json",
"registration_endpoint":"https://v1ct1m.auth0.com/oidc/register",
"revocation_endpoint":"https://v1ct1m.auth0.com/oauth/revoke",
"scopes_supported":[
"openid","profile",...
],
...
}
jwks.json
{
"keys":[
{
"kty":"RSA",
"use":"sig","n":" ... here goes the modulus ...",
"e":"AQAB",
"kid":"wow-I-am-the-keyid",
...
"alg":"RS256"}
]
}
I then edited the genuine token and replaced the iss
by my server’s URL, resent a request, and … nothing worked, I only got timeouts. With trial and error, I finally realised that there probably was an allowlisting, preventing the app from contacting arbitrary remote hosts. Only subdomains of Auth0 seem to be allowed, and therefore, I knew what I had to do next: create my own instance !
The idea was simple: creating my own Auth0 instance, and use it to forge tokens that would be accepted by the vulnerable app. Adjusting claims and users, and it should be fine. Although my first idea was to export my private keys and sign arbitrary tokens, I did not find how to do so.
First thing was to create a dummy application, so that an authentication endpoint would be configured.
From the Auth0 dashboard, I modified the Default application by setting some URLs:
This localhost:3000
comes from the fact that my dummy app would run on localhost:3000, more on this later.
Since my goal was to connect as bob@mail.local
on the victim application, I needed to create a fake user with the same username, able to connect on my fake app. It would therefore give me a token for this dummy user, that the victim app would also accept (note that having the same username is not always necessary, but it populates the claims consistently).
The last challenge was to add custom claims that the victim app was expecting. The article Adding Custom Claims to ID Tokens with Auth0 Actions describes how to do so, taking as an example the application assign-random-dog, that is meant to run on localhost:3000
.
Since the application expected a claim email_address
, I configured an Action to do so, adding this claim after user authentication (only for Bob here, because it’s the one I was interested in).
Finally, by deploying the Action and running npm start
in the assign-random-dog
directory on my laptop, it opened the dummy app. Clicking on Log in
redirects to Auth0, asking for the credentials, and I therefore entered Bob’s ones.
A successful authentication would redirect to the dummy app, and by visiting the Profile page while taking a look at the requests being sent, one can see that a token is obtained:
{
"access_token": "...",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Im9SSk9IN1ZRclE4a3ZNTnRzZFlMMyJ9.eyJlbWFpbF9hZGRyZXNzIjoiYm9iQG1haWwubG9jYWwiLCJuaWNrbmFtZSI6ImJvYiIsIm5hbWUiOiJib2JAbWFpbC5sb2NhbCIsInBpY3R1cmUiOiJodHRwczovL3MuZ3JhdmF0YXIuY29tL2F2YXRhci8wYmY4NGYwZTQzMmUzZGZkOTY5MWM3YTE0ZDU4ZjgyND9zPTQ4MCZyPXBnJmQ9aHR0cHMlM0ElMkYlMkZjZG4uYXV0aDAuY29tJTJGYXZhdGFycyUyRmJvLnBuZyIsInVwZGF0ZWRfYXQiOiIyMDIzLTEyLTI4VDE5OjU1OjA0LjI1MFoiLCJlbWFpbCI6ImJvYkBtYWlsLmxvY2FsIiw...FRsZFRTMWhyYmt0VlpRPT0ifQ.o2F5z...EO9ZEIMw",
"scope": "openid profile email",
"expires_in": 86400,
"token_type": "Bearer"
}
Once decoded, the body contains:
{
"email_address":"bob@mail.local",
"nickname":"bob",
"name":"bob@mail.local",
"picture":"https://s.gravatar.com/avatar/0bf84f0e432e3dfd9691c7a14d58f824?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fbo.png",
"updated_at":"2023-12-28T19:55:04.250Z",
email":"bob@mail.local",
email_verified":true,
"iss":"https://dev-....eu.auth0.com/",
...
}
This token could be used on the victim app as well, since the latter would happily validate it with my public key, and since the user bob@mail.local
was recognised !
Bottomline
Intro When it comes to input sanitisation, who is responsible, the function or the caller ? Or both ? And if no one does, hoping that the other one will do t...
Intro After being tasked with auditing GLPI 10.0.12, for which I uncovered two unknown vulnerabilities (CVE-2024-27930 and CVE-2024-27937), I became really i...
Intro A few weeks ago, I discovered during an intrusion test two vulnerabilities affecting GLPI 10.0.12, that was the latest public version at this time. The...
I was recently tasked with auditing the application GLPI, a few days after its latest release (10.0.12 at the time of writing). The latter stands for Gestion...
I won’t insult you by explaining once again what JSON Web Tokens (JWTs) are, and how to attack them. A plethora of awesome articles exists on the Web, descri...
A few days ago, I published a blog post about PHP webshells, ending with a discussion about filters evasion by getting rid of the pattern $_. The latter is c...
A few thoughts about PHP webshells …
I remember this carpet, at the entrance of the Computer Science faculty, with this message There’s no place like 127.0.0.1/8. A joke that would create two ca...
TL;DR A few experiments about mixed managed/unmanaged assemblies. To begin with, we start by presenting a C# programme that hides a part of its payload in an...
It was a sunny and warm summer afternoon, and while normal people would rush to the beach, I decided to devote myself to one of my favourite activities: suff...
The reader should first take a look at the articles related to CVE-2023-3032 and CVE-2023-3033 that I published a few days ago to get more context.
This walkthrough presents another vulnerability discovered on the Mobatime web application (see CVE-2023-3032, same version 06.7.2022 affected). This vulnera...
Mobatime offers various time-related products, such as check-in solutions. In versions up to 06.7.2022, an arbitrary file upload allowed an authenticated use...
King-Avis is a Prestashop module developed by Webbax. In versions older than 17.3.15, the latter suffers from an authenticated path traversal, leading to loc...
Let’s render unto Caesar the things that are Caesar’s, the exploit FuckFastCGI is not mine and is a brilliant one, bypassing open_basedir and disable_functio...
I have to admit, PHP is not my favourite, but such powerful language sometimes really amazes me. Two days ago, I found a bypass of the directive open_basedir...
PHP is a really powerful language, and as a wise man once said, with great power comes great responsibilities. There is nothing more frustrating than obtaini...
A few weeks ago, a good friend of mine asked me if it was possible to create such a program, as it could modify itself. After some thoughts, I answered that ...
In the previous article, I described how I wrote a simple polymorphic program. “Polymorphic” means that the program (the binary) changes its appearance every...
The malware presented in this blog post appeared on Google Play in 2016. I heard about it thanks to this article published on checkpoint.com. The malicious a...
Ransomwares are really interesting malwares because of their very specific purpose. Indeed, a ransomware will not necessarily try to be stealth or persistent...
A few days ago, I found this article about a malware targeting Sberbank, a big Russian bank. The app disguises itself as a web application, stealing in backg...
RuMMS is a malware targetting Russian users, distributed via websites as a file named mms.apk [1]. This article is inspired by this analysis made by FireEye ...
Could a 5-classes Android app be so harmful ? dsencrypt says “yes”…
~$ cat How_an_Android_app_could_escalate_its_privileges_Part4.txt
~$ cat How_an_Android_app_could_escalate_its_privileges_Part3.txt
~$ cat How_an_Android_app_could_escalate_its_privileges_Part2.txt
~$ cat How_an_Android_app_could_escalate_its_privileges.txt
Even if the thesis introduces the extensions internals, and analyses the difference between mobile and desktop browsers in terms of likelihood, efficiency an...