| Stored Command Argument Injection Açıklığı (CWE-88) | |||||
| Bu makalede Stored Command Argument Injection (CWE-88), yani Depolu Komut Argümanı Enjeksiyonu açıklığı anlatılacaktır.
Açıklık Önem Derecesi: Düşük Açıklığın Etkisi: Komut çalıştırma, tampon taşırma, dizin gezinme, kod çalıştırma Açıklığın Açıklaması: Geliştiriciler uygulamalarında kabuk (shell) komutu çalıştırmak için (yani uygulamalarının dışında harici bir program çalıştırmak için) komutları ve parametre & argümanlarını string (dize) şeklinde tanımlarlar. Bu string’ler statik olabileceği gibi dinamik de olabilmektedir. Eğer string dahili veya harici argüman almıyorsa statik, alıyorsa dinamiktir. Geliştiriciler bu string’lere argüman olarak harici veya dahili girdi ekleyebilmektedirler. Böylesi bir uygulamada geliştirici kabuk komutu ile kendi tanımladığı argümanların çalışacağını varsayar. Ancak string’e konulan girdi kötü niyetli ellerden çıkmış bir değer ise geliştiricinin varsaydığı çalışacak argümanlar dışında daha fazla sayıda argüman çalışabilir. Girdiler kabuk komutuna (harici bir programa) argüman olarak ilave edildiğinde filtreleme yapılmıyorsa “Komut Argümanı Enjeksiyonu (CWE-88)” açıklığı meydana gelir. Eğer girdiler sistemin bir bileşeninden geliyorsa “Depolu Komut Argümanı Enjeksiyonu (CWE-88)” açıklığı meydana gelir. Saldırgan kontrollü argümanlar ile yapılabilecekler kabuk (shell) komutunun işlevselliğine, kapasitesine, uygulanışına ve komuta verilmiş izin seviyesine bağlıdır. Örneğin;
Depolu Komut Argümanı Enjeksiyonu açıklığını izah etmek adına Java ve PHP dillerinde güvensiz ve güvenli kod blokları örneklerine yer verilmiştir: Java - Güvensiz Kod Örneği:
// GÜVENSİZ ÖRNEK
// ENG: Execute External Program with Arguments from Database
//
// TUR: Veri Tabanından Çekilen Argümanlar ile Harici Bir
// Program Çalıştırma
private String executeSystemCommand_Unsafe(HttpServletRequest request) throws Exception {
String commandResult;
String param = request.getParameter("CommandID");
int commandID = Integer.parseInt(param);
ResultSet rs = readCommandFromDB(commandID);
String commandFromDB = rs.getString("Arg");
try {
Runtime runtime = Runtime.getRuntime();
Process subProc = runtime.exec(EXTERNAL_PROGRAM + " " + commandFromDB);
BufferedReader irProcOutput = new BufferedReader(new InputStreamReader(subProc.getInputStream()));
String line = null;
while ((line = irProcOutput.readLine()) != null)
commandResult += line;
irProcOutput.close();
} catch (Exception ex) {
handleExceptions(ex);
}
return commandResult;
}
Güvensiz kod bloğu örneğinde veri tabanından çekilen bir girdi filtrelenmeden çalıştırılacak kabuk (shell) komutunun sonuna eklenmektedir. Veri tabanındaki girdi daha önceden saldırganca oluşturulmuşsa veya saldırganca manipule edilmişse komut bu haliyle çalıştığında saldırganın girdileri mevcut argümanların sonuna enjekte olabilir. Girdi kontrolü eksikliği nedeniyle buradaki kullanım güvensizdir. Java - Güvenli Kod Örneği:
// GÜVENLİ ÖRNEK
// ENG: Execute External Program with Alphanumeric
// Arguments from DB, Sanitized with Regex
//
// TUR: Regexp ile Filtrelenmiş, Veri Tabanından
// Çekilmiş Alfanümerk Argumanlar ile Harici
// Program Çalıştırma
private String executeSystemCommand_Safe(HttpServletRequest request) throws Exception {
String commandResult;
String param = request.getParameter("CommandID");
int commandID = Integer.parseInt(param);
ResultSet rs = readCommandFromDB(commandID);
String commandFromDB = rs.getString("Arg");
commandFromDB = commandFromDB.replaceAll("[^A-Za-z0-9]", "");
String[] programArgs = new String[] ( EXTERNAL_EXECUTABLE, commandFromDB );
try {
Runtime runtime = Runtime.getRuntime();
Process subProc = runtime.exec(programArgs );
BufferedReader irProcOutput = new BufferedReader(new InputStreamReader(subProc.getInputStream()));
String line = null;
while ((line = irProcOutput.readLine()) != null)
commandResult += line;
irProcOutput.close();
} catch (Exception ex) {
handleExceptions(ex);
}
return commandResult;
}
Güvenli kod bloğu örneğinde ise veri tabanından çekilen bir girdi regular expression denetlemesine tabi tutulmaktadır. Bu denetlemeye göre A’dan Z’ye, a’dan z’ye ve 0’dan 9’a kadarki karakterlerden olmayan her karakter silinmektedir. Bu şekilde bir filtrelemenin var olması mevcut argümanların sonunda saldırgan kontrollü argüman enjeksiyonunun yapılamayacağını gösterir. Bu kullanım güvenli kabul edilir. PHP - Güvensiz Kod Bloğu:
// GÜVENSİZ KOD
<?php
$result = mysql_query($conn, $sql); // Taint Source (Input)
if (mysql_num_rows($result) > 0) {
$row = mysql_fetch_assoc($result);
$filename = $row["filename"];
$cmd = "find . -type f -name ";
system(escapeshellcmd($cmd . $filename)); // Taint Sink
}
?>
PHP - Güvenli Kod Bloğu:
// GÜVENLİ KOD
<?php
$result = mysql_query($conn, $sql); // Taint Source (Input)
if (mysql_num_rows($result) > 0) {
$row = mysql_fetch_assoc($result);
$filename = $row["filename"];
$cmd = "find . -type f -name ";
system(escapeshellcmd($cmd . $filename)); // Taint Sink
}
?>
Güvensiz kod bloğu örneğinde veri tabanından girdi çekiliyor ve bu girdi olduğu gibi shell komut çalıştırma fonksiyonundaki komuta argüman olarak ekleniyor. Burada filtreleme olmaması ve doğrudan yerleştirme olması sebebiyle Depolu Komut Argümanı Enjeksiyonu açıklığı mevcuttur. Güvenli kod bloğu örneğinde ise veri tabanından girdi çekilmektedir ve bu girdi regular expression ile denetime tabi tutulmaktadır. Bu denetlemeye göre A’dan Z’ye, a’dan z’ye ve 0’dan 9’a kadarki karakterlerden olmayan her karakter silinmektedir. Böylece depolu komut argümanı enjeksiyonunda kullanılabilecek karakterlerden girdi ayıklandığından depolu komut argümanı enjeksiyonu ihtimali ortadan kaldırılmış oluyor. Bu güvenli kabul edilen kullanımdır. Ekstra olarak depolu komut argümanı enjeksiyonuna java’dan şu örnek de verilebilir: Java - Güvensiz Kod Bloğu Örneği (2):
// GÜVENSİZ ÖRNEK
// ENG: Execute External Program with Arguments from Environment
//
// TUR: Shell Ortamından Çekilen Argümanlar ile Harici Bir
// Program Çalıştırma
private String executeSystemCommand_Unsafe(HttpServletRequest request) throws Exception {
String commandResult;
String param = os.getEnv("CommandID");
try {
Runtime runtime = Runtime.getRuntime();
Process subProc = runtime.exec(EXTERNAL_PROGRAM + " " + param);
BufferedReader irProcOutput = new BufferedReader(new InputStreamReader(subProc.getInputStream()));
String line = null;
while ((line = irProcOutput.readLine()) != null)
commandResult += line;
irProcOutput.close();
} catch (Exception ex) {
handleExceptions(ex);
}
return commandResult;
}
Bu güvensiz örnekte java kaynak kodları sistemin environment variable’ını (ortam değişkenini) çekmektedir ve bunları sistem shell (kabuk) komutuna doğrudan argüman olarak eklemektedir. Eğer uygulamada gelecekte environment variable injection zafiyetine sahip bir bileşen ortaya çıkarsa (veya zafiyet halihazırda zaten varsa) environment variable enjeksiyon yoluyla saldırganlar sistemdeki ortam değişkenlerinin değerlerini değiştirebilirler. Uygulama sistemin kabuğundan bu manipule edilmiş ortam değişkenini çekip komut sonrasına eklediğinde ise mevcut kabuk komutlarındaki argümanlara ilave argümanlar şeklinde eklenebilir. Yani komut argümanı enjeksiyonu saldırısı yaşanabilir. Java - Güvenli Kod Bloğu Örneği (2):
// GÜVENLİ ÖRNEK
// ENG: Execute External Program with Alphanumeric
// Arguments from Environment, Sanitized with Regex
//
// TUR: Regexp ile Filtrelenmiş, Environment’tan
// Çekilmiş Alfanümerk Argumanlar ile Harici
// Program Çalıştırma
private String executeSystemCommand_Unsafe(HttpServletRequest request) throws Exception {
String commandResult;
String param = os.getEnv("arguments");
param = param.replaceAll("[^A-Za-z0-9]", "");
String[] programArgs = new String[] ( EXTERNAL_EXECUTABLE, param );
try {
Runtime runtime = Runtime.getRuntime();
Process subProc = runtime.exec( programArgs );
BufferedReader irProcOutput = new BufferedReader(new InputStreamReader(subProc.getInputStream()));
String line = null;
while ((line = irProcOutput.readLine()) != null)
commandResult += line;
irProcOutput.close();
} catch (Exception ex) {
handleExceptions(ex);
}
return commandResult;
}
Bu güvenli örnekte ise java kaynak kodları sistemin environment variable’ını (ortam değişkenini) yine çekmektedir, fakat bu sefer regular expression ile denetime tabi tuttuktan sonra sistem shell (kabuk) komutuna argüman olarak eklemektedir. Eğer uygulamada gelecekte environment variable injection zafiyetine sahip bir bileşen ortaya çıkarsa (veya zafiyet halihazırda zaten varsa) environment variable enjeksiyon yoluyla saldırganlar sistemdeki ortam değişkenleri değerlerini değiştirebilirler ama komut argümanı enjeksiyonu karakterlerine sahip karakterler eklemiş olsalar da uygulamanın mevcut kabuk komutlarındaki argümanlara ilave argümanlar ekleyemezler. Çünkü komuta argümanlar eklenirken filtrelenmektedir. Böylece ortam değişkeni enjeksiyonu çıksa bile komut argümanı enjeksiyonu zafiyeti önlenmiş olur. Açıklığın Önlemi: Tavsiyeler şu şekildedir:
|
|||||
Bu yazı 25.10.2025 tarihinde, saat 20:47:08'de yazılmıştır.
25.10.2025 tarihi ve 18:03:14 saatinde ise güncellenmiştir. |
|||||
|
|||||
| Yorumlar |
|||||
| Henüz yorum girilmemiştir. | |||||
| Yorum Ekle | |||||
Bu yazı 25.10.2025 tarihinde, saat 20:47:08'de yazılmıştır.
25.10.2025 tarihi ve 18:03:14 saatinde ise güncellenmiştir.