2012-11-23: 细节已通知厂商并且等待厂商处理中 2012-11-28: 厂商已经主动忽略漏洞,细节向公众公开
躺在床上读代码之phpcms [0x01]
在phpcms/modules/formguide/index.php中的57行。
$formguide_input = new formguide_input($formid);$data = $formguide_input->get($_POST['info']);
这里调用了一个class,formguide_input,然后get函数处理了$_POST过来的info,那么,我们看看这个get函数
function get($data,$isimport = 0) { $this->data = $data; $info = array(); foreach($this->fields as $field) { …… 省略几行也不会死 $value = $data[$field['field']]; //在这里的value使用了data的值,data就是$_POST['info'] …… 省略几行也不会死 if($maxlength && $length > $maxlength) { if($isimport) { $value = str_cut($value,$maxlength,''); //value使用了str_cut截取了字节 } else { showmessage($name.' '.L('not_more_than').' '.$maxlength.L('characters')); } } elseif($maxlength) { $value = str_cut($value,$maxlength,''); //又一次截取 } 省略…… return $info;
str_cut函数是phpcms自定义的截取函数,第三个参数是控制dot是不是...,所以这里截取的时候当value是123\'的时候,如果截取字段是4的话,将截取出一个反斜线\出来。而后这部分的变量进入了insert在phpcms/modules/formguide/index.php中的63行。$dataid = $this->m_db->insert($data, true);导致了SQL注射漏洞以下为str_cut的代码
function str_cut($string, $length, $dot = '...') { $strlen = strlen($string); if($strlen <= $length) return $string; $string = str_replace(array(' ',' ', '&', '"', ''', '“', '”', '—', '<', '>', '·', '…'), array('∵',' ', '&', '"', "'", '“', '”', '—', '<', '>', '·', '…'), $string); $strcut = ''; if(strtolower(CHARSET) == 'utf-8') { $length = intval($length-strlen($dot)-$length/3); $n = $tn = $noc = 0; while($n < strlen($string)) { $t = ord($string[$n]); if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) { $tn = 1; $n++; $noc++; } elseif(194 <= $t && $t <= 223) { $tn = 2; $n += 2; $noc += 2; } elseif(224 <= $t && $t <= 239) { $tn = 3; $n += 3; $noc += 2; } elseif(240 <= $t && $t <= 247) { $tn = 4; $n += 4; $noc += 2; } elseif(248 <= $t && $t <= 251) { $tn = 5; $n += 5; $noc += 2; } elseif($t == 252 || $t == 253) { $tn = 6; $n += 6; $noc += 2; } else { $n++; } if($noc >= $length) { break; } } if($noc > $length) { $n -= $tn; } $strcut = substr($string, 0, $n); $strcut = str_replace(array('∵', '&', '"', "'", '“', '”', '—', '<', '>', '·', '…'), array(' ', '&', '"', ''', '“', '”', '—', '<', '>', '·', '…'), $strcut); } else { $dotlen = strlen($dot); $maxi = $length - $dotlen - 1; $current_str = ''; $search_arr = array('&',' ', '"', "'", '“', '”', '—', '<', '>', '·', '…','∵'); $replace_arr = array('&',' ', '"', ''', '“', '”', '—', '<', '>', '·', '…',' '); $search_flip = array_flip($search_arr); for ($i = 0; $i < $maxi; $i++) { $current_str = ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i]; if (in_array($current_str, $search_arr)) { $key = $search_flip[$current_str]; $current_str = str_replace($search_arr[$key], $replace_arr[$key], $current_str); } $strcut .= $current_str; } } return $strcut.$dot;}
我想证明一下,可是这个功能在我本地测试失败,该表不存在,但是漏洞步骤确实如上。
进入数据库的东西不能随意取消dot的。
危害等级:无影响厂商忽略
忽略时间:2012-11-28 14:01
暂无
好淫荡的名字
碉堡了。。。。
每天躺一次 一天一个呀
@快点啊!! 真应该叫躺哥
躺在床上对着代码撸???
@Enjoy_Hacking 这个说法NB