cmseasy绕过补丁SQL注入
在lib\plugins\pay\alipay.php中。
上次提了这个文件的洞。
看了看官网发的补丁。
foreach($_POST as $key =>$data) {
if(preg_match('/(=|<|>)/', $data)){
return false;
}
就是过滤了几个运算符。 但是因为语句是 where xxx。
一般的注入的话 需要where id=xxx 来注入 但是这里过滤了这些。 没想出什么办法突破。
但是在这文件 还有一个函数。
$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;
}
上次是看的changeorders 现在 反正我是没办法利用了。
那现在来看看check_money
public static function check_money($id,$money) {
$where=array();
$where['id']=$id;
$orders=orders::getInstance()->getrow($where);
$archive=archive::getInstance()->getrow($orders['aid']);
$prices = getPrices($archive['attr2']);
$archive['attr2'] = $prices['price'];
可以看到是把order_sn 带入了getrow; 再继续
function getrow($condition,$order='1 desc',$cols='*') {
$this->condition($condition);
return $this->rec_select_one($condition,'*',$order);
function sql_select($tbname,$where="",$limit=0,$fields="*",$order='') {
$sql="SELECT ".$fields." FROM `".$tbname."` ".($where ?" WHERE ".$where : "")." ORDER BY ".$order.($limit ?" limit ".$limit : "");
//echo $sql."<br>";
return $sql;
这里来把语句输出一下看看。
SELECT * FROM `cmseasy_p_orders` WHERE `id`='123aaaa'
被单引号了。 但是又全局转义 怎么办呢?
看 $order_sn = str_replace($_GET['subject'],'',$_GET['out_trade_no']);
$order_sn = trim($order_sn);
这里跟ecshop 那个洞挺像。
在这里 有一个replace 是xx把清空 但是这个xxx是我们可控的。
总所周知 %00 转义后会变成\0 然后%00' 就是\0\'
这里 如果我们把0清空 的话 就成了\\' 单引号成功出来。
测试测试。
执行的语句有点多。。 直接全部输出来了。
是成功的哦。
修复方案:
继续过滤。
版权与免责声明:
凡注明稿件来源的内容均为转载稿或由网友用户注册发布,本网转载出于传递更多信息的目的;如转载稿涉及版权问题,请作者联系我们,同时对于用户评论等信息,本网并不意味着赞同其观点或证实其内容的真实性;