Java代码审计汇总系列(七)——XSS
- 2019 年 12 月 9 日
- 筆記

一、概述
xss漏洞是指对于和后端有交互的地方没有做参数的接收和输入输出过滤,导致恶意攻击者可以插入一些恶意的js语句来获取应用的敏感信息,黑盒系列可见:浏览器解析与编码顺序及xss挖掘绕过全汇总。
大多数通过白盒发现的xss通常发生在将用户输入拼接构造页面元素,或直接输出在前端页面中。
二、挖掘技巧
xss分为反射型,存储型和DOM型,挖掘的思路类似,注意前端构造的参数(元素或值)是否用户可控。
但白盒挖掘xss不像之前的漏洞有明显的漏洞特征和危险函数,需要根据实际情况审计前端js、jsp、html文件。用户输入处用的比较多的是request.getParameter(param)、${param}直接获取用户输入,当然也有其他输入源,需根据代码实际情况分析判断。
类似如下案例,直接将内容返回到前台的页面上,追踪courseName,其值取自数据库,用户可控:

三、漏洞防御
xss的防御办法较多且较为简单:
1、全局编写过滤器;
xml配置文件中定义过滤类或自写过滤类:
private String cleanXSS(String value) { //You'll need to remove thespaces from the html entities below value = value.replaceAll("<", "<").replaceAll(">", "& gt;"); value = value.replaceAll("\(","& #40;").replaceAll("\)", "& #41;"); value = value.replaceAll("'", "& #39;"); value = value.replaceAll("eval\((.*)\)", ""); value =value.replaceAll("[\"\'][\s]*javascript:(.*)[\"\']",""""); value = value.replaceAll("script", ""); return value;
2、调用第三方包
添加jar包:commons-lang-2.5.jar ,在后台调用函数:
StringEscapeUtils.escapeHtml(string); StringEscapeUtils.escapeJavaScript(string); StringEscapeUtils.escapeSql(string);
3、HTML转义输出
org.springframework.web.util.HtmlUtils 可以实现HTML标签及转义字符之间的转换。
String string =HtmlUtils.htmlEscape(userinput); //转义 String s2 =HtmlUtils.htmlUnescape(string); //恢复
四、实战案例
1、DOM XSS
审计js文件发现DOM渲染,经典的将用户输入拼接生成HTML代码或script标签中,这是在白盒测试中最常见的xss场景:
function search (){ varinputStr = $_ts("#search_input").val(); if(inputStr.length> 0){ varsearchurl = ""+url+"/search?keyword="+inputStr +"&lang=zh"; varsearchLink = '<a id="temp_search_link" target="_blank"rel="noopener " href="' + searchurl + '"style="display:none;"><span id="searchclick"></span></a>'; $_ts("body").append(searchLink); $_ts("#searchclick").click(); $_ts("#temp_search_link").remove(); }
2、Cookie XSS
同样是审计js文件,在文件中发现如下代码,:
document.write('<linkhref="resource/web/css/page.css" type="text/css"rel="stylesheet" />'); varlocale = getCookie("locale"); varCssPath = "resource /web/theme /default/css/base_" + locale +".css"; document.write('<linkhref="' + CssPath + '" type="text/css"rel="stylesheet" />');
将经过getCookie方法的值locale进行拼接,用document.write 输出到页面,跟进getCookie:
function getCookie(name) { vararr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); if(arr = document.cookie.match(reg)) returnunescape(arr[2]);
将cookie变量值locale与目录进行拼接,用document.write 输出到页面,未检查特殊字符,可在前端伪造cookie进行攻击。
另外,挖掘DOM xss可关注location.*、document.*、window.*等关键字。
3、 过滤绕过
审计jsp文件,param为用户输入参数,

然后在js文件中的exportStep2Host函数中进行赋值,在后 URL解码后传给form表单的action属性,然后再提交表单。这个函数会在页面被打开的时候触发。

但在取用户输入时经过了validateQuotAndBracketChar过滤,跟进分析此工具类:

这个类对用户输入进行了黑名单限制,不能包含<>’”以及对字符url编码的%3E、%3C等字符。可使用javascript协议进行url编码绕过:
javaScript%3a%3ba%25%36%63ert%601%60
最终payload:
https://url/path/exportStep2Host.jsp?param=javaScript%3a%3ba%256cert`1`
所以能用白名单尽量用白名单,若使用黑名单尽量全面。