Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Php Code Audits (PHP UK 2010)

3,877 views

Published on

Published in: Technology
  • Be the first to comment

Php Code Audits (PHP UK 2010)

  1. 1. PHP code 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 LAMP audits 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. Interviewing developpers Review what the application does Explain the code organization Explain the security features
  7. 7. Review the application Best : have a non-programmer explain the application Then have the programmer explain again The differences are interesting
  8. 8. Killer questions What is the most important asset to secure on the site? «everything» is not an answer data destruction data exportation client separation company image
  9. 9. How was the app secured? Where are the security functions/classes/layers/thingy? How are they applied? How do you check how they are applied ?
  10. 10. I like to hear... Out of web folder Automated deployment Automated tests AND manuals tests Security as a layer (functions and application)
  11. 11. Black Box testing Test from the outside Search the engines Session usurpation Disclosed files Displayed errors Tools : Rats, nikto, Wapiti
  12. 12. Open Code audits What to search for? What are the entry points? How can they be exploited Or protected ?
  13. 13. What to search for? Injections PHP SQL HTML system HTTP
  14. 14. Keep focused Easy to loose focus Tempting to audit everything
  15. 15. PHP injections PHP injections include, require and *_once back ticks ` ` eval(‘’) Using variables
  16. 16. Looking for eval Easy to look for grep Fast, available, convenient 853 occurences Tokenizer Semantic, accurate 37 occurrences
  17. 17. 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] => ) [1] => Array ( [10] => ; ( [0] => 314 [0] => PHP token [1] => hello [1] => PHP code [2] => 1 [2] => Script line ) ) [2] => "
  18. 18. 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...
  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. 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...
  21. 21. 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...
  22. 22. 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...
  23. 23. Assessing the code One liners One line of code is sufficiently to be bad Even though you must follow the code In reverse
  24. 24. 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 ?
  25. 25. $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")); ?>
  26. 26. $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");
  27. 27. Statistical audit Extract one type of information Review it out of context Use this as a starting point for more questions
  28. 28. 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
  29. 29. 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
  30. 30. Other interesting ideas name of functions name of classes name of constants literal strings, numbers Condition (if, while)
  31. 31. register_globals strikes back
  32. 32. register_globals strikes back Don’t use register globals!!
  33. 33. register_globals strikes back Don’t use register globals!! How can you emulate this behavior?
  34. 34. register_globals strikes back Don’t use register globals!! How can you emulate this behavior? There are no less than
  35. 35. register_globals strikes back Don’t use register globals!! How can you emulate this behavior? There are no less than
  36. 36. register_globals strikes back Don’t use register globals!! How can you emulate this behavior? There are no less than
  37. 37. register_globals strikes back Don’t use register globals!! How can you emulate this behavior? There are no less than ways to emulate register_globals...
  38. 38. register_globals strikes back Don’t use register globals!! 5 How can you emulate this behavior? There are no less than ways to emulate register_globals...
  39. 39. register_globals strikesr back e t ! is n g o re ti Don’t use register globals!! e ula 5 s How can you emulate this behavior? u m t e There are no less than ’ l n a o b D lo g ways to emulate register_globals...
  40. 40. register_globals strikes back
  41. 41. register_globals strikes back foreach and $$
  42. 42. register_globals strikes back foreach and $$ extract
  43. 43. register_globals strikes back foreach and $$ extract import_request_var
  44. 44. register_globals strikes back foreach and $$ extract import_request_var $GLOBALS
  45. 45. register_globals strikes back foreach and $$ extract import_request_var $GLOBALS parse_str
  46. 46. 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
  47. 47. SQL injections Point of entry mysql_query mysqli_real_escape_string SQL query : string with SELECT, UPDATE, ...
  48. 48. 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)
  49. 49. And also Header injection Look for header() XSS look for echo, print look for strings with tags Etc...
  50. 50. Report Executive summary 3 paragraphs, simple to read Problems summary Table, with problems, criticality and load Details Extras
  51. 51. Report Vulnerability Critical Load register_globals High High Injections High Medium SQL injection Medium High headers Low Low
  52. 52. Details Title In code example and explanation Protection suggestions Limitations List of all occurrences Or way to find them
  53. 53. Team Work Security is recommanded at conception time Audit is an after-thought tool Once When necessary Regularly Continuously
  54. 54. PHP Mantra List your mantra The five most important rules you agree upon Have them printed and visible to everyone
  55. 55. 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
  56. 56. 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/)
  57. 57. Community step up Mantra, cross audits go beyond services and departements Open this outside ? External review? New way of coding ?
  58. 58. Questions? damien.seguy@alterw ay.fr

×