首先还是老地方:archive_act.php(611行)
$tmp1与$tmp[1]开发人员一时犯糊涂,没看清,导致无效过滤。而且这里get参数进行了重组,从$_SERVER["REQUEST_URI"]分割获取,多此一举,还导致之前的过滤全部无效,这边过滤又失效。
通过front::$get['code'] 可以控制需要加载的pay文件,
再看文件: alipay.php:
控制参数trade_status=WAIT_SELLER_SEND_GOODS, 进入pay::changeorders($order_sn,$_GET);
在这里 $id 就是之前$order_sn,可以直接由get参数控制。
进入这个方法:$update=orders::getInstance()->rec_update($where,$id);
这里程序员又犯糊涂了, rec_update的方法 where变量明显是第二个参数,传入的时候居然$where放到了第一个参数(这个程序员开了吧!),这样$id值就被当做sql语句的条件了。
好吧 开始绕waf:
首先是360的waf: 检测了好多危险函数,更可恶的全局过滤单引号,看到就杀。但是$order_sn 直接被带入到了where后面 根本不需要单引号,不起作用, 在之前的方法中有一个:
$order_sn = str_replace($_GET['subject'],'',$_GET['out_trade_no']);
这样利用替换功能,在危险函数中间都插入^, 再把subject设置成^,就可以成功绕过360waf。
接下来在sql语句执行的时候又有一个过滤器:
由于是update注入,又不能显示错误,sleep被过滤,只能用BENCHMARK。
又过滤了if,只能用or。
get参数又是从querystring中直接过去,空格会被替换成%20,所有只能用/**/替换:
最终的POC:(延时盲注法,稍微改动下)