代码审计 熊海cms V1.0

Posted r1card0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码审计 熊海cms V1.0相关的知识,希望对你有一定的参考价值。

菜鸡跟着前辈文章入门代码审计。

首先看一下这套cms的源代码目录分布

  • admin//管理员后台
  • css//css样式
  • files//功能函数
  • images//图片文件
  • inc//配置信息
  • install//安装目录文件
  • seacmseditor//seacms编辑器
  • template//模板文件
  • upload//文件上传
  • index.php//网站入口
  • 使用说明.txt//使用说明

漏洞总结

id 漏洞 修复
1 文件包含漏洞
2 越权漏洞,登录绕过
3 资料处存储型xss
4 登录处存在POST sql注入
5 前台的评论处存储型型xss
6 post注入
7 前台的一个报错get型sql注入
8 sql注入报错伴随的反射型xss

 

 

 

 

 

 

 

代码审计常见方法

  1. 通读全文代码
  2. 定向功能审计
  3. 敏感函数回溯

1、通读全文代码

第一个漏洞,文件包含漏洞

 

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

 

index.php里通过get方法接受一个r参数,然后用addslashes函数进行过滤,如果r的值为空则拼接包含files/index.php,若r参数非空,则包含files/$file.php

php官方手册针对addslashes函数给的例子,该函数会对单引号()、双引号(")、反斜线()与 NUL(NULL 字符)进行转义。

<?php
$str = "Is your name O‘reilly?";

// 输出: Is your name O‘reilly?
echo addslashes($str);
?>

所以,我们在url里面可以路径跳转,访问file目录之外的php文件,但是因为拼接了.php所以不能任意文件包含,例如包含1.txt是不可以的。

在根目录写一个phpinfo.php的文件,通过index包含访问

http://192.168.2.114/xscms/index.php?r=../phpinfo    #可以成功包含

文件包含漏洞修复,想法是白名单操作,将所有可能调用的都写在一个数组里面,然后封装成一个函数。

function protect($r){
    $key=0;
    $cars=array("about","contact","content","download","downloads","index","list","pages","software","submit");
    for ($i=0;$i<count($cars);$i++){
        if($r==$cars[$i])
            $key=1;
    }
    return $key;
}

源代码包含逻辑修改为

<?php
//单一入口模式
error_reporting(0); //关闭错误显示
$file=addslashes($_GET[‘r‘]); //接收文件名
$action=$file==‘‘?‘index‘:$file; //判断为空或者等于index
if (protect($action)==1){
    include(‘files/‘.$action.‘.php‘); //载入相应文件}else{
    echo "图图已修复";
}
?>

我们跟进代码的正常逻辑,不指定参数r的值,包含files/index.php

href="?r=content&cid=<?php echo $toutiaoimg[‘id‘]?>"

可以看到主业,很多文章的连接如上,包含content.php,跟进content.php文件

<?php 
require ‘inc/conn.php‘;
require ‘inc/time.class.php‘;
$query = "SELECT * FROM settings";
$resul = mysql_query($query) or die(‘SQL语句有误:‘.mysql_error());
$info = mysql_fetch_array($resul);

$id=addslashes($_GET[‘cid‘]);
$query = "SELECT * FROM content WHERE id=‘$id‘";
$resul = mysql_query($query) or die(‘SQL语句有误:‘.mysql_error());
$content = mysql_fetch_array($resul);

$navid=$content[‘navclass‘];
$query = "SELECT * FROM navclass WHERE id=‘$navid‘";
$resul = mysql_query($query) or die(‘SQL语句有误:‘.mysql_error());
$navs = mysql_fetch_array($resul);

//浏览计数
$query = "UPDATE content SET hit = hit+1 WHERE id=$id";
@mysql_query($query) or die(‘修改错误:‘.mysql_error());
?>
<?php
$query=mysql_query("select * FROM interaction WHERE (cid=‘$id‘ AND type=1 and xs=1)");
$pinglunzs = mysql_num_rows($query)
?>

第8行get传入id参数,仅仅使用addslashes函数进行过滤。第9行,第19行,直接带入id进行查询,典型的报错注入。

$id=addslashes($_GET[‘cid‘]);
$query = "SELECT * FROM content WHERE id=‘$id‘";
$query = "UPDATE content SET hit = hit+1 WHERE id=$id";

使用updatexml语句进行测试。

http://192.168.2.114/xscms/index.php?r=content&cid=1 and updatexml(1,concat(0x7e,(select @@version),0x7e),1)

继续跟进content.php,第154行,调用了submit.php对应前台的评论提交功能处。

<form  name="form" method="post" action="/?r=submit&type=comment&cid=<?php echo $id?>">

跟进submit.php,第6行,第66行

$mail=$_POST[‘mail‘];
$query = "SELECT * FROM interaction WHERE( mail = ‘$mail‘)";

直接通过POST方式传入mail参数,未经任何处理直接拼接SQL查询语句

第175行

if ($type==1){
$query = "SELECT * FROM content WHERE( id= $cid)";
$result = mysql_query($query) or die(‘SQL语句有误:‘.mysql_error());
$wz = mysql_fetch_array($result);
$title=$wz[‘title‘];

第121行

$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())";

mail处提交

‘and updatexml(1,concat(0x7e,(select concat(0x7e,version(),0x7e)),0x7e),1) ,‘$url‘,‘$touxiang‘,‘$shebei‘,‘$ip‘,‘$content‘,‘$tz‘,‘1‘)#

