=-=!本人属菜鸟级只能写基础文章 高手勿笑
想不到之前随意写了个文章那么多人欣赏
希望借此机会恳求论坛大牛们每个月花1小时不到的时间写一下文章 发表下感想 帮帮我们这些迷途小羔羊
还是那句 只发土司 禁止转载 纯属又长又臭 高手们没耐烦看的可以一笑而过
以下内容或许挖不到洞 但会说明如果这里代码会是怎么写 会存在如何 漏洞 (纯属个人经验........)
那么这次找个全面点的系统去研究 最终选择了一个叫野草CMS的程序 因为有后台 有会员 比较全面的网站系统
那么大家先看文章的文件结构
第一个compiles 顾名思义就是编制我们理解为缓存文件把 一般来说是不能直接运行的
第二个images 放图片的 基本来说这个目录是没有用的
第三个includes 放函数的 文件调用的函数都在这里找 这里非常有用 等同核心文件
第四个languages 语言文件 一般来说很难利用 除了包含漏洞(语言文件)或后台上传语言文件
第五个scripts 看名字就知道 是放JS的JS不能执行 或许能查看JS是否调用了另外他的网站 试试渗透
第六个styles 样式 完全可以忽略 没有任何利用
第七个templates 模版目录 如果设置了目录权限不能写PHP文件 一般来说可以覆盖这些模版文件执行
第八个uploads 就是上传文件 有上传漏洞的都往这里跑了。。。。。
然后到文件
admin.php 估计就是后台管理页面authcode.php 验证码(要发动CC攻击就往这个文件打把) 一般来说这个文件不会有漏洞
channel.php 列表频道什么的 都是输出用户看comment.php 评论 想当年DEDE死在这里
content.php 也是输出用户看的把feedback.php 留言板 最有可能注入的地方。。。。
index.php 首页。。。。没了可不行哦install.lock 安装文件member.php 会员 多数CMS死在这里
page.php 翻页。。。search.php搜索sitemap.php地图vote.php 投票
说明一下install.lock这个文件 在没安装之前是install.php 安装完毕后自动改名字了
如果有些CMS没有改名字 或许可以看下代码开头是否有if is_file .......xxx.php or XX.lock 判定是否有文件 然后结束
如果没有的话 可以进行2次安装直接控制 数据库 系统 不过这个几率很渺小。。。。。。。。
还是按照上一篇思路 先从后台下手把 后台最有权限嘛 呵呵
看下admin.php 开始代码
<?php
/**
一堆版权信息.....话说野草本人思想挺成熟 和他聊天过........
*/
require_once'includes/global.php'; //载入全局 这里一会才去看
require_once'languages/'.$config['site_language'].'/admin.php';
//选择语言 之前说了语言文件最有可能被包含漏洞 这里一会才看$config 是否能改变
$action =empty($_GET['action'])?'':trim($_GET['action']);
//没有过滤提交 如果换了其他系统可能存在包含漏洞
$do=empty($_GET['do'])?'':trim($_GET['do']);
//同上
if($action==''){
include'includes/admin_default.php';
exit;
}if($action=='start'){
include'includes/admin_start.php';
exit;
}if($action=='config'){
include'includes/admin_config.php';
exit;
}if($action=='content'){
include'includes/admin_content.php';
exit;
}if($action=='member'){
include'includes/admin_member.php';
exit;
}if($action=='other'){
include'includes/admin_other.php';
exit;}
//以上是判定ACTION是什么而执行什么行为了 所以action这个GET完全没有利用作用
//以下都是自定义函数 这里就省略了 需要的时候再贴出来
那么我们先看下后台任意一个行为开头
随便就admin_member.php把
<?php
//会员列表
if($do=='member_list'){
check_permissions('member_read');
//action所指的文件都有这个开头 那么关键就是check_permissions 验证权限
//在ADMIN.PHP 下面代码中找到了
function check_permissions($permissions){
check_login();
//验证权限之前就检测了登录
//看下登录
function check_login(){
if(empty($_SESSION['admin_id'])||$_SESSION['admin_id']<1){
message(array('text'=>$GLOBALS['language']['please_login'],'link'=>get_self()));}
//上一篇文章说了$_SESSION是保存在服务器内存 我们没可能去修改......
//到了这里被程序带进来了message 到了这里还有一丝希望 看下message
function message($message=array()){
$smarty=new smarty();
$smarty->template_dir =ROOT_PATH.'templates/admin';
$smarty->cache_dir =ROOT_PATH.'compiles';
$smarty->compile_dir =ROOT_PATH.'compiles';
$smarty->assign('language',$GLOBALS['language']);
$smarty->assign('config',$GLOBALS['config']);
$smarty->assign('message',$message);
$smarty->display('message.htm');
exit;
}
//前段是smarty载入模版 最后带了exit 所以这里是绝对性结束了
//如果最后不结束 只是跳转 或许可以试试关闭脚本方式去绕过
好 既然这里没戏 那么我们碰下运气 试试登录验证 说不定存在N年前的or 1=1.......
没有登录 我们被带到了admin_default.php
看下这个文件验证登录的地方
if($do=='login'){//我们输入帐号密码后 就被带到这里了
$admin_name=empty($_POST['admin_name'])?'':trim($_POST['admin_name']);
$admin_password=empty($_POST['admin_password'])?'':trim($_POST['admin_password']);
$admin_name=str_replace("#","",$admin_name);
$admin_name=str_replace("=","",$admin_name);
$admin_name=str_replace("'","",$admin_name);
$admin_name=str_replace("\"","",$admin_name);
$admin_name=str_replace("%","",$admin_name);
$admin_name=str_replace("and","",$admin_name);
$admin_name=str_replace("select","",$admin_name);
//很明显 作者想过滤用户名字注入 以上是替换函数 把这些东西都替换为空白
//但很不理智的做法 如果某个用户刚好把admin用户名改为 12andsb 那么他就永远不能登录了? 所以这里是编写的败笔
if(empty($admin_name)){
message(array('text'=>$language['admin_name_is_empty'],'link'=>''));
}
if(empty($admin_password)){
message(array('text'=>$language['admin_password_is_empty'],'link'=>''));
}
//很明显我们都不会不填帐号密码
$row=$db->getone("SELECT * FROM ".$db_prefix."admin WHERE admin_name='".$admin_name."' AND admin_password='".password($admin_password)."' ");
//这个查询既简单也完全没漏洞因为使用了单引号 如果你看到admin_name=".$admin_name."这样的话 就放心去注入把!
//password我看了一下是 return strtoupper(sha1(trim($string))); 话说 MD5 太多 作者幻想换其他不能爆破
if($row){
//如果帐号密码都有对了
if($row['admin_state']==0){
message(array('text'=>$language['admin_is_lock'],'link'=>''));
}
//上面估计就是管理员帐号有没有锁定把
$_SESSION['admin_id']=$row['admin_id'];
$_SESSION['admin_name']=$row['admin_name'];
$_SESSION['admin_permissions']=$row['admin_permissions'];
//以上是我们想要的 不过要不到 以下是我们不想要的 不过被程序带下去了
}else{
message(array('text'=>$language['login_is_failure'],'link'=>''));
}
admin_log('login','system',$_SESSION['admin_name']);
//上面记录登录记录由于$_SESSION['admin_name']都不可控制 所以不用去看了
clear_cache();
//clear_cache是情况缓存文件 由于连帐号密码都碰不上 所以这里不会运行
message(array('text'=>$language['login_is_success'],'link'=>'?action=start'));
}
来到这里基本很肯定地告诉你 后台没希望
唯一有希望的就是把所有action动作的文件全看一次 看作者有没有漏写check_login()或者check_permissions
但作为一个充满激情的人 我们是不会放弃任何一个可能性
require_once'includes/global.php'; //载入全局 这里一会才去看
上面开始文章说了一会才看 或许还有希望
思路引导我们进了global.php
error_reporting(0);
//上面函数对我们暴错方式有很大的贡献 可以死心了
if(file_exists("install.php"))@header("location:install.php");
// 如果没有安装文件。。。 我都去安装了........
@session_start();
@header("content-type:text/html;charset=utf-8");
if(ereg('gzip',$_SERVER['HTTP_ACCEPT_ENCODING']))@ob_start("ob_gzhandler");
//以上是编码
if(version_compare( PHP _VERSION,'5.0.0','<')){
exit('PHP>5.0.0');
}//这里只是验证PHP版本 一般现在都是5以上
@set_magic_quotes_runtime(0);//过滤数据库写入.关闭了
if(@get_magic_quotes_gpc()){
function rs($s){
if(is_array($s)){
foreach ($s as $k=>$v)$s[$k]=rs($v);
}else{
$s=stripslashes($s);
}
return $s;
}
$_GET=rs($_GET);$_POST=rs($_POST);$_COOKIE=rs($_COOKIE);
//姨? 以上举动很神奇 这里等同关闭魔术引导 就是输入' 不会变成/' 不知道作者用意何在
}
//然后代码是2段encode 加密 解密的 这里就不贴了 暂时用不上
require_once(ROOT_PATH.'includes/config.php'); //数据库帐号密码地址....
require_once(ROOT_PATH.'includes/function.php'); //自定义函数 用的时候再来这里找
require_once(ROOT_PATH.'includes/share.php'); //同上
require_once(ROOT_PATH.'includes/class_db.php'); //连接数据库的
require_once(ROOT_PATH.'includes/class_smarty.php'); //搞模版的
$db=new db($db_host,$db_user,$db_password,$db_name);
$config=load_config();
//翻了下这个函数
function load_config(){
$config_temp=array();
$row=$GLOBALS['db']->getone("SELECT config_value FROM ".$GLOBALS['db_prefix']."config WHERE config_type='config'");
$config_temp=unserialize(base64_decode($row['config_value']));
return $config_temp;
}
//配置在数据库里 看来之前说的包含语言文件漏洞不会有戏了
$language=array();
@date_default_timezone_set('PRC');//时间
游荡完一圈回来 可以肯定地告诉我们 后门芝麻开门不开门了
然后我们死不到最后不死心的激进份子 跑到前台去看了
admin.php 可以放弃
别人说的名言 一切输入的数据都是有害的 那么我们就尽量找这个可能
member.php 会员系统 与用户交换度最高的东西
require_once('includes/global.php');//研究过了
require_once(ROOT_PATH.'languages/'.$config['site_language'].'/front.php'); //不可控制
require_once('includes/front.php');//前台的函数 需要才跑来这里看
if($config['member_state']=='no'){ //如果会员系统关闭了 你就可以放弃下面了 话说他怎么不写=off 而是=on .....
message(array('text'=>$language['member_sysytem_is_close'],'link'=>'./'));
}
$action=isset($_GET['action'])?$_GET['action']:'';//没有过滤
//AJAX检查会员邮件地址
if($action=='check_member_mail'){
check_request();
//我们看下check_request
function check_request(){
if(empty($_SERVER['HTTP_REFERER'])||(preg_replace("/https?:\/\/([^\:\/]+).*/i","\\1",$_SERVER['HTTP_REFERER'])!=preg_replace("/([^\:]+).*/", "\\1",$_SERVER['HTTP_HOST']))){
exit('Access Denied!');
}
//很明显这里只是检测是否外部提交(防止批量?) 这里可以自己编写提交 简单绕过
$member_mail=empty($_GET['member_mail'])?'':trim($_GET['member_mail']);
if(!is_email($member_mail)){
echo('1');
exit;
//is_email就不贴了 就是不是[email]xxxxxx@xxxx测试数据[/email] 格式就XX你
}
$count=$db->getcount("SELECT * FROM ".$db_prefix."member WHERE member_mail='".$member_mail."'"); //单引号 飘过
if($count>0){
echo('1');
}else{
echo('0');
}
exit;
}
//AJAX检查会员昵称
if($action=='check_member_nickname'){
check_request();//同上
$member_nickname=empty($_GET['member_nickname'])?'':trim($_GET['member_nickname']);
$count=$db->getcount("SELECT * FROM ".$db_prefix."member WHERE member_nickname='".$member_nickname."'");
//单引号 飘过
if($count>0){
echo('1');
}else{
echo('0');
}
exit;
//这里产生了一个比较简单的BUG 就是暴力爆破的话 简单了很多..速度也会快很多
}
//AJAX导出登陆界面
if($action=='login'){
check_request();
$smarty=new smarty();smarty_header();
$smarty->display('ajax_member_login. html ');
}//没东西给你操作
if($action=='login_ok'){
//到登录会员验证
check_request();//这里同上
$member_mail=empty($_GET['member_mail'])?'':trim(addslashes($_GET['member_mail']));
$member_password=empty($_GET['member_password'])?'':password($_GET['member_password']);
if(empty($member_mail)){
exit('error:mail_is_empty');
}
if(!is_email($member_mail)){
exit('error:mail_is_error');
}
if(empty($member_password)){
exit('error:password_is_empty');
}
//登录是以EMAILL的呢.
$row=$db->getone("SELECT * FROM ".$db_prefix."member WHERE member_mail='".$member_mail."' and member_password='".$member_password."'");
//单单单引号
if($row){
//这里我们总算能进来一次了.......
if($row['member_validation']==0){
exit('error:account_is_not_activate');
}
if($row['member_state']==0){
exit('error:account_is_lock');
}
$_SESSION['member_id']=$row['member_id'];
$_SESSION['member_mail']=$row['member_mail'];
$_SESSION['member_nickname']=$row['member_nickname'];
$_SESSION['member_photo']=$row['member_photo'];
$_SESSION['group_id']=$row['group_id'];
$update=array();
$update['member_last_time']=time();
$update['member_last_ip']=get_ip(); //注意一下获取IP方法 我们看下get_ip
function get_ip(){
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}elseif (isset($_SERVER['HTTP_CLIENT_IP'])){
$ip=$_SERVER['HTTP_CLIENT_IP'];
}else{
$ip=$_SERVER['REMOTE_ADDR'];
}
if(check_ip($ip)){
return $ip;
}else{
return '0.0.0.0';
}
//以上是国际问题
//关键还得要看check_ip
function check_ip($ip){
$oct = explode('.', $ip);
if (count($oct) != 4) {
return false;
//哎呀IP面有3个小点就可以绕过
}
for ($i = 0; $i < 4; $i++) {
if (!is_numeric($oct[$i])) {
return false;
//这里搞错了 想快了 其实应该不能绕过 多谢阿里巴巴老板提醒
}
if ($oct[$i] < 0 || $oct[$i] > 255){
return false;
//没有小点或者 大于255个
}
}
return true;
} $db->update($db_prefix."member",$update,"member_mail='".$member_mail."'");
//。。。。。
function update($table,$values,$where='',$debug=false){
$v='';
foreach($values as $key => $value){
$v.=$v?",`$key`='$value'":"`$key`='$value'";
}
$sql="update `$table` set $v where $where";
if($debug)return $sql;
return $this->query($sql);
}//。没悬念
clear_cache();//清理缓存
}else{
exit('error:login_failed');
}
只可惜admin后台用户不和放在会员表里 不然找机会修改会员权限进后台!
然后程序进行到了注册用户
if($action=='register_ok'){
check_request();//同上
$member_mail=empty($_GET['member_mail'])?'':trim(addslashes($_GET['member_mail']));
$member_password=empty($_GET['member_password'])?'':trim(addslashes($_GET['member_password']));
$member_password_confirm=empty($_GET['member_password_confirm'])?'':trim(addslashes($_GET['member_password_confirm']));
$member_safecode=empty($_GET['member_safecode'])?'':trim(addslashes($_GET['member_safecode']));
$member_nickname=empty($_GET['member_nickname'])?'':trim(addslashes($_GET['member_nickname']));
$member_state=empty($_GET['member_state'])?0:intval($_GET['member_state']);
//一些简单的过滤
if(empty($member_mail)){
exit('error:mail_is_empty');
}
if(!is_email($member_mail)){
exit('error:mail_is_error');
}
$count=$db->getcount("SELECT * FROM ".$db_prefix."member WHERE member_mail='".$member_mail."'");
if($count>0){
exit('error:mail_is_occupy');
}//EMALL不给你重复 单引号 没有注入
if(empty($member_password)){
exit('error:password_is_empty');
}
//省掉几个如果为空........
$count=$db->getcount("SELECT * FROM ".$db_prefix."member WHERE member_nickname='".$member_nickname."'");
if($count>0){
exit('error:nickname_is_occupy');
} //名字也不能重复哦
$insert=array();
$insert['member_mail']=$member_mail;
$insert['member_password']=password($member_password);
$insert['member_safecode']=password($member_safecode);
$insert['member_nickname']=$member_nickname;
$insert['member_name']='';
$insert['member_sex']=0;
$insert['member_birthday']=0;
$insert['member_phone']='';
$insert['member_photo']='';
$insert['member_from']='';
$insert['member_other']='';
if($config['member_validation_state']=='yes'){
$key=md5($member_mail.$member_password);
$insert['member_validation']=0;
$insert['member_validation_key']=$key;
//这KEY估计是找回密码用的把
}else{
$insert['member_validation']=1;
$insert['member_validation_key']='';
}
$insert['member_state']=1;
$insert['group_id']=0;
$insert['member_join_time']=$_SERVER['REQUEST_TIME'];
$insert['member_last_time']=$_SERVER['REQUEST_TIME'];
$insert['member_last_ip']=get_ip();//这里同上
$db->insert($db_prefix."member",$insert);//加进去
clear_cache();
if($config['member_validation_state']=='yes'){ //要邮箱验证才发个邮件
send_mail($member_mail,$config['smtp_user'],'Please activate the account!','<a href="'.get_position().'member.php?action=member_validation&key='.$key.'">Click!</a>');
}else{
$_SESSION['member_id']=$db->insert_id();
$_SESSION['member_mail']=$member_mail;
$_SESSION['member_nickname']=$member_nickname;
$_SESSION['group_id']=0;
}
}
开始感到鸭梨了..........
注册和登录都不能干大件事 那么我们看下会员有什么功能
3大功能 先从修改信息开刀
姨 我们看到了什么
这就像沙漠中的水一样 我们看到了可能的希望 于是赶紧跑去看修改会员的代码
if($action=='edit_member_ok'){
//这里省一段 是否登录呀 有没有填写好资料呀 之类的验证 没什么用不用看
//关键到了$member_photo=upload($_FILES['member_photo'],false); 我们看upload
function upload($upload,$mode=false,$ext='jpg,gif,png'){
$array=array();
foreach ($upload["error"] as $key=>$error){
$check_type=check_type($upload['tmp_name'][$key], $upload['name'][$key],$ext);
//检查后缀 重要! 我们看下check_type
function check_type($filename, $realname = '', $limit_ext_types = '')//第3个$ext为jpg,gif,png
if ($realname){
$extname = strtolower(substr($realname, strrpos($realname, '.') + 1));
}else{
$extname = strtolower(substr($filename, strrpos($filename, '.') + 1));
}
//获取后缀的方法很多 很明显这里犯了一个很严重的错误!
//如果文件名字为2222.php 那么将会获取到PHP 如果文件名字为sphp 没有小数点(意思就是没后缀) 那么结果将会也是PHP
//再举例 如果文件名字为123.jpg.php 也是获取到php 如果是awphp将会是wphp 如果是wphp 将是php 就是没有小数点 就获取第2个开始
if (@stristr($limit_ext_types,(string)$extname) === false){
return '';//这里限制了后缀只能是jpg,gif,png
//下面代码是判定文件类型输出结果 没用不看
//我们回归upload这里把 下面开始
if(!empty($check_type)){ //嗯嗯 有的 不过是没后缀的
if (!empty($upload['name'][$key])&&$upload['size'][$key]<2*1024*1024){ //有名字并文件大小不大于某个数值
$get_ext=get_ext($upload['name'][$key]);
//看下这个get_ext
function get_ext($filename){
if(!empty($filename)){
return end(explode(".",strtolower($filename)));
}
//这个获取方式就绝对不出问题了 。。 话说作者怎么这么飘忽。。。。
if(check_ext($get_ext,$ext)){
$name = date('YmdHis');
$name.="_";
for ($i = 0; $i < 6; $i++){
$name .= chr(mt_rand(97, 122));
}
$name .=".".$get_ext;//时间+随机数字命名方式加后缀
if (upload_move_file($upload['tmp_name'][$key],ROOT_PATH.'/uploads/'.$name)){
//upload_move_file就是move_uploaded_file和建立目录
$array[]=$name;
}
//看来上传漏洞是不存在的.....只能给你上传个没后缀的4位字母文件.......... -0-!
//思路回到了修改会员信息这里
$update=array();
if(!empty($member_password)){
$update['member_password']=password($member_password);
}
$update['member_name']=$member_name;
$update['member_sex']=$member_sex;
$update['member_birthday']=$member_birthday;
$update['member_phone']=$member_phone;
if(!empty($member_photo)){//member_photo=$_POST member_photo
if($member_photo_old!=$_SESSION['member_photo']){
//这里可以通过上面update的获取IP 注入修改绕过
exit('Access Denied!');
}
$member_photo_old=str_replace('..','',$member_photo_old); //WIN下你想返回上一级呀?被替换了
@unlink(ROOT_PATH."/uploads/".$member_photo_old);//很可惜这里如果没有加入uploads 可以删除任意文件漏洞!
//受限于/ 中的..被替换为空 所以WIN下无此漏洞 其他 系统 自己思考
$update['member_photo']=$member_photo;
$_SESSION['member_photo']=$member_photo;
if($config['image_thumb_open']=='yes'){
make_thumb(ROOT_PATH.'/uploads/'.$member_photo,100,100);
//估计是裁剪文件把..........
}
}
if(!empty($member_photo_delete)){
if($member_photo_delete!=$_SESSION['member_photo']){
exit('Access Denied!');
}
$member_photo_delete=str_replace('..','',$member_photo_delete);
@unlink(ROOT_PATH."/uploads/".$member_photo_delete);
$update['member_photo']='';
$_SESSION['member_photo']='';
} //这里同上 估计是不要了头像用的
$update['member_from']=$member_from;
$update['member_other']=$member_other;
$db->update($db_prefix."member",$update,"member_id=$member_id");
//姨? 最后这里发现了一个小漏洞 引用上面省掉代码$member_id=empty($_POST['member_id'])?0:intval($_POST['member_id']);
//以这里计算 可以产生任意修改任何会员账户信息漏洞了!
//作者应该是memberid= $_SESSION['member_id'] 这样才正确!
clear_cache();
message(array('text'=>$language['member_update_success'],'link'=>'index.php'));
}
思路来到这里 修改会员基本可以说放弃了
剩下的我的评论和我的帖子都是读取数据库 看了下没什么用处 这里就不分析了
我们坚持这个原则--------任何输入数据都是有害的!
所以我们跑去看评论和留言板把
先是评论comment.php
require_once('includes/global.php');
require_once(ROOT_PATH.'languages/'.$config['site_language'].'/front.php');
require_once('includes/front.php');
$action=isset($_GET['action'])?$_GET['action']:'';
if($action=='content_comment_content'){
$comment_id=empty($_GET['comment_id'])?'':intval($_GET['comment_id']);//强制为整数型
$row=$db->getone("SELECT comment_content FROM ".$db_prefix."content_comment WHERE comment_id=$comment_id");
//如果没有了强制限制为整数型 这么这里将是一个大大的注入点。。。。
echo($row['comment_content']);
exit;
}
//然后一段检查评论内容有没有非法和过滤的东西
//关键代码 $insert['comment_ip']=get_ip();
//到了下面
$db->insert($db_prefix."content_comment",$insert);
$db->query("UPDATE ".$db_prefix."content SET content_comment_count=content_comment_count+1 WHERE content_id='".$content_id."'");
//插入评论没悬念 就是记录IP那里........
然后很神奇的看到一个东西
删除评论
if($action=='content_comment_delete'){
check_request();
$content_id=empty($_GET['content_id'])?0:intval($_GET['content_id']);
$comment_id=empty($_GET['comment_id'])?0:intval($_GET['comment_id']);
$children_count=$db->getcount("SELECT * FROM ".$db_prefix."comment WHERE parent_id=$comment_id");
$db->delete($db_prefix."content_comment","comment_id=$comment_id");
$db->delete($db_prefix."content_comment","parent_id=$comment_id");
$count=$children_count+1;
$db->query("UPDATE ".$db_prefix."content SET content_comment_count=content_comment_count-".$count." WHERE content_id='".$content_id."'");
clear_cache();
} //估计模版是输出只有发表的人才可以删除 但没想到用户自己去搞
//这一小漏洞就是可以删除任何评论........
评论终结 到留言板feedback.php
这留言板代码不贴了 看了一下和评论代码一模一样 所以这里不分析了
就是只有提交代码 没少了删除那个漏洞 哈哈
迷惘了 输入有害都变没害了...
page.php 只有查询sitemap.php 一样也只是查询输出
投票vote.php就是update SET item_count=item_count+1 也没注入
search.php搜索也没有什么悬念
index.php不用说了 都是查询 输出
到此基本能给用户操作的都分析过了
由于评论和留言本都用了addslashes处理XSS不行了
但能利用修改会员注入功能 修改名字或者其他信息插入XSS攻击 期待管理员查询 最后希望了!
分析结束 后台就不分析了 前台你都不能进 想后台干什么呢 社工吗?
不知不觉到2点多了 原来写了2个小时了 真累 睡觉......
以下是转载:http://HdhCmsTestt00ls.net/thread-19989-1-1.html
查看更多关于PHP详细分析代码挖掘漏洞 - 网站安全 - 自学php的详细内容...