免责声明
由于传播、利用WK安全所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负
责,WK安全及作者不为此承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除
并致歉。谢谢!
本文由纷传@WK-代码审计圈原创,圈子优惠链接请看文末,谢谢支持!
目录架构
图一
根据以上的目录架构 ,我们首先明确我们需要阅读的内容 ,主要包括web.xml、 com 目录下的java代码、所有的jsp 文件
web.xml是Java Web应用程序中的配置文件 ,它在部署和运行Web应用程序时起着重要的作用。它位于Web应用程序 的WEB-INF目录下,用于定义和配置Servlet、过滤器、监听器、错误页面、上下文参数和安全约束等组件和行为。
1. Servlet配置:web.xml文件用于配置和映射Servlet。通过在web.xml中定义Servlet的名称、类名和URL映射, 可以将请求路由到相应的Servlet处理。
2. Filter配置:web.xml文件用于配置和映射过滤器(Filter )。过滤器可以在请求到达Servlet之前或响应返回给 客户端之前对请求和响应进行预处理和后处理。通过在web.xml中定义过滤器的名称、类名和URL映射 ,可 以将过滤器应用于特定的URL或Servlet。
3. Listener配置:web.xml文件用于配置和注册监听器(Listener )。监听器可以监听Web应用程序的生命周期事 件 ,如应用程序的启动和关闭 ,会话的创建和销毁等。通过在web.xml中定义监听器的类名和配置参数 ,可 以将监听器注册到Web应用程序中。
4. 错误页面配置:web.xml文件用于配置自定义的错误页面。通过在web.xml中定义错误码和对应的错误页面, 可以在发生错误时显示自定义的错误页面,提供更友好的用户体验。
5. 上下文参数配置:web.xml文件用于配置应用程序的上下文参数。上下文参数是应用程序级别的配置参数 , 可以在整个应用程序中共享和访问。通过在web.xml中定义上下文参数的名称和值 ,可以在应用程序中获取 和使用这些参数。
6. 安全约束配置:web.xml文件用于配置应用程序的安全约束。通过在web.xml中定义安全约束 ,可以限制对某 些URL或Servlet的访问权限,要求用户进行身份验证或授权。
jsp文件常用于动态页面显示,也可以当做后端代码进行逻辑控制, jsp文件编译后会变成servlet
com 目录下的java代码包含后端逻辑控制的servlet和相关代码
com 目录下的java代码因为编译成了class,所以需要反编译,反编译可以使用jadx,见图三
权限验证分析
项目代码使用struct2、MVC模式进行开发 ,代码量很大 ,路由的方式也有很多 ,这里只做举例讲解 ,比如图一中的 CharactorFilter过滤器 , 因为定义拦截/*即所有的请求都会拦截 ,通过阅读具体的拦截器代码 ,可以发现 ,它的作用 是过滤所有的请求,当请求中有zip为后缀时,设置content-type的方式会有所不同
当后缀为css时候
当后缀为zip时候
同理,我们逐个filter进行阅读
图二
图三
发现QZFilter这个拦截器的authenticate方法对所有的请求做了一个校验 ,校验用户有没有登录 ,如果没有登录情况下 访问就会弹出 用户没有登录,请重新登录!
不过这里有两种情况是例外的,不会进入该filter进行权限处理,第一种情况是authorurl.xml中的url除外
我们,我们看authenticate方法,跟进其中的一些方法调用,发现对authorurl.xml中的url做了特殊的处理
第二种情况是非JSP结尾等情况的判断不会进入权限处理
因为这里没有动态分析的条件 ,所以我们通过简单静态分析权限判断处理流程 ,这个逻辑看上去是比较难绕过的 , 我们来做一些黑盒fuzzing ,比方说js文件是不会进行权限校验的 ,如果存在一些差异 ,导致代码层的权限处理逻辑 判断当前的请求的url是js,但后端是解析成jsp,我们尝试把后缀修改为url编码
绕过了权限认证的逻辑, %70 url解码后是字母p
漏洞分析
这样一来 ,我们已经可以访问所有包含后端逻辑控制的jsp文件 ,后端存在漏洞很多 ,如下举例的jsp文件中的 whereStr参数点未进行安全验证,可导致sql注入
<%
response.setDateHeader("Expires", -10);
StringBuffer whereStr = new StringBuffer();
String whereSql = request.getParameter("whereSql");
if(!StringUtils.nullOrBlank(whereSql)){
whereSql= StringUtils.replaceSpecial(whereSql);
}
if(StringUtils.nullOrBlank(whereSql)){
String xnxq = request.getParameter("xnxq");
String sjmc = request.getParameter("sjmc");
String spzt = request.getParameter("spzt");
String xx0301id = request.getParameter("xx0301id");
if(!StringUtils.nullOrBlank(xnxq)){
whereStr.append(" and paper_basic_info.xnxqh = '"+xnxq+" '");
}
if(!StringUtils.nullOrBlank(sjmc)){
whereStr.append(" and paper_basic_info.paper_desc like '%"+sjmc+"% '"); }
if(!StringUtils.nullOrBlank(spzt)){
whereStr.append(" and paper_basic_info.spzt = '"+spzt+" '");
}
if(!StringUtils.nullOrBlank(xx0301id)){
whereStr.append(" and jx02.kkdw like '% ' || '"+xx0301id+" ' || '% '");
}
pageContext.setAttribute("whereSql",whereStr);
}else{
pageContext.setAttribute("whereSql",whereSql);
}
Frmuser user = (Frmuser) request.getSession().getAttribute(GlobalNames.USER_SESSION_KEY); Jg0101 jg0101 = user.getJg0101();
pageContext.setAttribute("jg0101",jg0101);
String jg0101id = user.getXs0101orjg0101id();
request.setAttribute("jg0101id",jg0101id);
%>
whereSql 参数是通过
request.getParameter("whereSql")
获取的用户输入。没有对这个参数进行适当的处理 ,可以在 whereSql 中插入恶意的 SQL 代码造成sql注入
需要注意的是,中间版本已经对大量的sql注入等做了修复,但权限绕过仍存在,老版本的漏洞不一定还能复现成功
最新版本已对权限绕过做限制,会提示 非法访问
【圈子介绍】
纷传@WK代码审计圈-本圈子主要做代码审计内容分享,涉及.NET、JAVA等审计内容,从0基础开始教起、分享众多bi源源码审计思路与过程,从基础出发到实战训练!
【新人优惠】
https://pc.fenchuan8.com/#/index?forum=75711&coupon=70b18a557e1c6be1e1ff3d670f12afa9&yqm=1X34
【扫码预览】
【运营微信】
原文始发于微信公众号(WK安全):【代码审计】某综合管理系统漏洞分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论