此时拼接的SQL语句

"INSERT INTO interaction (type,xs,cid,name,mail,url,touxiang,shebei,ip,content,tz,date) VALUES (‘$type‘,‘$xs‘,‘$cid‘,‘$name‘,‘‘ and updatexml(1,concat(0x7e,(select concat(0x7e,version(),0x7e)),0x7e),1) ,‘$url‘,‘$touxiang‘,‘$shebei‘,‘$ip‘,‘$content‘,‘$tz‘,‘1‘)#‘,‘$url‘,‘$touxiang‘,‘$shebei‘,‘$ip‘,‘$content‘,‘$tz‘,now())";

修复:使用mysqli_real_escape_string()函数对传入的参数进行过滤。

二、定向代码审计

以admin管理员相关功能为方向进行审计

首先定位到admin目录下的index.php,判断r是否传参,先默认跟进到admin/files/index.php文件

<?php
require ‘../inc/checklogin.php‘;
require ‘../inc/conn.php‘;
$indexopen=‘class="open"‘;
?>

包含,inc目录下的checklogin.php检查是否登录模块

跟进checklogin.php

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

仅仅只是简单的判断cookie是否有user,且user的值不为空,只要在cookie添加user字段,就很容易越权登录后台。

修复:

if(!defined(‘IN_SYS‘)) { 
exit(‘不好意思,越权已经被我干掉了~‘); 
}   #IN_SYS未定义

针对后台登录处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();
}
?>

在user和password没有进行过滤直接拼接SQL语句查询

开启报错

test‘ and updatexml(1,concat(0x7e,(select concat(0x7e,version(),0x7e)),0x7e),1) #

1‘ or updatexml(1,concat((select concat(0x7e,password,0x7e) from manage)),0) #

未开启报错,使用union联合查询绕过

‘ union select 1,2,3,md5(1),5,6,7,8#

密码为1

三、敏感函数回溯

根据敏感函数,来追踪函数使用传递的过程,逐一溯源进行分析。

在files/concat.php中的第12行

$page=addslashes($_GET[‘page‘]);
if ($page<>""){
if ($page<>1){
$pages="第".$page."页 - ";
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?php echo $navs[‘name‘]?> - <?php echo $pages.$info[‘name‘]?></title>

$page参数只是仅仅进行了特殊字符的转义,然后直接带入一下的html代码中,此处可以构造payloads直接进行反射性xss

修复使用htmlentities()函数进行修复

文章评论处的xss后面再补

 

以上是关于代码审计 熊海cms V1.0的主要内容,如果未能解决你的问题,请参考以下文章

代码审计系列:熊海CMS V1.0 (iseaCMS_1.0)

代码审计系列:熊海CMS V1.0 (iseaCMS_1.0)

php代码审计熊海cms1.0

熊海CMS 1.0代码审计漏洞集合

[代码审计]Bycms v1.0存储型XSS一枚#

熊海cms-文件包含漏洞