
Kostenloser Analyse-Tool für kompromittierte Zugriffsprotokolle: Webshell-Interaktionen, Exploit-Muster und Brute-Force-Ausbrüche in Ihren Apache-/nginx-Protokollen – Schweregrad, Konfidenz, Behebung. Nur-Lese-Zugriff.
Ihre Webserver-Logs wissen bereits, ob Sie angegriffen wurden. weblogchecker liest sie.
phpscan sagt Ihnen, ob Ihr PHP exponiert ist. phpscan hunt durchsucht das
Webroot nach Shells. weblogchecker beantwortet die dritte Frage — hat sie
tatsächlich jemand benutzt? — anhand des einen Datensatzes, den die meisten
Seiten bereits besitzen und den niemand liest: das Access-Log.
Es streamt Apache- und nginx-Access-Logs, die Ihnen gehören, findet die Interaktionen, die zählen — eine Webshell, die Anfragen beantwortet, ein Brute-Force-Ausbruch, der in einer Weiterleitung endet, ein Exploit-Muster, das ein 200 erhalten hat — und meldet jeden einzelnen mit Schweregrad, Konfidenz, den tatsächlichen Logzeilen als Beleg und dem, was zu tun ist.
weblogchecker analyze /var/log/apache2/access.log
Exit-Codes: 0 = keine Indikatoren, 1 = Indikatoren gefunden, 2 = Nutzungsfehler.
Fügen Sie --format json für maschinenlesbare Ausgabe hinzu, --since 2026-10-01, um
das Zeitfenster einzuschränken. .gz-Logs werden direkt gelesen; - liest von stdin.
Neu in 0.2.0 — Baseline-Diff. Signaturlisten kennen nur Shells, die bereits Namen haben. Die Shell, die auf Ihrer Site landet, hat einen zufälligen. Geben Sie weblogchecker ein vertrauenswürdiges älteres Log von derselben Site und es meldet die ausführbaren Dateien, die vorher nie dort waren:
weblogchecker analyze access.log --baseline access.log.last-month
Jeder ausführbare Pfad (.php, .phtml, .cgi, .asp, .jsp…), der zum ersten Mal erscheint, wird anhand von fünf schwachen Signalen allein aus dem Log bewertet — mit 2xx/3xx beantwortet, POST/PUT verwendet, referrer-los, von höchstens 2 IPs aufgerufen, unter einem Upload-/Cache-/Temp-Verzeichnis liegend — und als NEW mit den Signalen, Zählungen und Logzeilen als Beleg gemeldet. Erstmaliges Auftreten allein ist ein Hinweis mit geringer Schwere; die Schwere steigt erst, wenn sich Signale häufen (Details unten), sodass ein Plugin, das Sie letzte Woche installiert haben, nicht als Vorfall gelesen wird.
Eine Zeile, von PyPI (Python 3.11+, nur Standardbibliothek — keine Abhängigkeiten):
pip install weblogchecker
Erste PyPI-Veröffentlichung steht aus. Bis der PyPI Trusted Publisher konfiguriert ist, installieren Sie den identischen Code von GitHub:
pip install git+https://github.com/PHPatch/weblogchecker.git(oder laden Sie das signierte Release-Tarball unten herunter). Die obige Zeilepip install weblogcheckerfunktioniert, sobald die erste PyPI-Veröffentlichung erfolgt ist.
Auf Systemen, die mit „externally-managed-environment“ ablehnen (Debian/Ubuntu und Homebrew-Pythons), verwenden Sie stattdessen pipx:
python3 -m pip install --user pipx # if you don't have pipx yet
pipx install weblogchecker
Signierte Releases (sdist + wheel + PGP-Signaturen + SBOM) befinden sich auf der
GitHub-Releases-Seite.
Verifiziere die Signaturen mit dem Schlüssel in pgp-key.asc — Fingerabdruck
BAA1 586A AD37 18C0 CE41 D288 FE23 A624 54E3 5307. Siehe SECURITY.md.
| Muster in deinem Log | Schweregrad / Konfidenz | Warum es wichtig ist |
|---|---|---|
| Bekannte Webshell (c99, r57, FilesMan, b374k, WSO), die mit 2xx antwortet | hoch / hoch | Die Shell existiert und hat eine Anfrage bedient |
| Dieselben Namen sondiert, aber 404/403 | niedrig / niedrig | Jemand hat nachgesehen; nichts gefunden — Kontext, kein Alarm |
eval-stdin.php (phpunit), das antwortet | hoch / hoch | Die UnitTest-Shell aus der php2shell-Welle vom Okt. 2026 führt per POST übergebenen Code aus |
Ausführbare Datei (.php usw.) in /uploads/, /media/, /files/…, die antwortet, insb. auf POST | hoch / hoch | Upload-Verzeichnisse dürfen niemals Code ausführen |
| POST/PUT auf eine statische Datei (.jpg, .css…), mit 2xx beantwortet | hoch / mittel | Browser senden kein POST an Bilder; das „Bild" ist oft ein Skript |
Exploit-Muster in der URI (Traversal, eval(, php://, langes Base64-Token), mit 2xx beantwortet | hoch / mittel | Der Versuch könnte erfolgreich gewesen sein |
| Dieselben Muster blockiert / 404 | niedrig / niedrig | Hintergrundrauschen; nur als Kampagnenkontext nützlich |
| Brute-Force-Ausbruch auf wp-login.php / xmlrpc.php (≥20 POSTs / 10 Min.) | mittel / mittel | Eine IP, unmenschliches Tempo |
| Ein 302 innerhalb dieses Ausbruchs nach wiederholten Fehlschlägen | hoch / mittel | Die Form eines korrekten Passworts — mögliche Übernahme |
| Scanner-User-Agents (sqlmap, nuclei, nikto…) | niedrig / niedrig | Informativ; Scannen ist keine Kompromittierung |
Ausführbarer Pfad, der in deinem --baseline-Log fehlt und Anfragen beantwortet | niedrig → hoch / ≤ mittel | Die Shell mit unbekanntem Namen, die keine Blocklist kennt; der Schweregrad steigt mit POSTs, fehlenden Referrern, wenigen IPs, Upload-Verzeichnissen |
Jede Fundklasse enthält Behebungstext: die Datei in Quarantäne verschieben,
Anmeldedaten rotieren, alles überprüfen, was diese IP berührt hat. Webshell-Funde
verweisen auf das Begleitwerkzeug — phpscan hunt (pip install phpscan,
github.com/PHPatch/phpscan) —, das
das Webroot selbst nach den Shells durchsucht, auf die diese Log-Muster hinweisen.
Dieses Werkzeug wurde nach derselben Doktrin gebaut wie phpscan:
Das Parsen erfolgt als Line-Streaming: Die Datei wird nie in den Speicher geladen, und die Aggregation behält höchstens fünf Evidenzzeilen pro Befund. Gemessen am Fixture-Generator dieses Projekts (366.306 Zeilen, 72 MB realistisches kombiniertes Log): 7,6 Sekunden, 12,8 MB Spitzen-RSS auf einer bescheidenen VM. Ein 2-GB-Log benötigt denselben Speicher, proportional mehr Zeit.