目录
  1. 1. 审计之初
  2. 2. 安装流程中存在SQL注入
  3. 3. 主目录存在文件包含
  4. 4. 前台多处SQL注入
    1. 4.1. software.php
    2. 4.2. content.php
    3. 4.3. submit.php
  5. 5. XSS
    1. 5.1. 反射型XSS
    2. 5.2. 存储型XSS
  6. 6. 越权
  7. 7. 后台万能密码登录
  8. 8. 说在后面
代码审计 | SEACMS_V1.0

审计之初

目录结构

├── admin       //后台文件
├── css //CSS文件
├── files //功能函数文件
├── images //图片
├── inc //配置文件
├── index.php //主目录文件
├── install //安装文件
├── seacmseditor //编辑器
├── template //模版文件
└── upload //文件上传目录

使用RIPS or Seay 扫描,本地采用 RIPS .查看是否具有明显漏洞存在

安装流程中存在SQL注入

漏洞位置 /install/index.php

RIPS审计出现 sql 注入,跟进文件比对审计结果

通读代码发现代码逻辑如下

  1. 检查是否生成了 InstallLock.txt
  2. 执行sql语句

审计源码发现这里sql语句确实没有经过过滤,直接插入 update 的 sql 语句中,导致 sql 注入

报错注入payload如下
1' and extractvalue(1, concat(0x7e, (select @@version),0x7e))#

PS:这个洞鸡肋地方在于需要进入到安装过程中,如果是已经安装完的CMS的话是不能够进入到安装过程中的。代码里具有一个 if(file_exists('InstallLock.txt')) 这样的判断,如果网站上存在一个任意文件删除漏洞,那么将形成攻击链
任意文件删除漏洞 —》删除 InstallLock.txt —〉 重新进入到网站安装流程 —》 sql注入

主目录存在文件包含

漏洞位置 /index.php

RIPS审计出现文件包含漏洞

跟进文件

<?php
//单一入口模式
error_reporting(0); //关闭错误显示
$file=addslashes($_GET['r']); //接收文件名
$action=$file==''?'index':$file; //判断为空或者等于index
include('files/'.$action.'.php'); //载入相应文件
?>

代码逻辑大概是,通过 GET 型传参传入 r,并将值经过一次 addslashes()函数操作。然后一个三元运算符判断了要载入的文件,直接进入include函数包含

语法为:条件表达式?表达式1:表达式2。
问号前面的位置是判断的条件,判断结果为bool型,为true时调用表达式1,为false时调用表达式2。

include('files/'.$action.'.php');这条语句包含了 file 目录下的文件

Bypass:可用 ../ 进行目录跳转

前台多处SQL注入

结合 RIPS 扫描结果可发现多处 sql 注入漏洞。该CMS采用过滤方式大多是通过addslashes()函数过滤

那么单纯用 addslashes()函数 有两个需要注意的问题

  1. 是否采用GBK(宽字节注入)
  2. sql语句是否采用了单引号闭合

software.php

漏洞位置 files/software.php 第13行,where后子句忘记加单引号保护。

$query = "UPDATE download SET hit = hit+1 WHERE id=$id";

content.php

漏洞位置 files/content.php 第19行,where后子句忘记加单引号保护。

$query = "UPDATE content SET hit = hit+1 WHERE id=$id";

submit.php

首先可看见 过滤和传参

$type=addslashes($_GET['type']);
$name=$_POST['name'];
$mail=$_POST['mail'];
$url=$_POST['url'];
$content=$_POST['content'];
$cid=$_POST['cid'];
$ip=$_SERVER["REMOTE_ADDR"];
$tz=$_POST['tz'];
if ($tz==""){$tz=0;}
$jz=$_POST['jz'];

只对 type 参数进行了过滤,因此其他参数涉及到sql语句的可能存在sql注入

  • 漏洞位置 files/submit.php 第66行
$query = "SELECT * FROM interaction WHERE( mail = '$mail')";
  • 漏洞位置 files/submit.php 第121-147行
$query = "INSERT INTO interaction (
type,
xs,
cid,
name,
mail,
url,
touxiang,
shebei,
ip,
content,
tz,
date
) VALUES (
'$type',
'$xs',
'$cid',
'$name',
'$mail',
'$url',
'$touxiang',
'$shebei',
'$ip',
'$content',
'$tz',
now()
)";
  • 漏洞位置 files/submit.php 第176行
$query = "SELECT * FROM content WHERE( id= $cid)";
  • 漏洞位置 files/submit.php 第206行
$query = "SELECT * FROM content WHERE( id= $cid)";

XSS

反射型XSS

漏洞位置 files/contact.php 第12-15行

$page=addslashes($_GET['page']);
if ($page<>""){
if ($page<>1){
$pages="第".$page."页 - ";

经过一次 addslashes()函数处理就直接带入页面

存储型XSS

漏洞位置:files/content.php

<div class="manageinfo">
<ul>
<div class="lou">回复 #<?php echo $pinglun['id']?> 楼</div>
<?php
$query2 = "SELECT * FROM manage";
$resul2 = mysql_query($query2) or die('SQL语句有误:'.mysql_error());
$manage2 = mysql_fetch_array($resul2);
if ($manage2['img']==""){
$touxiang="images/manage.jpg";
} else{
$touxiang=$manage2['img'];
}
?>
<img src="<?php echo $touxiang?>">
<strong><?php echo $manage2['name']?><span>认证站长</span></strong>
<li>位置:<a><?php echo $pinglun['rip']?></a></li>
<li>时间:<a><?php echo tranTime(strtotime($pinglun['rdate']))?></a></li>
<li>来自:<a><?php echo $pinglun['rshebei']?></a></li>
</ul>
</div>

这里是从 $pinglun 这个变量中取出其中的信息,随后插入存储信息的 interaction

/files/submit.php中将content内容给过滤,

$content= addslashes(strip_tags($content));//过滤HTML

在评论处可以提交昵称、邮箱、网址、评论内容,但是显示评论和留言的地方有昵称,所以只有昵称处有存储型XSS

越权

漏洞位置 inc/checklogin.php

<?php
$user=$_COOKIE['user'];
if ($user==""){
header("Location: ?r=login");
exit;
}
?>

该处的漏洞逻辑存在问题,直接从COOKIE处附值给 $user

如果 $user 为空就跳转至登录界面

反之如果不为空就可以访问,因此存在越权访问

后台万能密码登录

漏洞位置: admin/files/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();
}
?>

万能密码登录核心有两个点

  1. user未经过滤直接拼接进入数据库查询
  2. password 的 md5比对可绕过

payload如下

user: 1' union select 1,2,'p2hm1n','c4ca4238a0b923820dcc509a6f75849b',5,6,7,8#
password: 1

md5(1)=c4ca4238a0b923820dcc509a6f75849b

md5比对核心绕过原因:

说在后面

其实还有很多SQl注入,就没有一一跟进了

后台的漏洞也还有很多,但是由于都出现在后台。故没有进一步进行审计。

文章作者: P2hm1n
文章链接: http://yoursite.com/2019/12/23/代码审计-熊海CMS/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 P2hm1n‘s Blog

评论