feat: tools/waechter.ps1 -- zaehlt offene Tueren und rechnet Dateien nach
Die Statusseite war waehrend des Einbruchs die ganze Zeit gruen. Sie waere auch
gruen geblieben, wenn der Miner gelaufen waere. Es fehlte kein Bildschirm, auf
dem man es haette sehen koennen -- es fehlte etwas, das VON SICH AUS Bescheid
sagt. Deshalb kein Frontend, sondern zwei Pruefungen mit Meldeweg.
1. Ports, die auf allen Adressen lauschen, gegen einen hinterlegten Stand.
Port 3000 stand elf Tage offen; das haette am ersten Tag gemeldet werden
koennen. Dazu eine feste Liste heikler Ports, die auch dann warnt, wenn
der Zustand "schon immer so" war -- 3000 war auch schon immer so.
2. Pruefsummen ueber sshd_config, administrators_authorized_keys, beide
Compose-Dateien und Giteas app.ini und .gitconfig. Der Angriff WAR eine
Datei, die sich um 21:13:57 aenderte.
Gemeldet wird nur bei Aenderung, mit Merker in den Einstellungen. Ein Waechter,
der taeglich meckert, wird stummgeschaltet und ist dann schlechter als keiner.
VOR DEM EINRICHTEN AN BEIDEN FAELLEN BEWIESEN statt behauptet:
Testport 45999 geoeffnet -> "NEU offen: 45999"
Datei geaendert -> Meldung raus, HTTP 204
zurueckgestellt -> "Wieder in Ordnung (Merker geleert)"
Und er prueft zuerst, ob er ueberhaupt etwas sehen kann: findet er keine
Objekte, meldet er "ungueltig" statt "sauber". Das ist die Lehre aus zwei
Suchen in dieser Nacht, die genau das verwechselt haben.
Die Statusseite zeigt den Stand mit; meldet der Waechter sich zwei Stunden
nicht, ist DAS der Befund -- er laeuft alle 15 Minuten.
Im Bericht ausserdem nachgetragen: die Inventur von aussen (NPM-Verwaltung und
MariaDB standen offen, beide jetzt gesperrt), die abgeschalteten Ueberbleibsel
von Caddy und cloudflared, und zwei Irrtuemer von mir -- "Docker geht an der
Firewall vorbei" und "der MariaDB-root hat kein Passwort". Beide waren aus
Messungen geschlossen, die die Frage nicht beantworten konnten.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -168,3 +168,94 @@ Seitdem laufen die Angriffe ins Leere:
|
||||
00:53:12 Connection closed by invalid user root 31.77.227.120 [preauth]
|
||||
alle 12 erfolgreichen Anmeldungen: eine IP, die des Betreibers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Nachtrag 13.08.2026, vormittags: die Inventur, und drei Irrtümer von mir
|
||||
|
||||
### Was von außen wirklich offen war
|
||||
|
||||
Erst eine Messung **vom Heimrechner** hat die Lage geklärt — vom Server aus ist
|
||||
sie nicht zu beantworten:
|
||||
|
||||
```
|
||||
vorher nachher
|
||||
80 True (gewollt) 80 True
|
||||
81 True NPM-Verwaltung 81 False
|
||||
135 True Windows-RPC 135 False
|
||||
3306 True MariaDB 3306 False
|
||||
445/3389/5985/9000/9443/11000 durchweg False
|
||||
```
|
||||
|
||||
**Die Verwaltungsoberfläche des Reverse-Proxys und eine Datenbank standen offen
|
||||
im Internet.** Beides ist jetzt per Firewall gesperrt; die NPM-Oberfläche
|
||||
erreicht man weiter über `https://proxy.d4rkst3r.de`, weil sie containerintern
|
||||
auf `127.0.0.1:81` läuft.
|
||||
|
||||
### ⚠️ Irrtum 1: „Docker geht an der Windows-Firewall vorbei"
|
||||
|
||||
**Falsch.** Port 81 wird von Docker veröffentlicht, und die Sperrregel greift
|
||||
dort sehr wohl — nachgemessen von außen. Ich hatte das Gegenteil behauptet,
|
||||
nachdem ich es *vom Server aus* geprüft hatte, und deswegen sogar eine Regel
|
||||
wieder gelöscht. Verkehr an die eigene öffentliche Adresse durchläuft die
|
||||
Eingangsregeln nicht; diese Messung kann die Frage gar nicht beantworten.
|
||||
|
||||
### ⚠️ Irrtum 2: „Der MariaDB-root hat kein Passwort"
|
||||
|
||||
**Falsch.** Er hat eines — das FiveM benutzt. Dass ich ohne hineinkam, liegt an
|
||||
der Standardeinrichtung von MariaDB unter Windows:
|
||||
|
||||
```json
|
||||
"plugin": "mysql_native_password",
|
||||
"auth_or": [ { }, { "plugin": "gssapi", "authentication_string": "SID:BA" } ]
|
||||
```
|
||||
|
||||
`auth_or` heißt „oder": Passwort **oder** Windows-Authentifizierung, und
|
||||
`SID:BA` ist die Gruppe der lokalen Administratoren. Ich war als Administrator
|
||||
unterwegs. Ein Angreifer aus dem Internet hat keine Windows-Identität — MySQL
|
||||
fällt als Einbruchsweg aus.
|
||||
|
||||
Meine Prüfung davor war kaputt (`JSON_LENGTH` auf eine Zeichenkette gibt immer
|
||||
`NULL`), und statt das zu bemerken, habe ich das Ergebnis geglaubt.
|
||||
|
||||
### Vergessene Dienste — der Verdacht des Betreibers war richtig
|
||||
|
||||
```
|
||||
Caddy-AutoStart [Ready] beim Systemstart nie gelaufen
|
||||
CloudflaredTunnel [Ready] beim Systemstart nie gelaufen
|
||||
C:\Users\Darkster\.cloudflared\ Tunnel-Zugangsdaten vom 23.03.2026
|
||||
```
|
||||
|
||||
Beide waren **aktiv** und wären beim nächsten Neustart angesprungen. Ein Tunnel
|
||||
ist ein Eingang, der an jeder Firewall vorbeigeht, weil er von innen aufgebaut
|
||||
wird. Umfang war eng (`fivem-api.d4rkst3r.de` → `localhost:30121`, wo nichts
|
||||
lauscht), der Caddyfile leer. Beide Aufgaben sind **abgeschaltet, nicht
|
||||
gelöscht**.
|
||||
|
||||
**Offen für den Betreiber:** den Tunnel `3a4a599b-…` im Cloudflare-Konto
|
||||
löschen. Solange er dort registriert ist, sind die Zugangsdaten auf der Platte
|
||||
gültig.
|
||||
|
||||
Außerdem gefunden: **Azure Arc** (vier Dienste, seit 04.08., Status
|
||||
`Disconnected`, ohne Abonnement) — vermutlich aus dem Anbieter-Abbild. Und
|
||||
**IPBan** läuft, ein Brute-Force-Blocker.
|
||||
|
||||
### Der Wächter
|
||||
|
||||
`tools/waechter.ps1`, alle 15 Minuten. Zählt die Ports, die auf allen Adressen
|
||||
lauschen, und rechnet Prüfsummen über `sshd_config`,
|
||||
`administrators_authorized_keys`, beide Compose-Dateien sowie Giteas `app.ini`
|
||||
und `.gitconfig`. Gemeldet wird **nur bei Änderung**, und die Statusseite zeigt
|
||||
den Stand.
|
||||
|
||||
Vor dem Einrichten an beiden Fällen bewiesen, statt es zu behaupten:
|
||||
|
||||
```
|
||||
Testport 45999 geoeffnet -> "NEU offen: 45999"
|
||||
Datei harmlos geaendert -> Meldung raus, HTTP 204
|
||||
Datei zurueckgestellt -> "Wieder in Ordnung (Merker geleert)"
|
||||
```
|
||||
|
||||
Er prüft zuerst, ob er überhaupt etwas sehen kann, und meldet sonst
|
||||
„ungültig" statt „sauber" — die Lehre aus zwei Suchen, die genau das
|
||||
verwechselt haben.
|
||||
|
||||
Reference in New Issue
Block a user