|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
One of my sites has been hacked and I'm trying to find the hole. The hack code creates dirs with
"nobody" ownership, so it's obvious stuff is not via ftp [ownership would be foo] Site is virtual host, Linux/Apache I'm concerned about a file uploader my users use to upload photos. Can anyone see a hole in this scrip? Can my code upload an executable masquerading as an image file? $filetype = array("gif", "jpg", "jpeg", "png", "txt", css") function csvt_file_upload($filetype, $max_size) { $prohibits = array("exe", "php", "inc", "php3", "pl", "bat", "cgi"); //common executables. $absolute_max_size = 2000000; end($_FILES); //get the "name" used by the html <input..... $name = key($_FILES); //could use the register variables, but this is safer. if(isset($_FILES[$name]['name'])) $input_name = $_FILES[$name]['name']; $error = "no"; //reset for error checks if (!isset($filetype)) { echo "<p style=\"color:red\"> File type assignment missing </p> "; $error = "yes"; }; if (!isset($max_size)) { echo "<p style=\"color:red\"> Max file size assignment missing.</p>"; $error = "yes"; }; $filename = $_FILES[$name]['name']; $tmp_name = $_FILES[$name]['tmp_name']; $size = $_FILES[$name]['size']; $absolute_path_file = getcwd(). DATA_DIR . $filename; if (($size >= $max_size) OR ($size > $absolute_max_size)) { echo "<p style=\"color:red\"> File size is too large.</p> "; $error = "yes"; } $ext = substr(strrchr($filename, "."), 1); //get the extension, remove the "." if (in_array($ext, $prohibits)) { echo "<p style=\"color:red\">Illegal file type, executable.</p>\r\n"; $error = "yes"; } if (is_executable($filename)) { echo "<p style=\"color:red\">Illegal file type, executable file.</p>\r\n"; $error = "yes"; } //This is a double check in case $prohibits is incomplete. if (is_array($filetype) AND !in_array($ext, $filetype)) { echo "<p style=\"color:red\">Illegal file type.</p>\r\n"; $error = "yes"; } if(!is_array($filetype) AND ($filetype != $ext)){ echo "<p style=\"color:red\">Illegal file type.</p>\r\n"; $error = "yes"; } if ($error == "yes") { echo "<p style=\"color:red\">There was an error(s) with your file selection \"$input_name\" as the note(s) indicates. Please reselect, or remove your file selection and email for . </p>\r\n"; } else { if(!move_uploaded_file($tmp_name, $absolute_path_file)) die("<p style=\"color:red\">There was an error saving your file. Check permissions of " . DATA_DIR .. " Must be 777 </p>\r\n"); chmod($absolute_path_file, 0644); } return; } |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
How was it "hacked"?
That will determine what kind of exploit might have been used. On 4/11/08, Al <news@ridersite.org> wrote: > One of my sites has been hacked and I'm trying to find the hole. The hack > code creates dirs with "nobody" ownership, so it's obvious stuff is not via > ftp [ownership would be foo] |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
The hack puts this .htaccess in dozens of dirs RewriteEngine On RewriteCond %{HTTP_REFERER} ^http://([a-z0-9_\-]+\.)*(google|msn|yahoo|live|ask|dogpile|mywebsearc h|yandex|rambler|aport|mail|gogo|poisk|alltheweb|f ireball|freenet|abacho|wanadoo|free|club-internet|aliceadsl|alice|skynet|terra|ya|orange|cl ix|terravista|gratis-ting|suomi24)\. [NC] RewriteCond %{HTTP_REFERER} [?&](q|query|qs|searchfor|search_for|w|p|r|key|keyword s|search_string|search_word|buscar|text|words|su|q t|rdata)\= RewriteCond %{HTTP_REFERER} \=[^&]+(%3A|%22) RewriteCond %{TIME_SEC} <59 RewriteRule ^.*$ /StartLocs/maps/kapicag/ex3/t.htm [L] # a995d2cc661fa72452472e9554b5520c The kapicag/ex3/t.htm appears to be phishing site. mike wrote: > How was it "hacked"? > > That will determine what kind of exploit might have been used. > > > On 4/11/08, Al <news@ridersite.org> wrote: >> One of my sites has been hacked and I'm trying to find the hole. The hack >> code creates dirs with "nobody" ownership, so it's obvious stuff is not via >> ftp [ownership would be foo] |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
I would recommend something more strong
http://www.php.net/manual/en/functio...-imagetype.php or if you dont have exif http://www.php.net/manual/en/function.getimagesize.php will do also a trick. One more thing, you are also allowing .txt and .css which may be potential hole, as Apache can run .css also through PHP engine if configured to do so. Sometimes I use PHP to process CSS so I can have dynamic CSS for some rare cases. On Apr 12, 2008, at 2:24 AM, Al wrote: > One of my sites has been hacked and I'm trying to find the hole. > The hack code creates dirs with "nobody" ownership, so it's obvious > stuff is not via ftp [ownership would be foo] > > Site is virtual host, Linux/Apache > > I'm concerned about a file uploader my users use to upload photos. > > Can anyone see a hole in this scrip? Can my code upload an > executable masquerading as an image file? > > $filetype = array("gif", "jpg", "jpeg", "png", "txt", css") > > function csvt_file_upload($filetype, $max_size) > { > $prohibits = array("exe", "php", "inc", "php3", "pl", "bat", > "cgi"); //common executables. > $absolute_max_size = 2000000; > > end($_FILES); //get the "name" used by the html <input..... > $name = key($_FILES); //could use the register variables, but > this is safer. > if(isset($_FILES[$name]['name'])) $input_name = $_FILES[$name] > ['name']; > > $error = "no"; //reset for error checks > > if (!isset($filetype)) { > echo "<p style=\"color:red\"> File type assignment > missing </p> "; > $error = "yes"; > }; > > if (!isset($max_size)) { > echo "<p style=\"color:red\"> Max file size assignment > missing.</p>"; > $error = "yes"; > }; > > $filename = $_FILES[$name]['name']; > $tmp_name = $_FILES[$name]['tmp_name']; > $size = $_FILES[$name]['size']; > > $absolute_path_file = getcwd(). DATA_DIR . $filename; > > > if (($size >= $max_size) OR ($size > $absolute_max_size)) { > echo "<p style=\"color:red\"> File size is too large.</p> "; > $error = "yes"; > } > > $ext = substr(strrchr($filename, "."), 1); //get the extension, > remove the "." > if (in_array($ext, $prohibits)) { > echo "<p style=\"color:red\">Illegal file type, > executable.</p>\r\n"; > $error = "yes"; > } > if (is_executable($filename)) { > echo "<p style=\"color:red\">Illegal file type, executable > file.</p>\r\n"; > $error = "yes"; > } //This is a double check in case $prohibits is incomplete. > if (is_array($filetype) AND !in_array($ext, $filetype)) { > echo "<p style=\"color:red\">Illegal file type.</p>\r\n"; > $error = "yes"; > } > if(!is_array($filetype) AND ($filetype != $ext)){ > echo "<p style=\"color:red\">Illegal file type.</p>\r\n"; > $error = "yes"; > } > if ($error == "yes") { > echo "<p style=\"color:red\">There was an error(s) with > your file selection \"$input_name\" as the note(s) indicates. > Please reselect, or remove your file selection and email for . > </p>\r\n"; > } > else { > if(!move_uploaded_file($tmp_name, $absolute_path_file)) > die("<p style=\"color:red\">There was an error saving your file. > Check permissions of " . DATA_DIR . " Must be 777 </p>\r\n"); > > chmod($absolute_path_file, 0644); > } > > return; > } > > -- > PHP General Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php > Igor Jocic http://www.carster.us/ |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Al wrote:
> One of my sites has been hacked and I'm trying to find the hole. The > hack code creates dirs with "nobody" ownership, so it's obvious stuff is > not via ftp [ownership would be foo] > > Site is virtual host, Linux/Apache > > I'm concerned about a file uploader my users use to upload photos. > <!-- SNIP --> First off, file type means NOTHING to people using uploaders. I have had a number of people try to hack my site with my uploader and they never succeed. If you don't parse the first few lines of the file, you're probably gonna find yourself hacked again. Depending on the size of the machine, you could just read the whole file and look for php somewhere in it, and if it exists, erase immediately. image.php.gif.jpg would pass your test as far as checking extensions. I have a number of the scripts used by others to try to hack my site available for download/review. If you search the archives, you should find them. If not, contact me directly and I'll send you the link to them. HTH, Wolf |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Thanks guys.
I had written a newer version restricted to images which checks MIME and image width and height. I have one application which needs a text file. I think I'll have my users hide a password in it and scan the whole file for <? an <?php and other signs of scripts, etc. Al wrote: > One of my sites has been hacked and I'm trying to find the hole. The > hack code creates dirs with "nobody" ownership, so it's obvious stuff is > not via ftp [ownership would be foo] > > Site is virtual host, Linux/Apache > > I'm concerned about a file uploader my users use to upload photos. > > Can anyone see a hole in this scrip? Can my code upload an executable > masquerading as an image file? > > $filetype = array("gif", "jpg", "jpeg", "png", "txt", css") > > function csvt_file_upload($filetype, $max_size) > { > $prohibits = array("exe", "php", "inc", "php3", "pl", "bat", "cgi"); > //common executables. > $absolute_max_size = 2000000; > > end($_FILES); //get the "name" used by the html <input..... > $name = key($_FILES); //could use the register variables, but this > is safer. > if(isset($_FILES[$name]['name'])) $input_name = $_FILES[$name]['name']; > > $error = "no"; //reset for error checks > > if (!isset($filetype)) { > echo "<p style=\"color:red\"> File type assignment missing > </p> "; > $error = "yes"; > }; > > if (!isset($max_size)) { > echo "<p style=\"color:red\"> Max file size assignment > missing.</p>"; > $error = "yes"; > }; > > $filename = $_FILES[$name]['name']; > $tmp_name = $_FILES[$name]['tmp_name']; > $size = $_FILES[$name]['size']; > > $absolute_path_file = getcwd(). DATA_DIR . $filename; > > > if (($size >= $max_size) OR ($size > $absolute_max_size)) { > echo "<p style=\"color:red\"> File size is too large.</p> "; > $error = "yes"; > } > > $ext = substr(strrchr($filename, "."), 1); //get the extension, > remove the "." > if (in_array($ext, $prohibits)) { > echo "<p style=\"color:red\">Illegal file type, > executable.</p>\r\n"; > $error = "yes"; > } > if (is_executable($filename)) { > echo "<p style=\"color:red\">Illegal file type, executable > file.</p>\r\n"; > $error = "yes"; > } //This is a double check in case $prohibits is incomplete. > if (is_array($filetype) AND !in_array($ext, $filetype)) { > echo "<p style=\"color:red\">Illegal file type.</p>\r\n"; > $error = "yes"; > } > if(!is_array($filetype) AND ($filetype != $ext)){ > echo "<p style=\"color:red\">Illegal file type.</p>\r\n"; > $error = "yes"; > } > if ($error == "yes") { > echo "<p style=\"color:red\">There was an error(s) with your > file selection \"$input_name\" as the note(s) indicates. Please > reselect, or remove your file selection and email for . </p>\r\n"; > } > else { > if(!move_uploaded_file($tmp_name, $absolute_path_file)) > die("<p style=\"color:red\">There was an error saving your file. > Check permissions of " . DATA_DIR . " Must be 777 </p>\r\n"); > > chmod($absolute_path_file, 0644); > } > > return; > } |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
Al wrote:
> Thanks guys. > > I had written a newer version restricted to images which checks MIME and > image width and height. > > I have one application which needs a text file. I think I'll have my > users hide a password in it and scan the whole file for <? an <?php and > other signs of scripts, etc. > > Al wrote: >> One of my sites has been hacked and I'm trying to find the hole. The >> hack code creates dirs with "nobody" ownership, so it's obvious stuff >> is not via ftp [ownership would be foo] >> >> Site is virtual host, Linux/Apache >> >> I'm concerned about a file uploader my users use to upload photos. >> >> Can anyone see a hole in this scrip? Can my code upload an executable >> masquerading as an image file? >> You probably need a deeper inspection than checking the extension - that's Microsoft thinking... You can't trust what the client is telling you - even the MIME type sent by the browser is no guarantee. Since you're on Linux, why not look at using the 'file' shell command to get a more detailed inspection of the upload. I made a basic function like this a few years ago - probably needs a bit of tweaking: <?php function getMimeType($file) { global $magicFile; $mimecmd = "/usr/bin/file -b -m ".escapeshellargs($magicFile)." ".escapeshellargs($file)." 2> /dev/null"; $ret = exec($mimecmd); if (!$ret) { $ret = "unknown"; } return $ret; } ?> The global $magicFile is the tricky bit - you need to find a nice Unix magic numbers file that returns mime types (they're easier to parse than regular magic number responses). Probably something like /usr/share/misc/magic.mime, but that depends on the system. -- Peter Ford phone: 01580 893333 Developer fax: 01580 893399 Justcroft International Ltd., Staplehurst, Kent |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
I don't pay any attention to MIME sent by the client.
I check the MIME returned from getimagesize() and I'm not too certain of it. i need to do further research. I do check the images have width and height and I extract the embedded text stuff. I'm going to look into your suggestion. Thanks. Peter Ford wrote: > Al wrote: >> Thanks guys. >> >> I had written a newer version restricted to images which checks MIME >> and image width and height. >> >> I have one application which needs a text file. I think I'll have my >> users hide a password in it and scan the whole file for <? an <?php >> and other signs of scripts, etc. >> >> Al wrote: >>> One of my sites has been hacked and I'm trying to find the hole. The >>> hack code creates dirs with "nobody" ownership, so it's obvious stuff >>> is not via ftp [ownership would be foo] >>> >>> Site is virtual host, Linux/Apache >>> >>> I'm concerned about a file uploader my users use to upload photos. >>> >>> Can anyone see a hole in this scrip? Can my code upload an executable >>> masquerading as an image file? >>> > You probably need a deeper inspection than checking the extension - > that's Microsoft thinking... > You can't trust what the client is telling you - even the MIME type sent > by the browser is no guarantee. > Since you're on Linux, why not look at using the 'file' shell command to > get a more detailed inspection of the upload. > I made a basic function like this a few years ago - probably needs a bit > of tweaking: > > <?php > function getMimeType($file) > { > global $magicFile; > $mimecmd = "/usr/bin/file -b -m ".escapeshellargs($magicFile)." > ".escapeshellargs($file)." 2> /dev/null"; > $ret = exec($mimecmd); > if (!$ret) > { > $ret = "unknown"; > } > return $ret; > } > ?> > > The global $magicFile is the tricky bit - you need to find a nice Unix > magic numbers file that returns mime types (they're easier to parse than > regular magic number responses). Probably something like > /usr/share/misc/magic.mime, but that depends on the system. > > |
|
![]() |
| Outils de la discussion | |
|
|