← Kembali ke blog

CARBONATO: Cacing AI Mencuri Server Docker. Daftar Periksa untuk Pengguna VPS yang Mengelola Parser

Botnet CARBONATO mengambil alih server melalui Docker API tanpa kata sandi, menginstal agen AI GH0ST dan pertama-tama mencuri kunci untuk model bahasa. Kami membahas rantai serangan, tanda-tanda infeksi, dan daftar periksa 15 menit untuk mereka yang menyimpan parser, kunci LLM, dan login proxy di VPS mereka.

📅27 September 2026
CARBONATO: Cacing AI Mencuri Server Docker. Daftar Periksa untuk Pengguna VPS yang Mengelola Parser

Pada 22 September 2026, peneliti ThreatDown mendeskripsikan botnet CARBONATO. Ia mengakses server melalui Docker API yang terbuka tanpa kata sandi, mengangkat agen AI di host, dan pertama-tama mencari kunci untuk model bahasa. Kunci SSH dan token akses datang kemudian. Jika Anda menjalankan parser di VPS dalam kontainer, dan di .env terdapat kunci OpenRouter atau OpenAI serta login proxy, ini adalah profil risiko Anda. Berikut adalah analisis tentang bagaimana serangan ini dilakukan, dan daftar periksa selama 15 menit yang menutup akses ini.

Apa yang ditemukan: 4,3 GB gambar dan agen bernama GH0ST

Semuanya dimulai dari registri Docker yang tidak tertutup milik para operator. Menurut ThreatDown, terdapat 59 repositori, 234 tag gambar, dan 4,3 GB data. Arsip ini mencakup periode dari Oktober 2024 hingga Agustus 2026, artinya botnet ini beroperasi hampir dua tahun sebelum dideskripsikan. Di repositori ditemukan penambang XMRig dan gambar dengan nama seperti fsociety/agent.

Rantai infeksi menurut laporan terlihat seperti ini:

  1. Pemindai mencari host di mana Docker API terbuka pada TCP 2375 tanpa autentikasi.
  2. Melalui API ini, cacing meluncurkan kontainer dengan hak istimewa dengan sistem file host yang dipasang. Mulai saat ini, ia secara efektif menjadi root di mesin tersebut.
  3. Terbangun terowongan SSH balik ke infrastruktur operator, dan server SSH dipasang dengan kunci mereka.
  4. Pemasangan dilakukan melalui cron, timer systemd, rc.local, dan OpenRC, dengan file yang ditandai sebagai tidak dapat diubah. Proses penjaga mengunduh ulang gambar jika ada yang dihapus.
  5. Kontainer menyamar sebagai systemd-resolved, dan prosesnya menyamar sebagai aliran inti [kworker/u2:0].
  6. Setiap lima menit, skrip memindai subnet tetangga /24 dan jembatan Docker untuk mencari port terbuka berikutnya 2375.

Penyebaran sepenuhnya otomatis dan tidak bergantung pada AI. AI di sini bertanggung jawab atas apa yang terjadi di dalam server yang sudah terinfeksi.

Untuk apa botnet membutuhkan agen AI dan mengapa ia memerlukan kunci LLM

Di host, kerangka kerja terbuka Hermes Agent dengan persona GH0ST dipasang (instruksinya terdapat dalam file SOUL.md). Operator menulis tugas di Telegram, agen meneruskannya bersama dengan instruksi ke gerbang LLM operasi. Model menganalisis tugas, menulis perintah untuk terminal, membaca output, dan memutuskan apa yang harus dilakukan selanjutnya. Hasilnya dikirim kembali ke Telegram.

Dalam instruksi agen, prioritas dijelaskan secara langsung. ThreatDown mengutip: “Kunci API AI adalah prioritas mutlak. Ekstraksi pertama”. Dalam daftar terdapat 14 penyedia model, termasuk OpenAI, Anthropic, Google, Groq, Mistral, dan OpenRouter. Akun SSH, token akses, dan data basis mengikuti sebagai poin berikutnya.

Logika sederhana: kunci LLM yang dicuri segera berubah menjadi komputasi gratis atau barang untuk dijual kembali, dan yang membayar adalah pemilik kunci tersebut. Berbeda dengan penambangan, pencurian semacam ini tidak terlihat dari beban pada CPU. Anda hanya akan menyadarinya dari tagihan dari penyedia model.

Mengapa ini penting bagi mereka yang melakukan parsing

