一个老大哥发的代码审计 自己跟着他的思路走了一遍 最后自己总结了下 cms就不发了 大家可以看看过程吧
/other/codepay_notify.php 存在SQL注入
<?php
define('SYSTEM_ROOT_E', dirname(__FILE__) . '/');
include '../ayangw/common.php'; // 包含一个文件
ksort($_POST); //排序post参数
reset($_POST); //内部指针指向数组中的第一个元素
$sign = '';
var_dump($conf);
foreach ($_POST AS $key => $val) {
if ($val == '') continue;
if ($key != 'sign') {
if ($sign != '') {
$sign .= "&"; //拼接&
$urls .= "&"; //拼接&
}
$sign .= "$key=$val"; //拼接为url参数形式
$urls .= "$key=" . urlencode($val); //拼接为url参数形式
}
}
if (!$_POST['pay_no'] || md5($sign . $conf['epay_key']) != $_POST['sign']) { //不合法的数据 KEY密钥为你的密钥
exit('fail | pay_no:'.$_POST['pay_no']."|sign:".$_POST['sign']."|md5:".md5($sign . $conf['epay_key']));//直接exit
} else { //合法的数据
$md5_trade_no = $_POST['param'];
$sql = "SELECT * FROM ayangw_order WHERE md5_trade_no='{$md5_trade_no}' limit 1";//没有过滤 可以直接sql注入
echo '<hr />';
echo $sql;
echo '<hr />';
$row = $DB->get_row($sql);
if($row['sta'] != 0){
wsyslog("mcallbackprocess,订单已被处理,","状态:(".$row['sta']."):".$md5_trade_no);
exit('success');
}
if(mmcallbackprocess()){ // 这里的回显只有success 和fail 所以只能进行盲注
exit('success');
}else{
exit('fail');
}
}
解释
可以看出如果我们让的md5($sign . $conf['epay_key']) != $_POST['sign'])
这里可以成立的话 那么久可以直接进去合法数据的语句里面然后可以进行盲注 ,但是我们发现$conf['epay_key']
这个参数不知道 怎么办呢? 但是我们打印的时候这个cms默认的时候不是存在$conf['epay_key']
,然后继续观察看下exit('fail | pay_no:'.$_POST['pay_no']."|sign:".$_POST['sign']."|md5:".md5($sign . $conf['epay_key']));
这里exit的时候发现会直接显示出md5($sign . $conf['epay_key'])
的值 那么我们到时候先填写好自己的注入语句然后再改成POST$sign
的md5值就可以进行注入了
总结
1.细心观察 每个变量的由来和未知变量的值是否存在