phpspy2010 繞過登陸漏洞解析
??? phpspy2010可謂是webshell界很不錯的一個工具,但是phpspy2010 和2011相繼爆出了繞過認證漏洞,我簡單分析下php2010的繞過漏洞,首先據說只有php2010的加密版才有這個漏洞,我大概看了下官方解釋,估計也只有加密版才有這個問題,而且看上去應該是個失誤。。。
????? 下面具體分析:附件是2010的原始碼,由於是加密的eval執行base64解密,
把eval改成echo就可以輸出原始碼了。
代碼核心部分如下
$admin = array();// 是否要求輸入密碼驗證, true 為需要驗證, false 為直接進入.下面選項則無效$admin['check'] = true;// 如果要求輸入密碼驗證,請修改登陸密碼$admin['pass'] = 'f4f068e71e0d87bf0ad51e6214ab84e9'; //angel//如您對 cookie 作用範圍有特殊要求, 或登入不正常, 請修改下面變數, 否則請保持預設// cookie 首碼$admin['cookiepre'] = '';// cookie 範圍$admin['cookiedomain'] = '';// cookie 作用路徑$admin['cookiepath'] = '/';// cookie 有效期間$admin['cookielife'] = 86400;
error_reporting(7);@set_magic_quotes_runtime(0);ob_start();$mtime = explode(' ', microtime());$starttime = $mtime[1] + $mtime[0];define('SA_ROOT', str_replace('\\', '/', dirname(__FILE__)).'/');define('IS_WIN', DIRECTORY_SEPARATOR == '\\');define('IS_COM', class_exists('COM') ? 1 : 0 );define('IS_GPC', get_magic_quotes_gpc());$dis_func = get_cfg_var('disable_functions');define('IS_PHPINFO', (!eregi("phpinfo",$dis_func)) ? 1 : 0 );@set_time_limit(0);foreach(array('_GET','_POST') as $_request) {foreach($$_request as $_key => $_value) {if ($_key{0} != '_') {if (IS_GPC) {$_value = s_array($_value);}$$_key = $_value;}}}//???ò???÷???????????à??!$writabledb && $writabledb = 'php,cgi,pl,asp,inc,js,html,htm,jsp';$charsetdb = array('','armscii8','ascii','big5','binary','cp1250','cp1251','cp1256','cp1257','cp850','cp852','cp866','cp932','dec8','eucjpms','euckr','gb2312','gbk','geostd8','greek','hebrew','hp8','keybcs2','koi8r','koi8u','latin1','latin2','latin5','latin7','macce','macroman','sjis','swe7','tis620','ucs2','ujis','utf8');if ($charset == 'utf8') {header("content-Type: text/html; charset=utf-8");} elseif ($charset == 'big5') {header("content-Type: text/html; charset=big5");} elseif ($charset == 'gbk') {header("content-Type: text/html; charset=gbk");} elseif ($charset == 'latin1') {header("content-Type: text/html; charset=iso-8859-2");} elseif ($charset == 'euckr') {header("content-Type: text/html; charset=euc-kr");} elseif ($charset == 'eucjpms') {header("content-Type: text/html; charset=euc-jp");}$self = $_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];$timestamp = time();/*===================== ?í·??é?¤ =====================*/if ($action == "logout") {scookie('loginpass', '', -86400 * 365);p('');p('Success');exit;}if($admin['check']) {if ($doing == 'login') {if ($admin['pass'] == md5($password)) {scookie('loginpass', md5($password));p('');p('Success');exit;}}if ($_COOKIE['loginpass']) {if ($_COOKIE['loginpass'] != $admin['pass']) {loginpage();}} else {loginpage();}}
?
?
這個代碼以擁有兩個部分,第一個部分就是不加密的部分,這裡需要使用者填寫登入密碼,問題就發生在這裡,密碼存到了
admin['pass']中,而在第二部分解密出來的php代碼中,才接受了使用者傳遞過來的參數,這樣使用者可以自己構造md5加密後的admin['pass'],覆蓋掉第一部分定義好的,以及password,從而通過
?
if ($admin['pass'] == md5($password)) {scookie('loginpass', md5($password));p('');p('Success');exit;}
?就是修改後的傳遞參數
?注意admin['pass']是md5加密的。
?
?
?
2011據說也是類似的漏洞,但是我只找到了後來更新過的版本,這個版本中,定義pass的語句下移,放到了
?
foreach($_POST as $key => $value) {if (IS_GPC) {$value = s_array($value);}$$key = $value;}
?
的後面,從而修正了這個bug。