Ada banyak cara bagi pengguna jahat untuk memanfaatkan situs web yang rentan. Salah satunya disebut injeksi perintah
Hari ini, Anda akan mempelajari apa itu injeksi perintah, bagaimana penyerang dapat menggunakannya untuk membahayakan aplikasi web Anda, dan bagaimana Anda dapat mencegah hal itu terjadi di aplikasi PHP Anda.
Mari kita langsung ke sana
Serangan injeksi perintah didasarkan pada eksekusi kode sewenang-wenang (dan kemungkinan besar berbahaya) pada sistem target
Apa itu Injeksi Perintah?
Serangan injeksi perintah didasarkan pada eksekusi kode sewenang-wenang (dan kemungkinan besar berbahaya) pada sistem target
Dengan kata lain, ini adalah cara menggunakan aplikasi yang dirancang untuk melakukan satu hal untuk tujuan yang sama sekali berbeda
Mari kita ambil contoh formulir kontak sederhana. Tujuan dari aplikasi semacam itu sederhana. untuk mengizinkan orang meninggalkan informasi kontak mereka agar seseorang di dalam perusahaan dapat dihubungi. Penyerang mungkin ingin menggunakan aplikasi untuk mencuri informasi tentang pelamar lain, misalnya. Dan mereka mungkin mencapai tujuan itu dengan menyuntikkan kode berbahaya
Bagaimana Injeksi Perintah Dilakukan?
Agar serangan injeksi perintah terjadi, tiga hal harus terjadi sekaligus
Aplikasi menggunakan beberapa fungsi untuk melakukan panggilan ke shell sistem
Aplikasi mengirimkan data yang tidak aman/tidak divalidasi ke panggilan tersebut
Penyerang menyadari fakta ini dan bertindak berdasarkan pengetahuan ini
Contoh Perintah Injeksi di PHP
Ketiga fungsi PHP ini, jika tidak digunakan dengan aman, dapat menyebabkan adanya kerentanan ini
eksekusi
passthru
sistem
Masalahnya terletak pada kenyataan bahwa mereka semua mengambil string arbitrer sebagai parameter pertama mereka dan meneruskannya ke sistem operasi yang mendasarinya.
Ini tidak menyiratkan risiko apa pun jika string ditulis oleh programmer (alias Anda), seperti ini
PHP
<?php $command = "ls -l"; $output = exec($command);
Namun, karena variabel $command adalah string, tidak ada yang menghalangi Anda untuk menulis sesuatu seperti di bawah ini
PHP
<?php $command = "ls ".$_GET['modifiers']; $output = exec($command);_
Yang tentu saja akan menghasilkan hasil yang sama persis (karena nilai dari $command adalah “ls -l”)
Sejauh ini, sangat bagus, bukan?
Sekarang, mari kita lihat contoh berikut
PHP
<?php $command = "ls ".$_GET['modifiers']; $output = exec($command);_
Di sini perintah dibuat dari dua sumber. string tetap ("ls") dan parameter URL (<?php $command = "ls ".$_GET['modifiers']; $output = exec($command);0)
Ini berarti bahwa perintah sebenarnya yang akan dieksekusi bergantung pada input pengguna
Katakanlah seseorang mengajukan permintaan seperti <?php $command = "ls ".$_GET['modifiers']; $output = exec($command);1
Saat kode dieksekusi, nilai <?php $command = "ls ".$_GET['modifiers']; $output = exec($command);2 akan menjadi “-l”, yang akan menghasilkan perintah “ls -l”
Tidak ada salahnya dilakukan, kan?
Tetapi bagaimana jika pengguna tidak begitu baik?
Bagaimana jika mereka mengeluarkan permintaan seperti <?php $command = "ls ".$_GET['modifiers']; $output = exec($command);3?
Perintah yang dihasilkan adalah “ls -l;
Jika Anda mengetahui sedikit tentang konsol Linux, Anda harus mengenali perintah “rm * -Rf” … dan menjadi sangat takut. (Jika Anda tidak terbiasa dengan konsol Linux, perintah itu berarti "hapus setiap file di direktori ini dan subdirektorinya. ”)
Sangat tidak mungkin seseorang akan mengeluarkan permintaan seperti itu secara tidak sengaja
Tetapi jika seseorang ingin merusak situs Anda dan mereka tahu sedikit PHP (atau bahasa pemrograman lainnya), mudah untuk membuat string seperti itu.
Jika Anda bertanya-tanya dari mana “-l%3B+rm+%2A+-Rf” berasal, ini adalah hasil dari berikut ini
<?php $command = "ls ".$_GET['modifiers']; $output = exec($command);_4
Bagaimana Cara Penyerang Membuat Permintaan Injeksi Perintah?
Mungkin cara termudah adalah dengan menggunakan formulir Anda sendiri
Pada contoh di atas, bayangkan ada halaman sebelumnya yang terlihat seperti ini
HTML
<html> <form action="index.php"> <input name="modifiers" type="text"> <input value="Get file names" type="submit"> </form> </html>_
Penyerang hanya perlu mengisi kolom <?php $command = "ls ".$_GET['modifiers']; $output = exec($command);5 dengan “-l%3B+rm+%2A+-Rf” dan tekan “Dapatkan nama file. ”
Tidak terlalu rumit, bukan?
Jika ingin beralih dari baris perintah, mereka dapat menggunakan alat sederhana seperti cURL, seperti ini
<?php $command = "ls ".$_GET['modifiers']; $output = exec($command);_6
Keuntungan bagi penyerang menggunakan mekanisme ini adalah, dengan menggunakan alat semacam ini, sangat mudah untuk mengotomatiskan serangan.
Dari Mana Data Tidak Aman Berasal?
Data yang tidak aman dapat berasal dari beberapa sumber berbeda. Sejauh ini, kita telah membahas parameter URL, tetapi penyerang dapat menggunakan cara apa pun yang tersedia untuk mentransfer informasi ke aplikasi Anda, seperti berikut ini
<?php $command = "ls ".$_GET['modifiers']; $output = exec($command);_7
KUE
Tajuk HTTP
File yang diunggah
Contoh <?php $command = "ls ".$_GET['modifiers']; $output = exec($command);7 akan sangat mirip dengan contoh <?php $command = "ls ".$_GET['modifiers']; $output = exec($command);9, jadi saya akan melewatkannya untuk menunjukkan kepada Anda bagaimana serangan ini dapat dilakukan menggunakan header HTTP
Semuanya dimulai dengan kode Anda menggunakan informasi tersebut untuk menyusun perintah yang akan dikeluarkan ke sistem operasi
PHP
<?php $command = "mv ".$_SERVER['HTTP_X_FILE']." uploads/"; $output = system($command);
Sekarang, yang diperlukan agar serangan berhasil adalah penambahan permintaan yang dibuat dengan hati-hati seperti ini
<?php $command = "ls ".$_GET['modifiers']; $output = exec($command);_0
Situasi yang sangat mirip dapat ditemukan jika Anda memiliki skrip yang terlihat seperti ini
PHP
# upload.php <?php $uploaded_file = $_FILES['file_name']['tmp_name']; $command = "cat ".file_get_contents($uploaded_file); $output = system($command); <!-- form.html --> <!DOCTYPE html> <html> <body> <form action="upload.php" method="post" enctype="multipart/form-data"> Select image to upload: <input type="file" name="fileToUpload" id="fileToUpload"> <input type="submit" value="Upload file" name="submit"> </form> </body> </html>
Dan seseorang mengunggah file yang berisi sesuatu seperti ini
<?php $command = "ls ".$_GET['modifiers']; $output = exec($command);_1
Anda mungkin bisa melihat polanya sekarang. membabi buta mempercayai input pengguna adalah ide yang buruk
Jadi sekarang setelah Anda tahu bagaimana seorang penyerang dapat menyulitkan Anda, mari kita lihat apa yang dapat Anda lakukan untuk mencegahnya terjadi
Cara Memperbaiki Kerentanan Injeksi Perintah
Seperti yang Anda lihat di bagian sebelumnya dari artikel ini, masalahnya berasal dari penggabungan eksekusi shell langsung dan penggunaan data yang tidak aman
Jadi, untuk mencegah hal ini terjadi, ada dua strategi yang mungkin Anda gunakan
Menahan diri dari menggunakan fungsi eksekusi shell langsung
Hindari menggunakan data yang tidak aman dalam kombinasi dengan fungsi eksekusi shell langsung
Jangan Gunakan Fungsi Eksekusi Direct Shell
Jika memungkinkan, Anda sebaiknya memilih untuk menggunakan fungsi bawaan daripada perintah OS
Misalnya, jika Anda perlu menghapus file dari disk, Anda dapat menggunakan ini
<?php $command = "ls ".$_GET['modifiers']; $output = exec($command);_2
Atau gunakan ini
<?php $command = "ls ".$_GET['modifiers']; $output = exec($command);_3
Dengan menggunakan fungsi unlink, Anda secara efektif menghilangkan kemungkinan seseorang menyuntikkan perintah jahat
PHP memiliki cukup banyak fungsi yang dapat Anda gunakan untuk menyamarkan panggilan sistem operasi, seperti berikut ini
rmdir untuk menghapus direktori
chmod untuk memanipulasi izin file
glob untuk mengulangi file di jalur yang diberikan
Dan beberapa lagi yang dapat Anda temukan di sini (sebut saja yang berhubungan dengan sistem file)
Efek samping lain yang menarik dari penggunaan fungsi ini adalah peningkatan portabilitas kode Anda
Jika Anda menggunakan fungsi eksekusi shell, perintah diinterpretasikan oleh sistem operasi itu sendiri, bukan oleh juru bahasa PHP
Ini berarti jika Anda menulis kode di lingkungan Windows tetapi server produksinya adalah Linux atau sejenisnya, semuanya tidak akan berfungsi
Tentu saja, akan ada kasus di mana Anda perlu menjalankan perintah khusus yang bukan bagian dari inti PHP, seperti program biner tertentu atau skrip yang Anda buat.
Mari kita lihat bagaimana menghadapi situasi seperti itu
Jangan Gunakan Data Tidak Aman dalam Kombinasi Dengan Fungsi Eksekusi Direct Shell
Jika Anda benar-benar perlu menggunakan panggilan sistem, Anda harus menggunakan validasi yang tepat pada data Anda
Misalnya, jika Anda akan mengeluarkan perintah seperti ini
PHP
<?php $targetIP = $_GET[ 'ip' ]; $cmd = exec( "ping $target" );
Sebaiknya pastikan <?php $command = "ls ".$_GET['modifiers']; $output = exec($command);4 sebenarnya adalah alamat IP
Untuk melakukan validasi tersebut, PHP menyediakan fungsi bawaan yang disebut filter_input, yang dapat Anda gunakan seperti ini
PHP
<?php if ($targetIP = filter_input(INPUT_GET,'ip',FILTER_VALIDATE_IP)) { $cmd = exec( "ping $target" ); } else { die("Please provide a valid IP address"); }
Ada fungsi serupa untuk memvalidasi sumber data lain (dan juga, ada beberapa jenis filter berbeda yang dapat Anda gunakan untuk mengakomodasi kebutuhan khusus Anda)
Anda dapat memindai kode Anda secara manual untuk mencari kode berbahaya, atau Anda dapat mempertimbangkan untuk menggunakan alat otomatis yang dapat disertakan langsung ke dalam alur kerja tim Anda
Lindungi Kode Anda dari Suntikan
Hari ini Anda belajar apa itu serangan injeksi perintah, fitur apa yang dimiliki aplikasi PHP agar rentan terhadap serangan semacam itu, dan apa yang harus dilakukan untuk menonaktifkan ancaman semacam itu di aplikasi Anda
Sekarang Anda memiliki beberapa pekerjaan rumah yang harus dilakukan
Anda dapat memindai kode Anda secara manual untuk mencari kode berbahaya, atau Anda dapat mempertimbangkan untuk menggunakan alat otomatis yang dapat disertakan langsung ke dalam alur kerja tim Anda. Salah satu alat tersebut adalah StackHawk, yang dapat memantau setiap permintaan penarikan dan memberi Anda wawasan tentang cara menyelesaikannya sebelum mencapai produksi
Anda dapat membaca detail tentang cara menerapkannya di sini
Posting ini ditulis oleh Mauro Chojrin. Mauro membantu pengembang PHP mengasah kemampuan mereka melalui pelatihan, buku, lokakarya, dan alat lainnya. Dia telah berkecimpung di industri TI sejak tahun 1997 dan telah memegang berbagai peran seperti pengembang, arsitek, dan pemimpin tim teknis. Mauro juga suka menulis dan membuat vlog