> For the complete documentation index, see [llms.txt](https://ne0b1t3.gitbook.io/vault/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ne0b1t3.gitbook.io/vault/eng/prolabs/dante.md).

# Dante

## <mark style="color:$warning;">Certification of Completion</mark>

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

Although Dante is generally considered the most accessible Pro Lab in Hack The Box, I personally found it to be one of the most valuable stepping stones toward larger and more complex environments.

Its difficulty does not come from highly advanced techniques or obscure vulnerabilities. Instead, it forces you to develop a solid methodology, stay organized, and learn how to properly correlate the information gathered throughout the engagement.

Before attempting Dante, there are several core skills that I strongly recommend being comfortable with.

***

### <mark style="color:$primary;">Systematic Enumeration</mark>

Enumeration is, by far, the most important skill throughout the entire Pro Lab. You'll be dealing with an infrastructure containing dozens of users, multiple hosts (approximately 15 machines), numerous services, web applications, and segmented networks.

<figure><img src="/files/Bw39ZbemREgXvEexE8Tr" alt="" width="263"><figcaption><p>All computers to be compromised</p></figcaption></figure>

Enumeration is, without a doubt, the most important skill in the entire Pro Lab, as we will be facing infrastructure with dozens of users, multiple hosts (\~15 machines), services, applications, and segmented networks.

You need to be comfortable enumerating services, reviewing configurations, analyzing web applications and CMS, as well as searching for sensitive information stored on the system (e.g., essential paths like `/opt`, `/var`, `/etc`, ...)\
Local enumeration is also common, reviewing users, their groups and descriptions, running services, active processes, scheduled tasks, internal hosts, and any type of sensitive configuration that might give a clue for privilege escalation or lateral movement.

In Windows environments, it's also worth paying special attention to software installed outside the usual locations, especially those in paths like `C:\Program Files`, `C:\ProgramData`, or `C:\Users<user>\AppData`, since many interesting findings come from applications added by users or administrators rather than from the system itself.

### <mark style="color:$primary;">Web Explotation</mark>

The web vulnerabilities present in Dante are relatively common, so you should be comfortable identifying and exploiting scenarios like Local File Inclusion (LFI), Path Traversal, PHP Wrappers, or SQL Injection.

<figure><img src="/files/EWOJqE2uNEQiwLaxRAF1" alt=""><figcaption><p>Local File Inclusion</p></figcaption></figure>

Beyond exploiting the vulnerability itself, it's important to understand what information can be obtained afterward: credentials stored in configuration files, sensitive database information, or passwords reused across other systems.

<figure><img src="/files/VfffWF8i534WbVDKScTm" alt=""><figcaption><p>SQL Injection</p></figcaption></figure>

***

### <mark style="color:$primary;">Credential Reuse</mark>

Probably the most important skill in the entire Pro Lab.\
A large part of lateral movement in Dante is based on reusing previously obtained information.\
Every new credential must be immediately validated against all services identified so far, including SSH, SMB, FTP, NFS, web applications, and databases.\\

\
If direct access isn't achieved, it's recommended to perform password spraying against the rest of the users discovered during enumeration, or to generate custom wordlists, something that was necessary at some steps.\\

\
During this Pro Lab, I ended up developing a small Python script as a personal "vault" where I stored users, passwords, hosts, services, ports, trust relationships, firewall rules, as well as enumeration notes.

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

I'm sharing the small script here in case someone wants to use it, modify it, or draw inspiration from it. Even so, I always recommend trying to create your own tools. Even if they're simpler, it's one of the best ways to practice languages like Python, Bash, PowerShell, Rust, or Go and truly understand how the techniques we use daily work.

{% code title="/usr/bin/vault" overflow="wrap" lineNumbers="true" expandable="true" %}

```python
#!/usr/bin/python3
import json
import os
import hashlib
from datetime import datetime

VAULT_FILE = "vault.json"

# ---------- NTLM HASH ----------
def ntlm_hash(password):
    return hashlib.new('md4', password.encode('utf-16le')).hexdigest()

# ---------- LOAD / SAVE ----------
def load_vault():
    if not os.path.exists(VAULT_FILE):
        return []
    with open(VAULT_FILE, "r") as f:
        return json.load(f)


def save_vault(data):
    with open(VAULT_FILE, "w") as f:
        json.dump(data, f, indent=4)

# ---------- TABLE RENDER ----------
def render_table(data):
    headers = ["ID", "Username", "Password", "Machine", "IP", "Hash", "Date"]

    # Calculate column widths
    col_widths = [len(h) for h in headers]

    rows = []
    for i, row in enumerate(data, 1):
        r = [
            str(i),
            row["username"],
            row["password"],
            row["machine"],
            row["ip"],
            row["hash"],
            row["date"]
        ]
        rows.append(r)
        for idx, val in enumerate(r):
            col_widths[idx] = max(col_widths[idx], len(str(val)))

    def separator():
        return "+" + "+".join("-" * (w + 2) for w in col_widths) + "+"

    def format_row(row):
        return "| " + " | ".join(str(val).ljust(w) for val, w in zip(row, col_widths)) + " |"

    print(separator())
    print(format_row(headers))
    print(separator())

    for r in rows:
        print(format_row(r))

    print(separator())

# ---------- DISPLAY ----------
def show_vault(data):
    os.system("cls" if os.name == "nt" else "clear")

    print(r"""
██╗   ██╗ █████╗ ██╗   ██╗██╗  ████████╗     ██████╗██████╗ ███████╗██████╗ ███████╗
██║   ██║██╔══██╗██║   ██║██║  ╚══██╔══╝    ██╔════╝██╔══██╗██╔════╝██╔══██╗██╔════╝
██║   ██║███████║██║   ██║██║     ██║       ██║     ██████╔╝█████╗  ██║  ██║███████╗
╚██╗ ██╔╝██╔══██║██║   ██║██║     ██║       ██║     ██╔══██╗██╔══╝  ██║  ██║╚════██║
 ╚████╔╝ ██║  ██║╚██████╔╝███████╗██║       ╚██████╗██║  ██║███████╗██████╔╝███████║
  ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚══════╝╚═╝        ╚═════╝╚═╝  ╚═╝╚══════╝╚═════╝ ╚══════╝

        by Ne0Byte

----------------------------------------------------------------------
""")

    print("[+] Stored Credentials:\n")
    if data:
        render_table(data)
    else:
        print("(empty)")

    print("\nCommands:")
    print("1 - New Creds --continue-on-success --no-bruteforce")
    print("2 - Exit")
    print("3 - Edit Creds")
    print("5 - Reset Vault")

# ---------- ADD CREDS ----------
def add_creds(data):
    print("\n[+] Enter new credentials")

    username = input("Username: ")

    hash_value = input("NTLM Hash (leave empty if unknown): ")
    password = input("Password (leave empty if unknown): ")

    if password and not hash_value:
        hash_value = ntlm_hash(password)

    machine = input("Machine: ")
    ip = input("IP: ")

    date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    entry = {
        "username": username,
        "password": password,
        "machine": machine,
        "ip": ip,
        "hash": hash_value,
        "date": date
    }

    data.append(entry)
    save_vault(data)

    # --- append files ---
    with open("users.txt", "a") as f:
        f.write(username + "\n")

    with open("passwords.txt", "a") as f:
        f.write(password + "\n")

    with open("hashes.txt", "a") as f:
        f.write(hash_value + "\n")

# ---------- EDIT -----------
def edit_creds(data):
    if not data:
        print("[-] Vault empty")
        input("Press Enter...")
        return

    render_table(data)

    try:
        idx = int(input("\nSelect ID to edit: ")) - 1
    except ValueError:
        print("Invalid ID")
        return

    if idx < 0 or idx >= len(data):
        print("ID out of range")
        return

    entry = data[idx]

    print("\n[+] Editing entry (leave empty to keep current value)\n")

    username = input(f"Username [{entry['username']}]: ") or entry["username"]

    hash_value = input(f"NTLM Hash [{entry['hash']}]: ") or entry["hash"]
    password = input(f"Password [{entry['password']}]: ") or entry["password"]

    # regenerate hash if password changed and hash missing/old empty
    if password and not hash_value:
        hash_value = ntlm_hash(password)

    machine = input(f"Machine [{entry['machine']}]: ") or entry["machine"]
    ip = input(f"IP [{entry['ip']}]: ") or entry["ip"]

    entry.update({
        "username": username,
        "password": password,
        "machine": machine,
        "ip": ip,
        "hash": hash_value,
        "date": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    })

    save_vault(data)

    print("\n[+] Entry updated")
    input("Press Enter...")

# ---------- RESET ----------
def reset_vault():
    confirm = input("Are you sure? (y/n): ")
    if confirm.lower() == "y":
        save_vault([])
        print("[!] Vault reset!")

# ---------- MAIN ----------
def main():
    data = load_vault()

    while True:
        show_vault(data)
        choice = input("\nSelect option: ")

        if choice == "1":
            add_creds(data)
        elif choice == "2":
            break
        elif choice == "3":
            edit_creds(data)
        elif choice == "5":
            reset_vault()
            data = []
        else:
            print("Invalid option")

if __name__ == "__main__":
    main()
```

{% endcode %}

This may seem trivial, but when you start managing more than a dozen systems, users, and multiple network segments, organization ceases to be an advantage and becomes a necessity.

### <mark style="color:$primary;">Privilege Escalation</mark>

In terms of privilege escalation, you should be comfortable enumerating current user privileges (`sudo -l`), cron jobs, processes run by privileged users, custom services, and insecure permissions.

{% tabs %}
{% tab title="Linux" %}
On Linux, techniques like library hijacking or Python module hijacking appear, along with binaries with insecure configurations or permissions, or scheduled tasks executed as a privileged user (generally root).
{% endtab %}

{% tab title="Windows" %}
On Windows, there's practically no Active Directory-related content, but there are several local privilege escalations.\
You should be comfortable enumerating SMB/MSSQL services, scheduled tasks, insecure permissions, Unquoted Service Paths, and other famous Windows vulnerabilities.
{% endtab %}
{% endtabs %}

Many times, the difference between gaining administrative access or getting stuck lies solely in correctly identifying which processes run periodically and under what context.

***

### <mark style="color:$primary;">Post-Explotation</mark>

Once a system is compromised, it's important to go beyond just getting a shell.\
Some tasks I constantly performed during the Pro Lab were escaping restricted shells, using [GTFOBins](https://gtfobins.org/), maintaining persistence via SSH keys, reviewing histories and configurations, enumerating local users, and extracting hashes from `/etc/shadow` for later cracking.

<figure><img src="/files/JcB00PgCyZPrVmq7K86y" alt=""><figcaption><p>GTF Obins - List of Unix executables for bypassing local security restrictions</p></figcaption></figure>

n the case of Windows, it was also necessary to know how to dump SAM, LSASS, or NTDS, as well as credentials stored in scheduled tasks.\\

\
Persistence via SSH keys deserves special mention. \
In environments where we continuously rely on tunnels and pivots, losing a session can force us to rebuild an entire access chain. That wasn't my case since I operated with Ligolo, but I know many experiences where it was more difficult when pivoting with socat and chisel.

### <mark style="color:$primary;">Lateral Movement</mark>

An extremely underrated skill. A large part of lateral movement in Dante doesn't come from complex vulnerabilities, but from information discovered while reviewing seemingly innocent files.\
\
My recommendation is simple: **every file that doesn't seem to belong to the operating system deserves to be reviewed**. Emails, internal documents, application exports, custom configurations, scripts developed by users, or manually installed applications often contain much more valuable information than many vulnerabilities.\\

\
And here comes a common question: <mark style="color:$primary;">**How do I know if a file is normal or not**</mark><mark style="color:$primary;">?</mark>\
\
The answer is simple: **experience**. Over time, you develop the ability to quickly differentiate what belongs to the operating system from what has been added later by users or administrators. That's why I always recommend solving many machines and familiarizing yourself with the typical Linux and Windows structure before tackling labs of this size.

***

### <mark style="color:$primary;">Approximate Lab Topology</mark>&#xD;

I must admit that I created the complete infrastructure topologies (in [Excalidraw](https://excalidraw.com/)) after finishing each Pro Lab, since in my case I organized myself well enough not to rely on a visual schematic.\
\
However, I know several colleagues and people who recommend them and have found them very helpful, as they are often a very useful way to visualize the entire infrastructure in real time.

<figure><img src="/files/gkGEybQy1yW4Mco6Agat" alt=""><figcaption><p>Lab Infrastructure</p></figcaption></figure>

***

### <mark style="color:$primary;">Main Tools</mark>

Throughout all the Pro Labs, I ended up using dozens of **different tools**, but there are some that appeared recurrently and with which I consider it **essential** to be comfortable before facing environments of this size.\\

\
It's **not necessary** to master **all these tools from memory**; what matters is understanding what problem each one solves and when to use it.

#### <mark style="color:$tint;">Tunneling and Pivoting</mark>

The tool I used was [Ligolo-ng](https://github.com/nicocha30/ligolo-ng). Personally, I think it's one of the best options for pivoting currently, as it's easy to deploy, very stable, and extremely comfortable to use.

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

Its main advantage is that it allows tunneling all network traffic, making internal hosts accessible from our attacking machine as if they were part of our own local network. This greatly simplifies enumeration, exploitation, and lateral movement tasks.\\

\
Even so, it's always advisable to master alternatives, since not all environments allow the use of Ligolo or modern binaries. Among them are local port forwarding, dynamic port forwarding (SOCKS), remote port forwarding, Chisel, Socat, Metasploit with autoroute and socks proxy, or FoxyProxy for accessing web applications.\\

\
These options allow building more manual pivoting chains using SOCKS and ProxyChains, which is especially useful in older or highly restricted environments.

#### <mark style="color:$tint;">Enumeration</mark>

Enumeration probably represents more than 70% of the work during the Pro Lab. The most used tools were:

{% code title="" overflow="wrap" lineNumbers="true" %}

```
Nmap
NetExec (NXC)
Showmount
SMBClient
SMBMap
Burp Suite
Curl/Wget
RpcClient
MSSQLClient
LinPEAS
WinPEAS
PowerUp
Pspy
Metasploit (local exploit suggester)
```

{% endcode %}

More important than knowing each tool is understanding what information to look for and how to relate it to the rest of the findings obtained.

#### <mark style="color:$tint;">File Transfer</mark>

La File transfer of tools and payloads is a constant task during any assessment.de herramientas y payloads es una tarea constante durante cualquier evaluación.

{% tabs %}
{% tab title="Linux" %}
On Linux, I mainly used **SCP** over SSH, **HTTP** servers with **Curl** or **Wget**, and **Base64** encoding.
{% endtab %}

{% tab title="Windows" %}
On Windows, on the other hand, common methods were **SMB** servers, HTTP servers with **CertUtil**, **Invoke-WebRequest**, **PowerShell**, and **Base64** via `System.Text.Encoding`.
{% endtab %}
{% endtabs %}

Having several methods prepared is key when there are network restrictions or PowerShell limitations (which wasn't the case in this Pro Lab).

#### <mark style="color:$tint;">Persistence and Cracking</mark>

Although not the main focus, tools like Hashcat, John the Ripper, Hydra, NetExec for password spraying, SSH-Keygen, and Mimikatz were recurrent.\\

\
**Hashcat** and **John** allowed hash cracking, while **Hydra** and **NetExec** were used to validate credential reuse.\
**SSH-Keygen**, for its part, was especially useful for maintaining persistence via SSH keys, something critical in environments with constant pivoting.

#### <mark style="color:$tint;">Explotation</mark>

In terms of exploitation, there aren't usually particularly complex vulnerabilities, but it is important to handle tools like **SQLMap**, **WPScan**, **Metasploit**, and **Burp Suite**.\\

\
However, most compromises in Dante don't come from automated tools, but from good enumeration, information correlation, and credential reuse.

***

### <mark style="color:$primary;">Lesson Learned</mark>

Personally, I was pleasantly surprised by my first Pro Lab.\\

\
Nothing in Dante is especially complex on its own; rather, the real challenge lies in correctly connecting each small piece of information obtained during enumeration:

> One credential leads to a new system. That system contains an interesting file. That file reveals a new password. That password provides access to another service.> \
> And so on.

Precisely that ability to chain small findings and turn them into a complete compromise chain is one of the most important skills for tackling more advanced Pro Labs like Zephyr, Offshore, or RastaLabs.\\

\
For that reason, I consider the greatest lesson learned to be practicing organization. Both for completing Pro Labs and for functioning effectively in real environments without wasting time.


---

# 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:

```
GET https://ne0b1t3.gitbook.io/vault/eng/prolabs/dante.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
