Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Problem with PHP upload script

Posted on 2015-02-20
7
Medium Priority
?
113 Views
Last Modified: 2015-02-23
Hello..

Need a urgent help.

A hacker uploading php file through image upload option and hacking my website.

Anyone can register on my website and upload their profile picture. This guy is somehow uploading a php file through this option. From that file he is able to access all files and upload different malicious files to the server.

I've browser side and server side validations but still not able to figure out how is he uploading.

my upload script will change Image file name automatically before uploading to  the server.

for example :

if you upload sample.jpg it will convert to esd2238982.jpg (System generated name). This is guy is converting to esd2238982.php

please help me to trace this problem. i cant control him from accessing the website. instead i want to make the necessary coding changes.

Thanks
Sarath
0
Comment
Question by:sarath_nalla
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 8

Expert Comment

by:Ahmed Merghani
ID: 40622724
What is the validation you have in the server side?
0
 

Author Comment

by:sarath_nalla
ID: 40622730
image extension and mime type
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 40623070
Convert the image file into a PNG.  Also, make sure you track your clients so you can catch and disable accounts that exhibit this behavior!

I'll try to show you a code sample in a moment.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:sarath_nalla
ID: 40623076
Thanks for helping me out...He is actual a hacker..
0
 
LVL 111

Accepted Solution

by:
Ray Paseur earned 2000 total points
ID: 40623084
I have only tested this a little bit, but it seems to work.  Obviously I will not leave it on my server, but hopefully it will show you the design guidance you might use to stop unwanted uploads.
http://iconoun.com/demo/temp_sarath.php

The important part starts around line 147.
<?php // demo/temp_sarath.php
/**
 * Demonstrate how to upload a single file in PHP
 *
 * REQUIRED: Man Page References
 * http://php.net/manual/en/reserved.variables.files.php
 * http://php.net/manual/en/features.file-upload.php
 * http://php.net/manual/en/features.file-upload.common-pitfalls.php
 * http://php.net/manual/en/function.move-uploaded-file.php
 *
 * IMPORTANT: If dealing with large files
 * http://php.net/manual/en/ini.core.php#ini.upload-max-filesize
 * http://php.net/manual/en/ini.core.php#ini.post-max-size
 * http://php.net/manual/en/info.configuration.php#ini.max-input-time
 */
error_reporting(E_ALL);

// PHP 5.1+  SEE http://php.net/manual/en/function.date-default-timezone-set.php
date_default_timezone_set('America/Chicago');

// ESTABLISH THE BIGGEST FILE SIZE WE CAN ACCEPT - ABOUT 8 MB
$max_file_size = '8000000';

// ESTABLISH THE KINDS OF FILE EXTENSIONS WE WANT (USE UPPERCASE ONLY)
$file_exts = array
( 'PNG'
, 'JPG'
)
;
$f_exts = implode(', ', $file_exts);

// ESTABLISH THE NAME OF THE DESTINATION FOLDER
$my_dir = getcwd();

// OR USE THIS TO PUT UPLOADS IN A SEPARATE FOLDER
$my_dir = 'storage';
if (!is_dir($my_dir))
{
    mkdir($my_dir);
}

// LIST OF THE ERRORS THAT MAY BE REPORTED IN $_FILES[]["error"] (THERE IS NO #5)
$errors = array
( 0 => "Success!"
, 1 => "The uploaded file exceeds the upload_max_filesize directive in php.ini"
, 2 => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"
, 3 => "The uploaded file was only partially uploaded"
, 4 => "No file was uploaded"
, 5 => "UNDEFINED ERROR"
, 6 => "Missing a temporary folder"
, 7 => "Cannot write file to disk"
)
;


