### 简要描述: 过滤不严。 ### 详细说明: - - 又来绕过了。 官网上又更新了包。 看看是怎么来过滤的 lib\plugins\pay\alipay.php ``` function respond() { if (!empty($_POST)) { foreach($_POST as $key =>$data) { if(preg_match('/(=|<|>|\')/', $data)){ return false; } $_GET[$key] = $data; } } $payment = pay::get_payment($_GET['code']); $seller_email = rawurldecode($_GET['seller_email']); $order_sn = str_replace($_GET['subject'],'',$_GET['out_trade_no']); $order_sn = trim($order_sn); if (!pay::check_money($order_sn,$_GET['total_fee'])) { return false; } if($_GET['trade_status'] == "WAIT_SELLER_SEND_GOODS"||$_GET['trade_status'] == "TRADE_FINISHED" || $_GET['trade_status'] == "TRADE_SUCCESS") { pay::changeorders($order_sn,$_GET); return true; }else { return false; } } } ``` 可以看到 官方是在正则表达式那里做了修改。 添加了\' 因为全局转义 所以就不能用单引号了。 所以像上次那样绕过就不行了。 那就再来找找其他的突破口。 ``` public static function changeorders($id,$orderlog) { //file_put_contents('logs.txt', $id); $where=array(); $where['id']=$id; $where['status']=4;...
### 简要描述: 过滤不严。 ### 详细说明: - - 又来绕过了。 官网上又更新了包。 看看是怎么来过滤的 lib\plugins\pay\alipay.php ``` function respond() { if (!empty($_POST)) { foreach($_POST as $key =>$data) { if(preg_match('/(=|<|>|\')/', $data)){ return false; } $_GET[$key] = $data; } } $payment = pay::get_payment($_GET['code']); $seller_email = rawurldecode($_GET['seller_email']); $order_sn = str_replace($_GET['subject'],'',$_GET['out_trade_no']); $order_sn = trim($order_sn); if (!pay::check_money($order_sn,$_GET['total_fee'])) { return false; } if($_GET['trade_status'] == "WAIT_SELLER_SEND_GOODS"||$_GET['trade_status'] == "TRADE_FINISHED" || $_GET['trade_status'] == "TRADE_SUCCESS") { pay::changeorders($order_sn,$_GET); return true; }else { return false; } } } ``` 可以看到 官方是在正则表达式那里做了修改。 添加了\' 因为全局转义 所以就不能用单引号了。 所以像上次那样绕过就不行了。 那就再来找找其他的突破口。 ``` public static function changeorders($id,$orderlog) { //file_put_contents('logs.txt', $id); $where=array(); $where['id']=$id; $where['status']=4; //$where['orderlog']=serialize($orderlog); $update=orders::getInstance()->rec_update($where,$id); ``` ``` function rec_update($row,$where) { $tbname=$this->name; $sql=$this->sql_update($tbname,$row,$where); ``` ``` function sql_update($tbname,$row,$where) { $sqlud=''; if (is_string($row)) $sqlud=$row.' '; else foreach ($row as $key=>$value) { if (in_array($key,explode(',',$this->getcolslist()))) { $value=$value; if (preg_match('/^\[(.*)\]$/',$value,$match)) $sqlud .= "`$key`"."= ".$match[1].","; elseif ($value === "") $sqlud .= "`$key`= NULL, "; else $sqlud .= "`$key`"."= '".$value."',"; } } $sqlud=rtrim($sqlud); $sqlud=rtrim($sqlud,','); $this->condition($where); $sql="UPDATE `".$tbname."` SET ".$sqlud." WHERE ".$where; ``` 这里可以看到。 如果$where 不是数型的话 就没有单引号保护的。 这个有点不太符合我的常识啊。 不是一般数型的才不用单引号保护,字符串才用单引号保护的么? 不懂程序猿的世界。 但是这里$where 不太好利用 因为过滤掉了= < > 一般是利用where id=user() 之类的来注入 需要自己添加一个等号之类的 但是这里过滤掉了= < >。 再找找其他的突破口。 ``` foreach ($row as $key=>$value) { if (in_array($key,explode(',',$this->getcolslist()))) { $value=$value; if (preg_match('/^\[(.*)\]$/',$value,$match)) $sqlud .= "`$key`"."= ".$match[1].","; elseif ($value === "") $sqlud .= "`$key`= NULL, "; else $sqlud .= "`$key`"."= '".$value."',"; } } ``` 可以看到这里 遍历 然后赋值。 ``` else $sqlud .= "`$key`"."= '".$value."',"; ``` 这个被单引号保护了 无法利用。 但是这里有一个 ``` if (preg_match('/^\[(.*)\]$/',$value,$match)) $sqlud .= "`$key`"."= ".$match[1].","; ``` 这里是没有单引号保护的。 只要满足这个匹配 然后就可以无单引号啦。 哟西 好激动。 满足这个表达式后 他所执行的语句。 UPDATE `cmseasy_p_orders` SET `id`= 123,`status`= '4' WHERE [123] 但是过滤了= <> 我也没有什么好的注入办法。 我利用的是-号,然后用substr 一位一位的查询 然后对查询出来的结果 ascii 一次 然后再-掉一个数字。 例如 账户为admin substr 查询出来的第一位为a 然后ascii 后就为97. 然后这里就需要写一个脚本来跑了。 然后97-xx 只有当xx为97的时候 才不会延时 当为其他的数字的时候都会延时的。 Come on baby ### 漏洞证明: 我直接把语句输出来。 [<img src="https://images.seebug.org/upload/201403/15182922d5e31351a0cc4ccf3d94c7b27e6526cd.jpg" alt="5.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201403/15182922d5e31351a0cc4ccf3d94c7b27e6526cd.jpg) 注释掉后面的 相当于就是说 执行的就是 UPDATE `cmseasy_p_orders` SET `id`= if(ascii(substr((select username from cmseasy_user),1,1))-96,sleep(1),null) 我这substr查询出来的是a 然后ascii 后就为97 [<img src="https://images.seebug.org/upload/201403/151832023c793734e65f40e6736446d17d2023e5.jpg" alt="6.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201403/151832023c793734e65f40e6736446d17d2023e5.jpg) 可以看到的是 当剪掉的是正确数字的时候 是不会延时的。 但是减去其他任意数字的时候 都会延时的。 然后 把ascii转回来 就可以得到数据了。 这里需要写个脚本跑, 要不很慢啊。