致远OA未授权漏洞复现和简单分析
2021-01-10 15:04:44 Author: forum.90sec.com(查看原文) 阅读量:2691 收藏

最近几天这个漏洞诈尸了。全是通告阿里云

555

奇安信

666

你说你们复现就复现吧。还全部马赛克让我等小菜如何学习进步。
我来一张高清无码的进行复现。

致远

新漏洞出来不要吝啬分享。毕竟都能防御了。留图不留种菊花万人捅。
未授权漏洞可以利用url
位置
D:\Seeyon\A8\ApacheJetspeed\webapps\seeyon\WEB-INF\cfgHome\base/systemProperties.xml

 <not_need_logon>
            <navurl>/main.do</navurl>
            <navurl>/main.do?method=changeLocale</navurl>
            <navurl>^/main.do?method=login</navurl>
            <navurl>^/main.do?method=headerjs</navurl>
            <navurl>/main.do?method=main</navurl>
            <navurl>/main.do?method=showAbout</navurl>
            <navurl>^/main.do?method=logout</navurl>
            <navurl>^/genericController.do</navurl>
            <navurl>^/autoinstall.do</navurl>
            <navurl>^/identification.do?method=getSessionId</navurl>
            <navurl>^/thirdpartyController.do</navurl>
            <navurl>^/form/formUpgrade.do</navurl>
            <navurl>^/uploadService.do?method=processUploadService</navurl>
            <navurl>^/a8genius.do~session=false</navurl>
            <navurl>^/uc/chat.do~session=false</navurl>
            <navurl>^/fileUpload.do?method=showRTE~session=false</navurl>
            <navurl>^/commonimage.do?method=showImage</navurl>
			<navurl>mProfileManager.getProfile</navurl> 
			<navurl>mLoginManager.transLogin</navurl> 
			<navurl>mMessageManager.getPushMessageList</navurl>  
			<navurl>mBindApplyManager.bindApplyByUser</navurl> 
			<navurl>mProductManager.productStatus</navurl>
			<navurl>mProductManager.productInfo</navurl>
			<navurl>mMOneProfileManager.getUpdateServerInfo</navurl>
			<navurl>mMOneProfileManager.getOAProfile</navurl>
			<navurl>mMessageManager.getConfig</navurl>
			<navurl>portalManager.smsLoginEnabled</navurl>
			<navurl>portalManager.sendSMSLoginCode</navurl>
			<navurl>weixinLoginManager.isLogin</navurl>			
			<navurl>^/seeyonReport/checkReportController.do</navurl>
			<navurl>^/personalBind.do</navurl>
			<navurl>/individualManager.do?method=resetPasswordNologin</navurl>
			<navurl>configManager.getConfigValue</navurl>
        </not_need_logon>
/main.do
/main.do?method=changeLocale
/main.do?method=login
/main.do?method=headerjs
/main.do?method=main
/main.do?method=showAbout
/main.do?method=logout
/genericController.do
/autoinstall.do
/identification.do?method=getSessionId
/thirdpartyController.do
/form/formUpgrade.do
/uploadService.do?method=processUploadService
/a8genius.do~session=false
/uc/chat.do~session=false
/fileUpload.do?method=showRTE~session=false
/commonimage.do?method=showImage
mProfileManager.getProfile
mLoginManager.transLogin
mMessageManager.getPushMessageList
mBindApplyManager.bindApplyByUser
mProductManager.productStatus
mProductManager.productInfo
mMOneProfileManager.getUpdateServerInfo
mMOneProfileManager.getOAProfile
mMessageManager.getConfig
portalManager.smsLoginEnabled
portalManager.sendSMSLoginCode
weixinLoginManager.isLogin
/seeyonReport/checkReportController.do
/personalBind.do
/individualManager.do?method=resetPasswordNologin
configManager.getConfigValue

其中上面 mProductManager.productStatus 的这些是用来限制ajax.do请求不需要登陆。能请求类型和方法。用来限制ajax.do未登录的访问。当然如果采用上面方式绕过那么就可以通过ajax.do访问任意相关联的方法。解释下几张图:

5

6

7

漏洞代码

private String getUri(HttpServletRequest request) throws BusinessException {String uri = request.getRequestURI();if (uri.matches(".*?/{2,}.*?"))throw new BusinessException("url格式错误有超过2个以上的'/'" + uri);int idx = uri.indexOf(';');uri = uri.substring(request.getContextPath().length(), (idx == -1) ? uri.length() : idx);return uri;}

boolean isAjax = "/ajax.do".equals(uri);  获取请求的url是是否是ajax.do

