PHP security audits
Assess your code for security<script>alert(‘XSS’..
Agenda


How to run an audit
Scouting the PHP code
Organizing for security
Speaker


 Damien Seguy
 Raise elePHPants
 damien.seguy@alterway.fr
Yes,
we take
questions
PHP code audits

Interview with the developpers : 1 day
Black Box testing              : 1 day
Open Code audit            ...
The application
  http://www.cligraphcrm.com/
Interviewing developpers


 Review what the application does
 Explain the code organization
 Explain the security features
Review the application


 Best : have a non-programmer explain the application
 Then have the programmer explain again
   ...
Killer question
 What is the most important asset to secure on the site?
   «everything» is not an answer
 data destructio...
How was the app secured?


Where are the security functions?
How are they applied?
How do you check how they are applied ?
I like to hear...

 Out of web folder
 Automated deployement
 Automated tests AND manuals tests
 Security as a layer (func...
Black Box testing
 Test from the outside
 Search the engines
 Session usurpation
 Disclosed files
 Displayed errors
 Tools ...
Open Code audits

What to search for?
What are the entry points?
How can they be exploited
  Or protected ?
What to search for?

  Injections
    PHP
    SQL
    HTML
    system
    HTTP
Keep focused


               Easy to loose focus
               Tempting to audit
               everything
PHP injections

PHP injections
  include, require and *_once
  back ticks ` `
  eval(‘’)
Using variables
Looking for eval
 Easy to look for
 grep
   Fast, available, convenient
   853 occurences
 Tokenizer
   Semantic, accurate...
Tokenizer
<?php print ("hello $world! "); ?>
  [1] => Array
      (                   [6] => Array
          [0] => 266   ...
Evals

◦ eval('$retour=$GLOBALS["'.$matches[1].'"];')
  ◦ Variable variables.
◦ eval($contenu_thjipk);
◦ eval($contents_es...
Assessing the code

One liners
  One line of code is sufficiently to be bad
Even though
  you must follow the code
  In rev...
Inclusion
◦ require("../params_frm.php")
◦ require(fct_lien_page_custom(TYPE_DOMAINE."/".TYPE_DOC.
  "_custom.php","abs"))...
$format ?
<?php require("../params_trt.php");

$format=htmlentities($_REQUEST['exp_formdoc']);
if(empty($_REQUEST['exp_aff...
$choix_format ?
  switch($choix) {
    case 0 : $choix_page="tabl";
    break;
    case 1 : $choix_page="histo1"; 
       ...
Statistical audit


 Extract one type of information
 Review it out of context
 Use this as a starting point for more ques...
Comments
//echo "<div><a class="texte1" style=...
#echo "<pre>";
  Left overs : what were they for?
#print_r($_REQUEST);
 ...
Variables
 6883 different variables names
 All one possible one letter variable
 32 chars : $cache_maxsize_UTF8StringToArr...
Other interesting ideas
 name of functions
 name of classes
 name of constants
 literal
    strings, numbers
 Condition (i...
register_globals strikes back
register_globals strikes back


 Don’t use register globals!!
register_globals strikes back


 Don’t use register globals!!
 How can you emulate this behavior?
register_globals strikes back
register_globals strikes back

 foreach and $$
register_globals strikes back

 foreach and $$
 extract
register_globals strikes back

 foreach and $$
 extract
 import_request_var
register_globals strikes back

 foreach and $$
 extract
 import_request_var
 $GLOBALS
register_globals strikes back

 foreach and $$
 extract
 import_request_var
 $GLOBALS
 parse_str
Found!

◦ ./install/identification.php
◦ extract($_POST)  : 1
  ◦ Injection by $_POST


◦ ./fonctions/fonctions_gen.php
◦ $...
SQL injections	

 Point of entry
   mysql_query
   mysqli_real_escape_string
   SQL query :
     string with SELECT, UPDAT...
Found!
◦ 'UPDATE param_suivi SET      param_suivi_nom="'.str_replace($tr
  ansf_sp,$transf_fr,$_POST["suivi_nom"])  : 1
  ...
And also
Header injection
  Look for header()
XSS
  look for echo, print
  look for strings with tags
Etc...
Report
Executive summary
  3 paragraphs, simple to read
Problems summary
  Table, with problems, criticality and load
Deta...
Report
 Vulnerability     Critical    Load

register_globals    High       High

   Injections       High      Medium

 SQ...
Details
 Title
 In code example and explanation
 Protection suggestions
   Limitations
 List of all occurrences
   Or way ...
Team Work
Security is recommanded at conception time
Audit is an after-thought tool
  Once
  When necessary
  Regularly
  ...
PHP Mantra


List your mantra
The five most important rules you agree upon
Have them printed and visible to everyone
Cross audit

Group developers by two
  Have each one review the code of the other
  Based on the mantra
Light weight proce...
PHP audit tools

Groogle (http://groogle.sourceforge.net)
Review Board (http://www.review-board.org/)
Rietveld http://code...
Community step up

Mantra, cross audits
  go beyond services and departements
Open this outside ?
  External review?
New w...
Questions?
damien.seguy@alterw
ay.fr
Upcoming SlideShare
Loading in...5
×

PHP security audits

6,552

Published on

How to run a security audit on PHP code.

Published in: Technology
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
6,552
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
255
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide
  • Transcript of "PHP security audits"

    1. 1. PHP security audits Assess your code for security<script>alert(‘XSS’..
    2. 2. Agenda How to run an audit Scouting the PHP code Organizing for security
    3. 3. Speaker Damien Seguy Raise elePHPants damien.seguy@alterway.fr
    4. 4. Yes, we take questions
    5. 5. PHP code audits Interview with the developpers : 1 day Black Box testing : 1 day Open Code audit : 2 days Report and review : 1 day
    6. 6. The application http://www.cligraphcrm.com/
    7. 7. Interviewing developpers Review what the application does Explain the code organization Explain the security features
    8. 8. Review the application Best : have a non-programmer explain the application Then have the programmer explain again The differences are interesting
    9. 9. Killer question What is the most important asset to secure on the site? «everything» is not an answer data destruction data exportation client separation company image
    10. 10. How was the app secured? Where are the security functions? How are they applied? How do you check how they are applied ?
    11. 11. I like to hear... Out of web folder Automated deployement Automated tests AND manuals tests Security as a layer (functions and application)
    12. 12. Black Box testing Test from the outside Search the engines Session usurpation Disclosed files Displayed errors Tools : Rats, nikto, Wapiti
    13. 13. Open Code audits What to search for? What are the entry points? How can they be exploited Or protected ?
    14. 14. What to search for? Injections PHP SQL HTML system HTTP
    15. 15. Keep focused Easy to loose focus Tempting to audit everything
    16. 16. PHP injections PHP injections include, require and *_once back ticks ` ` eval(‘’) Using variables
    17. 17. Looking for eval Easy to look for grep Fast, available, convenient 853 occurences Tokenizer Semantic, accurate 37 occurrences
    18. 18. Tokenizer <?php print ("hello $world! "); ?> [1] => Array ( [6] => Array [0] => 266 ( [1] => print [0] => 309 [2] => 1 [1] => $world ) [2] => 1 ) [2] => Array ( [7] => Array [0] => 370 ( [1] => [0] => 314 [2] => 1 [1] => ! ) [2] => 1 ) [3] => ( [4] => " [8] => " [5] => Array [9] => ) ( [10] => ; [0] => 314 [1] => Array [1] => hello ( [2] => 1 [0] => PHP token ) [1] => PHP code [2] => Script line ) [2] => "
    19. 19. Evals ◦ eval('$retour=$GLOBALS["'.$matches[1].'"];') ◦ Variable variables. ◦ eval($contenu_thjipk); ◦ eval($contents_essai); ◦ Content is read into variable, then executed : an include? ◦ eval('$hexdtime = "'.$hexdtime.'";') ◦ Long way to cast a string into a string ◦ eval('$retour2.= '.var_dump($recept->erreur).';') ◦ This doesn’t even make sense...
    20. 20. Assessing the code One liners One line of code is sufficiently to be bad Even though you must follow the code In reverse
    21. 21. Inclusion ◦ require("../params_frm.php") ◦ require(fct_lien_page_custom(TYPE_DOMAINE."/".TYPE_DOC. "_custom.php","abs")) ◦ require(fct_lien_page_custom("params_footer.php","abs")) ◦ Pretty secure inclusions ◦ But 96 variables used in includes ◦ include(fct_lien_page_custom("action/facture_". $format.".php","abs")) ◦ $format, anyone? ◦ require_once("etat_simple_".$choix_page."_trt.php") ◦ $choix_page, anyone ?
    22. 22. $format ? <?php require("../params_trt.php"); $format=htmlentities($_REQUEST['exp_formdoc']); if(empty($_REQUEST['exp_affiche'])) $affichage=0;  else $affichage=$_REQUEST['exp_affiche']; if(empty($_REQUEST['exp_stockdoc'])) $stockage=0;  else $stockage=$_REQUEST['exp_stockdoc']; $cde_id=$_REQUEST['exp_id']; $type_doc=$_REQUEST['exp_typedoc']; require(fct_lien_page_custom("fonctions/fonction_img.php","abs")); include(fct_lien_page_custom("action/facture_". $format.".php","abs")); ?>
    23. 23. $choix_format ?   switch($choix) {     case 0 : $choix_page="tabl";     break;     case 1 : $choix_page="histo1";  if ($gfx_sens_graph=="1") $gfx_margegauche_dft="90";     break;     case 2 : $choix_page="histo2";  if ($gfx_sens_graph=="1") $gfx_margegauche_dft="90";     break;     case 3 : $choix_page="histo3";  if ($gfx_sens_graph=="1") $gfx_margegauche_dft="90";     break;     case 4 : $choix_page="histo4";  if ($gfx_sens_graph=="1") $gfx_margegauche_dft="90";     break; } ###...Way below     require_once("etat_simple_".$choix_page."_trt.php");
    24. 24. Statistical audit Extract one type of information Review it out of context Use this as a starting point for more questions
    25. 25. Comments //echo "<div><a class="texte1" style=... #echo "<pre>"; Left overs : what were they for? #print_r($_REQUEST); No organization for bugs? // hack for mozilla sunbird's extra = signs Look for swearing, TODO, hack
    26. 26. Variables 6883 different variables names All one possible one letter variable 32 chars : $cache_maxsize_UTF8StringToArray Most used : $i (2586 times) $_1904, $samedi, $dummy, $sss, 19 $unknowns 711 variables used only once in the code
    27. 27. Other interesting ideas name of functions name of classes name of constants literal strings, numbers Condition (if, while)
    28. 28. register_globals strikes back
    29. 29. register_globals strikes back Don’t use register globals!!
    30. 30. register_globals strikes back Don’t use register globals!! How can you emulate this behavior?
    31. 31. register_globals strikes back
    32. 32. register_globals strikes back foreach and $$
    33. 33. register_globals strikes back foreach and $$ extract
    34. 34. register_globals strikes back foreach and $$ extract import_request_var
    35. 35. register_globals strikes back foreach and $$ extract import_request_var $GLOBALS
    36. 36. register_globals strikes back foreach and $$ extract import_request_var $GLOBALS parse_str
    37. 37. Found! ◦ ./install/identification.php ◦ extract($_POST)  : 1 ◦ Injection by $_POST ◦ ./fonctions/fonctions_gen.php ◦ $GLOBALS[$k] = $chaine[$k] ◦ $GLOBALS[$this->mode] [$k] = $chaine[$k] ◦ In the fct_urldecode, the values are stripslashed, and then injected in the $GLOBALS, resulting in variable creation
    38. 38. SQL injections Point of entry mysql_query mysqli_real_escape_string SQL query : string with SELECT, UPDATE, ...
    39. 39. Found! ◦ 'UPDATE param_suivi SET      param_suivi_nom="'.str_replace($tr ansf_sp,$transf_fr,$_POST["suivi_nom"])  : 1 ◦ Direct injection via POST ◦ WHERE campagne_nom LIKE '%".addslashes($_REQUEST['rech_nom'])  ◦ Injection from $_REQUEST ◦ "UPDATE even_spl SET even_spl_fait='". $even_fait."',even_spl_modification='".$date_du_jour."'     WHERE even_spl_id='".$even_id."' AND even_spl_affaire_id='". $even_aff_id."'";  : 1 ◦ "INSERT INTO ".$type_doc."_suivi    (". $type_doc."_suivi_param_suivi_id, ".$type_doc."_suivi_". $type_doc."_id, ".$type_doc."_suivi_canal_id,    ". $type_doc."_suivi_action, ".$type_doc."_suivi_commentaire, ". $type_doc."_suivi_creation)    VALUES ('".$id_suivi."', '". $id_doc."', '".$id_canal."', '". $suivi_date."', '".addslashes($suivi_commentaire)
    40. 40. And also Header injection Look for header() XSS look for echo, print look for strings with tags Etc...
    41. 41. Report Executive summary 3 paragraphs, simple to read Problems summary Table, with problems, criticality and load Details Extras
    42. 42. Report Vulnerability Critical Load register_globals High High Injections High Medium SQL injection Medium High headers Low Low
    43. 43. Details Title In code example and explanation Protection suggestions Limitations List of all occurrences Or way to find them
    44. 44. Team Work Security is recommanded at conception time Audit is an after-thought tool Once When necessary Regularly Continuously
    45. 45. PHP Mantra List your mantra The five most important rules you agree upon Have them printed and visible to everyone
    46. 46. Cross audit Group developers by two Have each one review the code of the other Based on the mantra Light weight process Doesn’t have to be in the same project
    47. 47. PHP audit tools Groogle (http://groogle.sourceforge.net) Review Board (http://www.review-board.org/) Rietveld http://codereview.appspot.com/ SmartBear (http://www.smartbear.com/)
    48. 48. Community step up Mantra, cross audits go beyond services and departements Open this outside ? External review? New way of coding ?
    49. 49. Questions? damien.seguy@alterw ay.fr
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×