obsidian auto-sync 2026-04-24 15:30:00
This commit is contained in:
76
decisions/2026-04-24-finland-vps-malware-cleanup.md
Normal file
76
decisions/2026-04-24-finland-vps-malware-cleanup.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
date: 2026-04-24
|
||||
type: incident
|
||||
tags: [niikn, vpn, security, malware, finland]
|
||||
---
|
||||
|
||||
# Finland VPS 78.17.4.225 — инцидент XorDDoS + очистка
|
||||
|
||||
## Обстоятельства
|
||||
- 24 Apr провайдер adminvps.ru заблокировал сервер за **14 ТБ трафика за ~11 дней** (~1.27 ТБ/день)
|
||||
- Олег доплатил +8 ТБ, сервер снова в сети
|
||||
- AmneziaVPN НИИКН (клиенты через OpenWrt 10.8.1.16) всё это время работал, но на фоне шёл malware
|
||||
|
||||
## Диагноз
|
||||
Семейство **Linux/XorDDoS** (или близкий вариант). Маскировки:
|
||||
- `/usr/bin/zneirjeklr` — главный бинарь, cmdline `[rcu_gp]` (под kernel thread)
|
||||
- `/etc/init.d/zneirjeklr` — SysV init persistence (автогенерит systemd unit)
|
||||
- `/etc/cron.hourly/gcc.sh` — backup persistence, cp из `/lib/libudev.so` в `/lib/libudev.so.6` и запуск
|
||||
- `/usr/local/bin/lvm2-monitor` — под LVM monitor
|
||||
- `/lib/libudev.so` + `/usr/lib/libudev.so` — под libudev
|
||||
- `/tmp/*` + `/var/tmp/*` — дропперы с числовыми именами (3.2 МБ каждый)
|
||||
- `/var/tmp/QvqDAQNp` — UPX-packed дроппер (14 МБ)
|
||||
- cmdline `hald-runner` / `mingetty tty1` — фейковые имена процессов
|
||||
|
||||
## Хронология (по mtime)
|
||||
| Дата | Событие |
|
||||
|------|---------|
|
||||
| 28 Mar 23:59 | Первый успешный `Accepted password` с 172.18.0.3 (panel-web legitimate или уже compromised) |
|
||||
| 7 Apr 19:44 | Дроппер `/var/tmp/QvqDAQNp` создан |
|
||||
| 13 Apr 5:54-5:59 | Массовое создание 7 дропперов в `/var/tmp/` |
|
||||
| 17 Apr 17:33 | Ещё волна (EXT4 remount в dmesg) |
|
||||
| 20 Apr 02:13 | `zneirjeklr.service` активирован (systemd-sysv-generator) |
|
||||
| 23 Apr 14:49 | Провайдер остановил сервер (квота) |
|
||||
| 24 Apr 11:40 | Олег оплатил, сервер поднялся — malware сразу запустился |
|
||||
| 24 Apr 12:00-12:30 | Очистка |
|
||||
|
||||
## C2 инфраструктура
|
||||
- 141.98.10.115:1531
|
||||
- 170.168.103.27:29205
|
||||
- 64.89.161.144:40778
|
||||
|
||||
## Точка входа
|
||||
**RCE в PHP-панели AmneziaVPN (`amnezia-panel-web`)** — НЕ SSH brute-force.
|
||||
Доказательство: единственные успешные `Accepted password` в auth.log — с 176.62.183.186 (Олег) и 172.18.0.3 (панель, легитимный `collect_metrics.php`). **Ни одного Accepted с внешнего malware-IP.**
|
||||
|
||||
Брут извне был (91.142.77.101: 67k, 91.142.78.60: 66k, 91.142.78.8: 36k попыток) — НЕ пробил.
|
||||
|
||||
## Что сделано
|
||||
1. **Блок C2** — `iptables -I OUTPUT -d <C2> -j DROP` × 3
|
||||
2. **Kill + empty + chattr +i** на все 10 malware-файлов (пересоздаются но с нулевым содержимым и immutable — записаться не могут)
|
||||
3. **SSH усилен:**
|
||||
- Убран `PubkeyAuthentication no` из `/etc/ssh/sshd_config.d/99-cloud-init.conf` (cloud-init ставил по умолчанию — вот почему раньше входили только паролем)
|
||||
- `PasswordAuthentication no` везде
|
||||
- Новый root пароль `Ztey8pwWBiNNiMU09y76` (сохранён в `/root/.new_root_pw`), но по сути пароль уже не используется
|
||||
4. **Docker→host SSH заблокирован:** `iptables -I INPUT -s 172.17.0.0/16 -p tcp --dport 22 -j DROP` (× 4 сети). **Важно:** это ломает `amnezia-panel/collect_metrics.php` — панель больше не получает метрики хоста. ВПН-туннели работают.
|
||||
5. **fail2ban** установлен, active. Whitelist для docker сетей добавлен в `/etc/fail2ban/jail.d/docker-ignore.conf`.
|
||||
6. **iptables-persistent** — правила сохранены в `/etc/iptables/rules.v4`, выживут reboot.
|
||||
|
||||
## Forensic артефакты (на сервере)
|
||||
- `/root/forensic-20260424/zneirjeklr.bin` — копия бинарника
|
||||
- `/root/forensic-20260424/1380609993.bin` — копия второй стадии
|
||||
- `/root/clean-*.log` — лог очистки
|
||||
- `/root/.ssh/authorized_keys.bak-20260424` — бэкап authorized_keys до дедупликации
|
||||
|
||||
## Что ещё надо (не сделано)
|
||||
1. **Обновить/пересобрать amnezia-panel-web** — там PHP-RCE, может вернуться (текущий образ `amneziavpnphp_web` из `/opt/amneziavpnphp/docker-compose.yml`)
|
||||
2. **Восстановить метрики панели** — либо положить SSH-ключ из контейнера в authorized_keys хоста, либо отключить `collect_metrics.php`
|
||||
3. Мониторинг: `vnstat -d` раз в сутки, алерт при >50 ГБ/день
|
||||
4. Через ~24 часа проверить `iptables -nvL OUTPUT | grep DROP` — если счётчики всё ещё растут = остался watchdog
|
||||
5. Проверить другие контейнеры (amnezia-panel-db, vpn-nginx) на заражение
|
||||
|
||||
## Как заходить теперь
|
||||
```bash
|
||||
ssh -i ~/.ssh/id_ed25519 root@78.17.4.225 # только ключ
|
||||
# Пароль sshpass больше не работает (PasswordAuthentication=no)
|
||||
```
|
||||
Reference in New Issue
Block a user