Path Traversal – Limitarea insuficientă a căii fişierelor/directoriilor în sistemul de fişiere de un directoriu cu acces interzis.
Path Traversal se manifestă ca o vulnerabilitate a unei aplicaţii care utilizează datele de intrare ca parte componentă a căii destinate pentru identificarea unui fişier sau directoriu, şi accesarea directoriului părinte al căruia este interzisă, insă metodele de validare a datelor de intrare nu sunt corecte sau lipsesc. Astfel prin intermediul acestei vulnerabilităţi se poate obţine acces la conţinutul fişierelor şi directoriilor restricţionate iniţial,care se afla în afara directoriului predefinit.
Multe din operaţiile cu fişiere sunt destinate a fi executate în contextul restrîns al unui director. Prin utilizarea elementelor speciale, cum ar fi “..” şi “/”, atacatorii pot ieşi în afara restricţiilor, obţinînd acces la fişierele sau directoriile care sunt situate în zone restricţionate pentru acces. Unul dintre elementele speciale cele mai des întîlnite este secvenţa “../”, care, în majoritatea sistemelor de operare moderne este interpretată ca directoriul părinte faţă de locaţia actuală. Această tehnică utilizează traversarea relativă a căii (din en. Relative path traversal), adică calea va fi relativă faţă de cea actuală. Utilizarea unor elemente speciale, cum ar fi “/” sau “/etc/passwd”, de asemenea pot fi utile în accesarea fişierelor interzise. Această tehnică utilizează traversarea absolută (din en. Absolute path traversal), adică calea indicată este cea absolută în sistemul de fişiere, şi nu e relativă sau dependentă de calea utilizată în aplicaţie.
În multe limbaje de programare, injectarea unui octet nul (0 sau NUL) poate permite unui atacator să scurteze numele generat al fişierului şi de a extinde domeniul de aplicare al atacului. De exemplu, aplicaţia adaugă “.txt” la sfîrşitul oricărei căi indicate, limitând astfel atacatorul doar la fişierele text, însă injectarea unui octet nul poate înlătura eficient această restricţie.
Impact
Integritate
Executarea codului sau comenzilor neautorizate
Atacatorul poate crea sau rescrie fişiere critice care sunt folosite pentru a executa cod, cum ar fi programe sau biblioteci.
Citirea / scrierea fişierelor şi directoriilor
Atacatorul poate rescrie sau crea fişierele critice, cum ar fi programe, biblioteci, sau date importante. Dacă fişierul ţintă este folosit de către un mecanism de securitate, atunci atacatorul poate evita acest mecanism. De exemplu, adăugarea unui nou cont la sfârşitul unui fişier care stochează parolele poate permite unui atacator să ocolească autentificarea.
Confidenţialitate
Citirea/scrierea fişierelor şi directoriilor
Atacatorul poate citi conţinutul fişierelor critice şi divulga date sensibile. Dacă fişierul ţintă este folosit de către un mecanism de securitate, atunci atacatorul poate evita acest mecanism. De exemplu, citind o parolă dintr-un fişier, atacatorul ar putea utilza parola pentru intrarea într-un cont dintr-un sistem de pe acelaşi server.
Disponibilitate
Atacatorul poate rescrie sau crea fişiere critice, cum ar fi programe, biblioteci, sau date importante. Acest lucru poate împiedica aplicaţia să ruleze corect, precum şi alte sisteme dependente, iar în cazul unor mecanisme de protecţie, cum ar fi autentificarea, e posibil de a bloca toţi utilizatorii aplicaţiei.
Probabilitate
Probabilitatea exploatării acestei vulnerabilităţi este foarte mare, fiindcă exploatarea:
- nu necesită cunoştinţe şi aptitudini aprofundate în domeniu
- nu necesită utilitare complexe
- e realizabilă de către orice utilizator al sistemului (în unele cazuri chiar şi neautentificat)
Exemple
Exemplul 1
Acest cod poate fi utilizat într-o reţea socială, forum, sau orice aplicaţie în care informaţia de profil a utilizatorilor este stocată în fişiere separate, într-un singur director.
Cod Vulnerabil în PERL
my $dataPath = "/users/securitate.md/profiles"; my $utilizator = param("user"); my $profilePath = $dataPath . "/" . $utilizator; open(my $fh, "<$profilePath") || ExitError("Eroare de citire : $profilePath"); print " <ul>\n"; while (<$fh>) { print " <li>$_</li> \n"; } print "</ul> \n";
Programatorul a intenţionat sa acceseze fişiere de tip /users/securitate.md/profiles/mihai sau /users/securitate.md/profiles/nicolae, insă nu a implementat verificarea datelor de intrare. Un atacator ar putea indica:
Exemplu de atac
../../../etc/passwd
In urma prelucrării datelor sistemul va avea pentru executare calea:
Rezultatul atacului
/etc/passwd
Drept, rezultat, atacatorul va putea citi conţinutul fişierului /etc/passwd.
Exemplul 2
În acest exemplu calea către un fişier dicţionar e citită din o proprietate a sistemului şi utilizată pentru iniţierea unui obiect File.
Exemplu de cod vulnerabil Java
String filename = System.getProperty("com.domain.application.dictionaryFile"); File dictionaryFile = new File(filename);
Nu are loc verificare căii către fişier înainte de crearea obiectului File. Acest fapt permite oricărui utilizator care are acces de modificare a parametrului sistemului să determine ce fişier să fie utilizat. Corect însă ar fi, în acest caz, ca după validarea datelor de intrare, calea să fie obţinută în mod relativ faţă de o aplicaţie sau directoriului home al utilizatorului.
Exemplul 3
Acest cod încearcă să valideze cu expresii regulare datele de intrare, eliminînd “../“. Apoi concatenează rezultatul la /home/user şi încearcă să citească fişierul corespunzător căii.
Exemplu de cod vulnerabil Perl
my $Username = GetUntrustedInput(); $Username =~ s/\.\.\///; my $filename = "/home/user/" . $Username; ReadAndSendFile($filename);
Se observă că expresia regulară nu are parametrul global /g, de aceea ea va elimina doar prima
“../”
Atac
../../../etc/passwd
Aplicaţia va elimina prima intrare “../” şi avem:
Rezultatul Atacului
../../etc/passwd
Are loc concatenarea cu directoriul /home/user/:
Rezultatul Atacului
/home/user/../../etc/passwd
Aceasta va cauza afişarea datelor din /etc/passwd
Rezultatul Atacului
/etc/passwd
Măsuri de control
Validarea datelor de intrare:
- Validarea corectă şi riguroasă a datelor de intrare începe cu presupunerea că toate datele de intrare sunt maliţioase.
- Crează un filtru pentru identificarea celor nemaliţioase.
- Respingeţi toate datele de intrare ce nu corespund specificaţiilor stricte sau aplicaţi transformări pentru a corespunde.
- Utilizaţi principiul respinge tot, acceptă doar cele valide.
- Încercaţi să ţineţi cont de toate tipurile de date de intrare posibile, toate valorile acceptabile, de lungimea datelor de intrare, valorile lipsă sau prea mari şi prea multe, sintaxă, conformarea cu politicile interne şi dependenţa de alte cîmpuri.
- Pentru numele fişierelor, creaţi un set de caractere admisibile pentru validare. Dacă e realizabil, permiteţi un singur caracter “.” şi excludeţi “/”, “\” şi “;”. (Nu uitaţi că numele fişierelor pot conţine mai multe caractere legitime “.” de exemplu: “fis.ier.txt”).
- Utilizaţi “lista albă” a extensiilor fişierelor admisibile.
La nivel de implementare:
Utilizaţi funcţii standard pentru “canonizarea” căilor înainte de utilizarea lor:
* realpath() în C
* getCanonicalPath() în Java
* GetFullPath() în ASP.NET
* realpath() sau abs_path() în Perl
* realpath() în PHP
La nivel de mediu în care rulează sistemul:
Executaţi aplicaţia cu cît mai puţine privilegii posibile. Dacă e realizabil, creaţi conturi izolate de utilizatori cu drepturi limitate pentru task-uri aparte. În acest mod, chiar dacă atacul asupra aplicaţiei va reuşi impactul asupra întregului sistem va fi mult mai mic. De exemplu, aplicaţiile ce utilizează zilnic bazele de date nu trebuie să acceseze bazele de date din numele administratorului.
Be Safe.
#1 by Alex on April 15, 2010 - 15:58
Mihai, te laud, un articol care face citit. Keep it on!!!
#2 by Victor on April 15, 2010 - 16:00
Как обычно заведено риски и проблемы зачастую сваливаются в одну кучу.
Риск – это существующий или развивающийся фактор процесса, который обладает потенциально негативным воздействием на процесс разработки.
Иногда мы ничего не можем сделать с риском или наших воздействий недостаточно, чтобы исключить риск из списка.
Как сказать : разминирование мин, процесс рискованный, но работать надо !
В этом случае мы пытаемся себя подстраховать себя методикой которая является распространённой и суть ее очень проста – двигателем большинства личных усилий является желание не попасть под удар, когда запахнет жареным.
Запахнуть жареным может в любой момент когда выясняется что недостаточно времени было уделено тестированию (!) и проверки на элементарные ошибки и эксплойты.
Ведь по сути своей что такое проект? Проект с точки зрения менеджера — это время, деньги и хепинес заказчика ! Проект по тестированию это такой же проект, с той разницей, что деньгами напрямую тест-менеджеры управляют редко, но их ресурсы в виде человеко-часов в эти деньги можно конвертировать или работать с трудозатратами напрямую.
Риск характеризуется тем, что тестировщики не привлекаются ни к ревью трудозатрат по проекту, ни к получению самих оценок.
Риск игнорирования рисков ! Это один из рисков, который распространяется на все уровни управления рисками.
В этом месте одна голова хорошо, а две — лучше.
Выше изложенная статейка очень познавательная ! и очень своевременная !
Могу лишь добавить маленький нюанс !
если прокатила фишка с “../” , то соответственно может прокатить и другая фишка с “..\” (!!!)
в процессе проверки, нужно обязательно это учитывать !
#3 by Mihai on April 15, 2010 - 16:08
Alex, merci.
Victor, ai dreptate într-adevăr, acest lucru este menţionat în lista măsurilor de control în ultimul punct < << excludeţi “/”, “\” şi “;” >>> însă nu e indicat implicit.
#4 by Victor on April 15, 2010 - 16:15
Mihai, ai dreptate, un profesionist bun ar fi trebuit unele lucrui sa le intuiasca sau sa le prevada
dar cum se spune
piatra mica rastoarna carul mare
deci respectiv un mic maruntzish poate fi problematik pentru un project mare !