
Analyseur gratuit de compromission de journaux d'accès : interactions avec des webshells, schémas d'exploitation et rafales de force brute dans vos journaux Apache/nginx - gravité, confiance, remédiation. Lecture seule.
Vos journaux de serveur web savent déjà si vous avez été attaqué. weblogchecker les lit.
phpscan vous indique si votre PHP est exposé. phpscan hunt fouille la
racine web à la recherche de shells. weblogchecker répond à la troisième question — quelqu'un
les a-t-il réellement utilisés ? — à partir du seul enregistrement que la plupart des sites possèdent déjà et que personne
ne lit : le journal d'accès.
Il traite en flux les journaux d'accès Apache et nginx qui vous appartiennent, identifie les interactions qui comptent — un webshell qui répond à des requêtes, une rafale de force brute qui se termine par une redirection, un motif d'exploit qui a obtenu un 200 — et signale chacune d'elles avec la sévérité, la confiance, les lignes de journal réelles comme preuve, et ce qu'il faut faire à ce sujet.
weblogchecker analyze /var/log/apache2/access.log
Codes de sortie : 0 = aucun indicateur, 1 = indicateurs trouvés, 2 = erreur d'utilisation.
Ajoutez --format json pour une sortie lisible par machine, --since 2026-10-01 pour
limiter la fenêtre. Les journaux .gz sont lus directement ; - lit stdin.
Nouveau dans la 0.2.0 — diff de référence. Les listes de signatures ne connaissent que les shells qui ont déjà un nom. Le shell qui atterrit sur votre site en a un aléatoire. Fournissez à weblogchecker un ancien journal de confiance du même site et il signale les exécutables qui n'y étaient jamais présents auparavant :
weblogchecker analyze access.log --baseline access.log.last-month
Tout chemin exécutable (.php, .phtml, .cgi, .asp, .jsp…) qui apparaît pour
la première fois est évalué sur cinq signaux faibles à partir du journal seul —
réponse 2xx/3xx, POST/PUT utilisé, absence de référent, accès par au plus 2 IP,
situé sous un répertoire upload/cache/temp — et signalé comme NEW
avec les signaux, les comptages et les lignes de journal comme preuves. La première
apparition seule est une note de faible gravité ; la gravité augmente uniquement à mesure que les signaux s'accumulent (détails
ci-dessous), ainsi un plugin que vous avez installé la semaine dernière n'est pas lu comme un
incident.
Une ligne, depuis PyPI (Python 3.11+, bibliothèque standard uniquement — zéro dépendance) :
pip install weblogchecker
Première publication PyPI en attente. Tant que le trusted publisher PyPI n'est pas configuré, installez le code identique depuis GitHub :
pip install git+https://github.com/PHPatch/weblogchecker.git(ou téléchargez l'archive de release signée ci-dessous). La lignepip install weblogcheckerci-dessus fonctionne dès que la première publication PyPI est disponible.
Sur les systèmes qui refusent avec « externally-managed-environment » (Python Debian/Ubuntu et Homebrew), utilisez plutôt pipx :
python3 -m pip install --user pipx # if you don't have pipx yet
pipx install weblogchecker
Les versions signées (sdist + wheel + signatures PGP + SBOM) sont disponibles sur la
page des releases GitHub.
Vérifiez les signatures avec la clé dans pgp-key.asc — empreinte
BAA1 586A AD37 18C0 CE41 D288 FE23 A624 54E3 5307. Voir SECURITY.md.
| Motif dans votre journal | Sévérité / confiance | Pourquoi c'est important |
|---|---|---|
| Webshell connue (c99, r57, FilesMan, b374k, WSO) répondant en 2xx | élevée / élevée | Le shell existe et a servi une requête |
| Mêmes noms sondés mais en 404/403 | faible / faible | Quelqu'un a cherché ; rien trouvé — contexte, pas alerte |
eval-stdin.php (phpunit) répondant | élevée / élevée | Le shell UnitTest de la vague php2shell d'oct. 2026 exécute le code envoyé en POST |
Exécutable (.php etc.) dans /uploads/, /media/, /files/… répondant, surtout en POST | élevée / élevée | Les répertoires d'upload ne doivent jamais exécuter de code |
| POST/PUT vers un fichier statique (.jpg, .css…) répondu en 2xx | élevée / moyenne | Les navigateurs ne font pas de POST vers des images ; l'« image » est souvent un script |
Motif d'exploit dans l'URI (traversée, eval(, php://, long jeton base64) répondu en 2xx | élevée / moyenne | La tentative a peut-être réussi |
| Mêmes motifs bloqués / en 404 | faible / faible | Bruit de fond ; utile uniquement comme contexte de campagne |
| Rafale de force brute sur wp-login.php / xmlrpc.php (≥20 POST / 10 min) | moyenne / moyenne | Une seule IP, rythme inhumain |
| Un 302 dans cette rafale après des échecs répétés | élevée / moyenne | La forme d'un mot de passe correct — prise de contrôle possible |
| User-agents de scanners (sqlmap, nuclei, nikto…) | faible / faible | Informatif ; scanner n'est pas compromettre |
Chemin d'exécutable absent de votre journal --baseline, répondant aux requêtes | faible → élevée / ≤ moyenne | Le shell au nom inconnu qu'aucune blocklist ne connaît ; la sévérité s'accumule avec les POST, les referrers manquants, peu d'IP, les répertoires d'upload |
Chaque classe de détection porte un texte de remédiation : mettre le fichier en quarantaine, renouveler
les identifiants, examiner tout ce que cette IP a touché. Les détections de webshell renvoient vers
l'outil compagnon — phpscan hunt (pip install phpscan,
github.com/PHPatch/phpscan) — qui
scanne la racine web elle-même pour les shells vers lesquels ces motifs de journal pointent.
Cet outil a été construit selon la même doctrine que phpscan :