if (isAjax) { 如果是那么
String serviceName = request.getParameter("managerName");
String methodName = request.getParameter("managerMethod");
if (methodName != null)
validateUserRole(PerfmonMisc.getAopProxySaneName(AppContext.getBean(serviceName)), methodName, user);
ignoreUrl = serviceName + "." + methodName;  //拼接组成 ignoreUrl
}

boolean needlessUrl = false;
if (user == null) {  //由于没有登录那么user为空
    AppContext.removeThreadContext("SESSION_CONTEXT_USERINFO_KEY");
    String methodName = method;
    if (isAjax) {  //如果请求中有ajax.do 那么获取方法
        methodName = request.getParameter("managerMethod");
    if (methodName == null)
        methodName = method;
    }
    needlessUrl = isNeedlessLoginUrl(request, methodName, needlessUrl); //是否包含指定的methodName 这个关系不大
}

if (!needlessUrl) //
    if (!CTPSecurityManager.isIgnoreUrl(ignoreUrl, request, response)) { //那么在检测是否是忽略的url 如果是CTPSecurityManager.isIgnoreUrl(ignoreUrl, request, response)=true 是忽略的url  关键点跳过验证

 如果是ajax请求那么ignoreUrl 只能是 mProfileManager  getProfile   限制ajax访问类。
  <navurl>mProfileManager.getProfile</navurl>
            <navurl>mLoginManager.transLogin</navurl>
            <navurl>mMessageManager.getPushMessageList</navurl>  
            <navurl>mBindApplyManager.bindApplyByUser</navurl>
            <navurl>mProductManager.productStatus</navurl>
            <navurl>mProductManager.productInfo</navurl>
            <navurl>mMOneProfileManager.getUpdateServerInfo</navurl>
            <navurl>mMOneProfileManager.getOAProfile</navurl>
            <navurl>mMessageManager.getConfig</navurl>
            <navurl>portalManager.smsLoginEnabled</navurl>
            <navurl>portalManager.sendSMSLoginCode</navurl>
            <navurl>weixinLoginManager.isLogin</navurl> 
        boolean state = checkSessionPre(request, response, handler.getClass().getCanonicalName(), isAjax);
        if (!state)
        return state;
        validateUserRole(clazzName, method, user);
    }
initJsonParams(request);

public static boolean isIgnoreUrl(String navurl, HttpServletRequest request, HttpServletResponse response) {
boolean result = ignoredUrl.contains(navurl), inited = false;
if (!result)
for (String url : ignoredUrl) {
Map<String, String> configMap = new HashMap<String, String>();
int idx = url.indexOf('~');
int idxUrl = url.indexOf('~');
if (idx != -1) {
String[] cfgs = url.substring(idx + 1).split(";");
for (String cfg : cfgs) {
idx = cfg.indexOf('=');
if (idx != -1) {
String key = cfg.substring(0, idx);
String value = cfg.substring(idx + 1);
configMap.put(key, value);
}
}
url = url.substring(0, idxUrl);
}
String initSessionCfg = configMap.get("session");
if (initSessionCfg != null && !Boolean.parseBoolean(initSessionCfg)) {
AppContext.initSystemEnvironmentContext(request, response, false);
inited = true;
}
if (url.startsWith("^") && navurl.startsWith(url.substring(1))) {
result = true;
break;
}
}
if (!inited)
AppContext.initSystemEnvironmentContext(request, response);
return result


private static Set<String> ignoredUrl;
private static void init() {
if (ignoredUrl == null) {
ignoredUrl = new HashSet<String>();
loadNotNeedLogon("ctp", ignoredUrl);
Object obj = MclclzUtil.invoke(c1, "getInstance");
List<String> plugins = (List<String>)MclclzUtil.invoke(c1, "getPluginIds", null, obj, null);
for (String plugin : plugins)
loadNotNeedLogon(plugin, ignoredUrl);
}
}

D:\Seeyon\A8\ApacheJetspeed\webapps\seeyon\WEB-INF\cfgHome\base/systemProperties.xml
private static void loadNotNeedLogon(String prefix, Set<String> ignoreList) {
String sysConfig = AppContext.getSystemProperty(prefix + ".not_need_logon.navurl"); ctp.not_need_logon.navurl
if (sysConfig != null) {
String[] urls = sysConfig.split("\\|");
for (String c : urls)
ignoreList.add(c);
}
}

相关的漏洞jar包就提供了。以上仅贴出了关键代码。由于对致远A8不熟悉难免分析不准。如果有分析比较模糊的。大家可以跟帖进行详细分析。好了此贴完毕!!!


文章来源: https://forum.90sec.com/t/topic/1513
如有侵权请联系:admin#unsafe.sh