// IF THERE IS INFORMATION POSTED
if (!empty($_POST))
{
    // IF THERE ARE ERRORS
    $error_code    = $_FILES["userfile"]["error"];
    if ($error_code)
    {
        trigger_error($errors[$error_code], E_USER_ERROR);
    }

    // GET THE FILE SIZE
    $fsize = number_format($_FILES["userfile"]["size"]);

    // SYNTHESIZE THE NEW FILE NAME FOR TEMPORARY STORAGE
    $fname = basename($_FILES['userfile']['name']);

    // FAIL IF THIS IS NOT AN ALLOWABLE EXTENSION
    $f_ext = explode('.', $fname);
    $f_nom = current($f_ext);
    $f_ext = end($f_ext);
    $f_ext = strtoupper(trim($f_ext));
    if (!in_array($f_ext, $file_exts)) trigger_error("$f_ext NOT ALLOWED.  CHOOSE FROM $f_exts", E_USER_ERROR);

    // THE SERVER PATH TO THE FILE
    $my_path
    = getcwd()
    . DIRECTORY_SEPARATOR
    . $my_dir
    . DIRECTORY_SEPARATOR
    . $f_nom . '.png'
    ;

    // THE URL PATH TO THE FILE
    $my_url
    = $my_dir
    . DIRECTORY_SEPARATOR
    . $f_nom . '.png'
    ;

    // MESSAGES ABOUT THE UPLOAD STATUS, IF ANY
    $msg = NULL;

    // IF THE FILE IS NEW (DOES NOT EXIST)
    if (!file_exists($my_path))
    {
        // IF THE MOVE FUNCTION WORKED CORRECTLY
        if (move_uploaded_file($_FILES['userfile']['tmp_name'], $my_path))
        {
            $upload_success = 1;
        }
        // IF THE MOVE FUNCTION FAILED IT PROBABLY THREW A MESSAGE
        else
        {
            $upload_success = -1;
            trigger_error("MOVE TO $my_path FAILED", E_USER_ERROR);
        }
    }

    // IF THE FILE ALREADY EXISTS
    else
    {
        $msg .= "<br/><b><i>$my_url</i></b> already exists" . PHP_EOL;

        // SHOULD WE OVERWRITE THE FILE? IF NOT
        if (empty($_POST["overwrite"]))
        {
            $upload_success = 0;
        }

        // IF WE SHOULD OVERWRITE THE FILE, TRY TO MAKE A BACKUP
        else
        {
            $now    = date('Y-m-d-His');
            $my_bak = $my_path . '.' . $now . '.bak';
            if (!copy($my_path, $my_bak))
            {
                $msg .= "<br/><strong>Attempted Backup Failed!</strong>" . PHP_EOL;
            }
            if (move_uploaded_file($_FILES['userfile']['tmp_name'], $my_path))
            {
                $upload_success = 2;
            }
            else
            {
                $upload_success = -1;
                trigger_error("MOVE TO $my_path FAILED", E_USER_ERROR);
            }
        }
    }


    // CONVERT THE IMAGE TO A PNG
    $img = @ImageCreateFromJpeg($my_path);
    if (!$img) $img = @ImageCreateFromPng($my_path);
    if (!$img)
    {
        unlink($my_path);
        trigger_error("$fname is not an acceptable file", E_USER_ERROR);
    }
    ImagePNG($img, $my_path);
    ImageDestroy($img);


    // PREPARE A REPORT OF THE SCRIPT'S SUCCESS OR FAILURE
    if ($upload_success == 2) { $msg .= "<br/>A backup was made and the file was overwritten" . PHP_EOL; }
    if ($upload_success == 1) { $msg .= "<br/><strong>$my_url</strong> has been saved" . PHP_EOL; }
    if ($upload_success == 0) { $msg .= "<br/><strong>It was NOT overwritten.</strong>" . PHP_EOL; }
    if ($upload_success < 0)  { $msg .= "<br/><strong>ERROR: $my_url NOT SAVED - SEE WARNING FROM move_uploaded_file()</strong>" . PHP_EOL; }

    // ADD FILE SIZE AND PERMISSION INFORMATION
    if ($upload_success > 0)
    {
        $msg .= "<br/>$fsize bytes uploaded" . PHP_EOL;
        if (!chmod ($my_path, 0755))
        {
            $msg .= "<br/>chmod(0755) FAILED: fileperms() = ";
            $msg .= substr(sprintf('%o', fileperms($my_path)), -4);
        }
    }

    // SHOW THE SUCCESS OR FAILURE
    echo $msg;

    // SHOW A LINK TO THE FILE
    echo '<br/>'
    . '<a href="'
    . $my_url
    . '" target="_blank">'
    . "See: $my_url"
    . '</a>'
    ;
}


// CREATE THE FORM FOR INPUT (USING HEREDOC SYNTAX)
$form = <<<EOF
<h2>Upload a File</h2>
<p>
<form enctype="multipart/form-data" method="post">
<!--
    SOME IMPORTANT THINGS TO NOTE ABOUT THIS FORM...
    ENCTYPE= ATTRIBUTE IN THE HTML <FORM> TAG
    MAX_FILE_SIZE HIDDEN CONTROL MUST PRECEDE THE FILE INPUT CONTROLS
    INPUT NAME= IN TYPE=FILE DETERMINES THE NAME YOU FIND IN _FILES ARRAY
    ABSENCE OF ACTION= ATTRIBUTE IN <FORM> TAG CAUSES POST TO SAME URL
-->
<input type="hidden" name="MAX_FILE_SIZE" value="$max_file_size" />
Find a file to Upload ($f_exts): <input name="userfile" type="file" />
<br/>Check this box
<input autocomplete="off" type="checkbox" name="overwrite" /> to <strong>overwrite</strong> existing files
</br><input type="submit" value="Upload" />
</form>
</p>
EOF;

echo $form;

Open in new window

0
 

Author Closing Comment

by:sarath_nalla
ID: 40625535
Thank You so much for taking your time for me.. Im following your guidelines and making necessary changes to the upload script
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 40627191
Glad to help -- best of luck with it! ~Ray
0

Featured Post

How To Reduce Deployment Times With Pre-Baked AMIs

Even if we can't include all the files in the base image, we can sometimes include some of the larger files that we would otherwise have to download, and we can also sometimes remove the most time-consuming steps. This can help a lot with reducing deployment times.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Things That Drive Us Nuts Have you noticed the use of the reCaptcha feature at EE and other web sites?  It wants you to read and retype something that looks like this. Insanity!  It's not EE's fault - that's just the way reCaptcha works.  But it i…
This article discusses four methods for overlaying images in a container on a web page
Learn the basics of while and for loops in Python.  while loops are used for testing while, or until, a condition is met: The structure of a while loop is as follows:     while <condition>:         do something         repeate: The break statement m…
The viewer will learn how to count occurrences of each item in an array.

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question