### 简要描述: phpmps设计缺陷导致CSRF(全站功能通杀) ### 详细说明: phpmps防御xss和sql还是很好的,但是却忽略了csrf 请求没有token,没有验证referer。可以请求伪造。 所以是全站通杀! 还是给几个案例吧 案例1:修改管理员密码 ``` case 'repass': if(empty($_REQUEST[password]))show("请输入密码"); if(empty($_REQUEST[repassword]))$msg .= "请输入重复密码\n"; if($_REQUEST[password] <> $_REQUEST[repassword])show("两次输入的密码不一致"); $password = md5($_REQUEST[password]); $sql = "UPDATE {$table}admin SET password = '$password' WHERE userid = '$_SESSION[adminid]'"; $res = $db->query($sql); admin_log("$_SESSION[adminid]修改密码成功"); show('资料修改成功', 'admin.php'); break; ``` [<img src="https://images.seebug.org/upload/201502/0112030600c349d6446d24a89b0ad6253e0883cc.jpg" alt="360截图20150201115454295.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201502/0112030600c349d6446d24a89b0ad6253e0883cc.jpg) 案例2:刷钱 ``` case 'add': if($_POST['dosubmit']) { extract($_REQUEST); $amount = floatval($amount); $r = $db->getOne("SELECT userid,email,money FROM {$table}member WHERE...
### 简要描述: phpmps设计缺陷导致CSRF(全站功能通杀) ### 详细说明: phpmps防御xss和sql还是很好的,但是却忽略了csrf 请求没有token,没有验证referer。可以请求伪造。 所以是全站通杀! 还是给几个案例吧 案例1:修改管理员密码 ``` case 'repass': if(empty($_REQUEST[password]))show("请输入密码"); if(empty($_REQUEST[repassword]))$msg .= "请输入重复密码\n"; if($_REQUEST[password] <> $_REQUEST[repassword])show("两次输入的密码不一致"); $password = md5($_REQUEST[password]); $sql = "UPDATE {$table}admin SET password = '$password' WHERE userid = '$_SESSION[adminid]'"; $res = $db->query($sql); admin_log("$_SESSION[adminid]修改密码成功"); show('资料修改成功', 'admin.php'); break; ``` [<img src="https://images.seebug.org/upload/201502/0112030600c349d6446d24a89b0ad6253e0883cc.jpg" alt="360截图20150201115454295.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201502/0112030600c349d6446d24a89b0ad6253e0883cc.jpg) 案例2:刷钱 ``` case 'add': if($_POST['dosubmit']) { extract($_REQUEST); $amount = floatval($amount); $r = $db->getOne("SELECT userid,email,money FROM {$table}member WHERE username='$username'"); if(!$r) show('不存在此用户'); $balance = $r['money']; $value = 0; if($operation == '+') { $balance += $amount; } elseif($operation == '-') { $balance -= $amount; } $balance = round($balance, 2); $time = time(); $year = date('Y', $time); $month = date('m', $time); $date = date('Y-m-d', $time); $note = htmlspecialchars_deep($note); $note = cut_str($note, 200); if($operation == '+') { money_add($username, $amount, $note); } elseif($operation == '-') { money_diff($username, $amount, $note); } $url = 'pay.php?act=add'; show('操作成功', $url); ``` [<img src="https://images.seebug.org/upload/201502/011206334b610c665e7f769bc177c22b3458f864.jpg" alt="360截图20150201115454295.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201502/011206334b610c665e7f769bc177c22b3458f864.jpg) ------------------------------------- 由于全站都存在,我就不一一指出了 还有一个设计缺陷在这里提提 备份数据生成的文件名是 ``` $filename = date('Ymd').'_'.$random.'_'.$fileid.'.sql'; ``` 而$random是 ``` $random = mt_rand(1000, 9999); ``` 生成就是时间戳_从1000到9999的任意数字_加上操作者的id(通常都是1).sql 只需针对写个爆破脚本就可以看到了 **----- 还有一个提示,学dz,把下载数据备份的目录为不可访问,只有管理员才可以访问 ### 漏洞证明: phpmps防御xss和sql还是很好的,但是却忽略了csrf 请求没有token,没有验证referer。可以请求伪造。 所以是全站通杀! 还是给几个案例吧 案例1:修改管理员密码 ``` case 'repass': if(empty($_REQUEST[password]))show("请输入密码"); if(empty($_REQUEST[repassword]))$msg .= "请输入重复密码\n"; if($_REQUEST[password] <> $_REQUEST[repassword])show("两次输入的密码不一致"); $password = md5($_REQUEST[password]); $sql = "UPDATE {$table}admin SET password = '$password' WHERE userid = '$_SESSION[adminid]'"; $res = $db->query($sql); admin_log("$_SESSION[adminid]修改密码成功"); show('资料修改成功', 'admin.php'); break; ``` [<img src="https://images.seebug.org/upload/201502/0112030600c349d6446d24a89b0ad6253e0883cc.jpg" alt="360截图20150201115454295.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201502/0112030600c349d6446d24a89b0ad6253e0883cc.jpg) 案例2:刷钱 ``` case 'add': if($_POST['dosubmit']) { extract($_REQUEST); $amount = floatval($amount); $r = $db->getOne("SELECT userid,email,money FROM {$table}member WHERE username='$username'"); if(!$r) show('不存在此用户'); $balance = $r['money']; $value = 0; if($operation == '+') { $balance += $amount; } elseif($operation == '-') { $balance -= $amount; } $balance = round($balance, 2); $time = time(); $year = date('Y', $time); $month = date('m', $time); $date = date('Y-m-d', $time); $note = htmlspecialchars_deep($note); $note = cut_str($note, 200); if($operation == '+') { money_add($username, $amount, $note); } elseif($operation == '-') { money_diff($username, $amount, $note); } $url = 'pay.php?act=add'; show('操作成功', $url); ``` [<img src="https://images.seebug.org/upload/201502/011206334b610c665e7f769bc177c22b3458f864.jpg" alt="360截图20150201115454295.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201502/011206334b610c665e7f769bc177c22b3458f864.jpg) ------------------------------------- 由于全站都存在,我就不一一指出了 还有一个设计缺陷在这里提提 备份数据生成的文件名是 ``` $filename = date('Ymd').'_'.$random.'_'.$fileid.'.sql'; ``` 而$random是 ``` $random = mt_rand(1000, 9999); ``` 生成就是时间戳_从1000到9999的任意数字_加上操作者的id(通常都是1).sql 只需针对写个爆破脚本就可以看到了 **----- 还有一个提示,学dz,把下载数据备份的目录为不可访问,只有管理员才可以访问