Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
strutt-cve-2014-0114 — Apache Struts 1 클래스 매개변수 조작(CVE-2014-0114)에 대한 기술 분석 및 개념 증명으로, Tomcat에서 원격 코드 실행 및 JBoss/Wildfly에서 서비스 거부를 시연합니다. | Kitploit
도구/GitHubGitHub/aenlr/strutt-cve-2014-0114
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingPapers & ResearchLearning & Education
GitHubaenlr/strutt-cve-2014-0114

strutt-cve-2014-0114

Apache Struts 1 클래스 매개변수 조작(CVE-2014-0114)에 대한 기술 분석 및 개념 증명으로, Tomcat에서 원격 코드 실행 및 JBoss/Wildfly에서 서비스 거부를 시연합니다.

저장소 보기
2117년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2014-0114 - Struts 1의 취약점

POST 또는 GET 요청의 매개변수는 양식을 기준으로 설정될 속성(properties)으로 처리됩니다. 매개변수는 중첩된 객체로의 경로일 수 있습니다.

Apache Struts 1.x는 Form Beans에서 getClass()를 호출하도록 조작될 수 있습니다. 예를 들어, 양식의 classloader 속성을 직접 조작할 수 있습니다: https://example.com/?class.classLoader.defaultAssertionStatus=true.

내부적으로 Apache Struts 1.x는 commons-beanutils를 사용하는데, 버전 1.8(및 이전 버전)에서는 class 속성을 제외하지 않습니다.

Struts 2도 유사한 결함이 있었지만, 여기서는 프레임워크에 패치가 없으며 최신 버전이 2008년에 출시된(2013년부터 EOL) Struts 1.x에 초점을 맞춥니다.

Tomcat - Remote Code Execution (RCE)

애플리케이션이 Tomcat (Catalina)에서 실행되는 경우 로깅을 조작하여 공격자가 JSP 파일을 생성하고 서버에 요청할 때 실행되도록 할 수 있습니다. JSP 파일은 Java 프로세스를 실행하는 사용자로 임의의 Java 코드를 실행할 수 있습니다.

자세한 내용은 Julián Vilas의 데모를 참조하세요.

JBoss/Wildfly - Denial Of Service (DOS)

(JBoss EAP 7.1에서 테스트됨)

최악의 경우 JBoss를 완전히 사용할 수 없게 만들고 재시작이 필요한 DOS 공격을 수행하는 간단한 방법이 있습니다. 최선의 경우 JBoss가 느리게 응답합니다.

실행

class 속성을 통해 Class#protectionDomain.codeSource.location에 접근할 수 있습니다. JBoss에서는 프로토콜을 가진 객체입니다.

vfs
URL

vfs:// 타입의 URL에 대해 JBoss는 URLStreamHandler를 등록했으며, URL#getContent가 호출되면 org.jboss.vfs.VirtualFile 타입의 객체를 반환합니다.

class.protectionDomain.codeSource.location.content.pathName는 <SÖKGVÄG>/<applikation>/WEB-INF/classes 디렉토리를 가리킵니다.

parent를 통해 한 단계 위 디렉토리의 객체에 접근합니다:

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

질문: 파일 시스템의 루트에 도달하기 위해 몇 개의 parent 참조가 필요한가?

질문: 파일 시스템의 루트 디렉토리에 대해 class.protectionDomain.codeSource.location.content.parent.parent.[...].childrenRecursively[0].pathName을 요청하면 어떻게 되는가?

답변: JBoss는 파일 시스템의 모든 파일을 탐색하고 각 파일 및 디렉토리에 대해 org.jboss.vfs.VirtualFile을 할당합니다.

추가 질문: 두 개의 요청이 동시에 파일 시스템의 모든 파일을 요청하면 어떻게 되는가? 세 개? 다섯 개? 열 개? 백 개?

...

답변:

충분히 기다리면 오류가 기록됩니다

root@kitploit:~
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는 몇 개의 요청에 대한 가비지 컬렉션을 처리하느라 최대치로 작동하며 Java 프로세스는 다른 작업을 거의 처리하지 못합니다.

애플리케이션에 따라 다르기도 합니다. 잠금을 획득하는 코드 경로를 트리거하면 애플리케이션/시스템이 중단될 수 있습니다.

참고 자료

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)

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

도구 다운로드