Stack parsing yang khas pada tahun 2026 terlihat seperti ini: VPS, beberapa kontainer (crawler, antrean, basis data, browser headless), LLM untuk menganalisis halaman, dan kumpulan proxy. Semua rahasia terletak dalam satu .env atau dalam variabel lingkungan kontainer. Bagi agen yang “membaca semuanya” dengan akses root, ini adalah sasaran empuk dalam satu file:

  • kunci LLM: untuk inilah CARBONATO diciptakan;
  • login dan kata sandi proxy: laporan tidak menyoroti mereka secara terpisah, tetapi agen dengan akses root mengumpulkan akun dan token apa pun yang dilihatnya, dan kredensial proxy biasanya terletak di dekatnya;
  • kunci cloud dan akses ke basis data dengan hasil parsing;
  • server itu sendiri: XMRig dalam arsip yang sama berarti bahwa CPU crawler Anda akan digunakan untuk penambangan, dan tugas akan mulai gagal karena timeout.

Masalah terpisah adalah reputasi. Server yang dipindai oleh cacing di subnet orang lain dengan cepat masuk dalam daftar penyalahgunaan, dan penyedia hosting dapat memblokirnya berdasarkan keluhan. Untuk parsing, ini adalah pukulan ganda: IP server terdaftar, dan kredensial proxy yang dicuri sudah menghabiskan lalu lintas Anda dengan permintaan orang lain.

Bagaimana port 2375 bisa terbuka, meskipun Anda tidak membukanya

Secara default, Docker mendengarkan soket UNIX lokal, bukan jaringan. Port 2375 muncul ketika seseorang secara sadar menambahkan -H tcp://0.0.0.0:2375 dalam konfigurasi daemon. Biasanya ini dilakukan untuk menghubungkan IDE jarak jauh, CI, atau panel kontrol kontainer, dan kemudian dilupakan. Dokumentasi Docker secara langsung memperingatkan bahwa akses ke daemon setara dengan akses root ke mesin, dan menyarankan untuk menjaga kunci darinya seperti kata sandi root. Versi terenkripsi dengan TLS berfungsi pada port 2376, sedangkan 2375 berarti teks terbuka tanpa verifikasi klien.

Perangkap kedua menyerang mereka yang yakin bahwa “saya sudah menggunakan ufw”. Dalam dokumentasi Docker disebutkan bahwa lalu lintas port yang diterbitkan oleh kontainer diteruskan dalam tabel nat sebelum rantai INPUT dan OUTPUT, yang menjadi dasar ufw. Dalam praktiknya, aturan ufw untuk port semacam itu tidak berfungsi. Jika Anda menjalankan Redis, panel antrean, atau pengelola proxy dengan -p 6379:6379, port tersebut terbuka ke internet, terlepas dari apa yang ditampilkan oleh ufw status.

Daftar periksa selama 15 menit untuk server dengan parser

1. Periksa bahwa Docker API tidak mendengarkan jaringan

  1. Periksa port yang mendengarkan: ss -tlnp | grep -E '2375|2376|dockerd'. Jika output menunjukkan 0.0.0.0:2375 atau :::2375, tutup segera.
  2. Periksa dari mana bendera tersebut berasal: /etc/docker/daemon.json (kunci "hosts") dan unit systemctl cat docker (baris ExecStart dengan -H tcp://).
  3. Hapus pendengar TCP dan restart daemon. Untuk pengelolaan jarak jauh, gunakan konteks SSH: docker context create remote --docker host=ssh://user@server. Port ke luar tidak diperlukan sama sekali.
  4. Jika TCP tetap diperlukan (CI, pengatur), maka hanya 2376 dengan autentikasi TLS mutual dan daftar putih IP sumber.

2. Periksa apa yang terbuka dari kontainer

  • Jalankan docker ps --format '{{.Names}} {{.Ports}}'. Segala sesuatu yang dimulai dengan 0.0.0.0: dapat diakses dari internet tanpa melalui ufw.
  • Layanan penting (Redis, Postgres, Mongo, panel antrean, Selenium Grid, API pengelola proxy) hanya diterbitkan pada alamat lokal: -p 127.0.0.1:6379:6379. Akses eksternal dilakukan melalui terowongan SSH.
  • Jika tidak bisa tanpa port eksternal, filter dalam rantai DOCKER-USER: rantai ini tidak ditimpa oleh Docker, dan itulah yang diterapkan pada lalu lintas kontainer.
  • Jangan biarkan proxy terbuka di server tanpa otorisasi (Squid di 3128, SOCKS di 1080 “untuk orang dalam”). Pemindai secara teratur menemukan port semacam itu, dan lalu lintas asing mengalir melalui IP Anda dengan keluhan orang lain.

3. Atur rahasia dengan baik

  • Pisahkan kunci: satu kunci LLM untuk setiap server atau proyek, dengan batas pengeluaran di penyedia model. Kunci yang dicuri dengan batas $20 — adalah masalah, tanpa batas — adalah lubang dalam anggaran.
  • Kunci proxy juga dipisahkan berdasarkan tugas: login terpisah (sub-akun) untuk setiap parser. Dengan begitu, kebocoran terlihat dari pengeluaran login tertentu, dan hanya login itu yang dapat dicabut tanpa menghentikan pekerjaan lainnya.
  • Jangan meneruskan seluruh .env ke dalam kontainer melalui env_file, jika layanan hanya membutuhkan dua kunci dari dua puluh.
  • Di mana memungkinkan, ikat akses ke IP server: daftar putih di penyedia proxy atau pembatasan kunci API berdasarkan alamat.

Lebih lanjut tentang di mana dan bagaimana menyimpan login proxy dalam skrip dan kontainer, kami telah menulis dalam analisis penyimpanan aman kredensial proxy.

4. Hapus hak istimewa yang tidak perlu

  • Jangan jalankan kontainer dengan --privileged dan jangan pasang / atau /var/run/docker.sock ke dalam tanpa kebutuhan mendesak. Soket di dalam kontainer adalah sama dengan root di host.
  • Untuk browser headless biasanya cukup dengan --shm-size dan profil seccomp. Mode dengan hak istimewa “agar Chrome bisa berjalan” adalah kompromi yang buruk.

Bagaimana mengetahui bahwa Anda sudah terinfeksi

ThreatDown dan analisis laporan mereka menunjukkan tanda-tanda kompromi sebagai berikut:

  • file SOUL.md dengan kata GH0ST (misalnya, /root/.hermes/SOUL.md);
  • variabel lingkungan atau baris dalam .env: CARBONATO_API_KEY;
  • file /usr/local/bin/.docker-network-monitor dan /usr/sbin/systemd-logind yang mencurigakan;
  • kontainer dengan nama systemd-resolved (systemd-resolved yang asli adalah layanan host, bukan kontainer);
  • lalu lintas keluar yang tidak terduga ke Telegram API dan terowongan SSH balik menuju AS262145;
  • koneksi ke alamat 45.79.183.61, 213.136.79.115, 190.211.124.187;
  • file yang tidak dapat diubah di cron dan systemd: lsattr /etc/cron.d/* /etc/systemd/system/* akan menunjukkan bendera i.

Jika setidaknya satu tanda cocok, membersihkan server secara manual tidak ada gunanya: pemasangan bersifat berlapis, dan penjaga akan mengembalikan implan. Urutan yang benar adalah sebagai berikut:

  1. Dari mesin lain, cabut semua kunci yang ada di server: LLM, cloud, basis data, proxy.
  2. Periksa pengeluaran untuk setiap kunci selama beberapa minggu terakhir di penyedia. Statistik berdasarkan login proxy akan segera menunjukkan lalu lintas asing.
  3. Bangun server baru dari gambar bersih, terbitkan kunci baru dan hanya kemudian pindahkan data, tanpa biner dan file cron dari mesin lama.

Di mana proxy di sini dan apa yang tidak mereka selesaikan

Proxy tidak melindungi server dari CARBONATO. Cacing masuk bukan melalui permintaan keluar Anda, tetapi melalui port masuk. Namun, skema kerja yang benar dengan proxy mengurangi kerugian. Login terpisah untuk tugas, batas lalu lintas, dan pengikatan berdasarkan IP mengubah kebocoran dari “seluruh saldo hilang” menjadi “mencabut satu login”.

Ada juga sisi sebaliknya, yang sering ditunjukkan oleh botnet: perangkat yang terinfeksi orang lain sendiri menjadi “proxy residensial” dari jaringan yang meragukan. Oleh karena itu, untuk parsing, sebaiknya ambil lalu lintas dari penyedia dengan asal pool yang jelas. Untuk sebagian besar tugas pengumpulan data, proxy residensial dengan pembayaran per gigabyte cocok, di mana pengeluaran untuk setiap proxy terlihat di dasbor. Untuk tugas layanan tanpa perlindungan anti-bot yang ketat, cukup gunakan proxy pusat data yang lebih murah.

Kesimpulan

CARBONATO tidak menggunakan kerentanan hari nol atau eksploitasi yang rumit. Ia masuk melalui pintu yang dibuka oleh pemilik server sendiri: TCP 2375 tanpa kata sandi. Yang baru di dalamnya adalah: di dalam beroperasi agen AI, yang ditugaskan untuk pertama-tama mengambil kunci untuk model. Bagi mereka yang mengumpulkan data di VPS mereka, kesimpulannya praktis. Tutup Docker API, terbitkan port layanan pada 127.0.0.1, pisahkan kunci LLM dan proxy berdasarkan tugas dengan batas pengeluaran. Ini adalah 15 menit kerja, dan setelah itu server Anda menjadi target yang tidak menarik bagi botnet semacam itu.