The CVE That Will Never Die!
While exploring targets lately on Synack and HackerOne, I keep coming across this old CVE, it’s CVE-2016–0957. For those that don’t recall this little gem, it involves bypassing adobe’s dispatcher. Think of the dispatcher like a web application firewall (WAF). But first I will start by explaining the Adobe Experience Manager (AEM) quick. Adobe says it’s a comprehensive content management solution for building websites, mobile apps, and forms.
Adobe, I’m sure it’s great! But let’s learn how I spot it, what’s possible once you find it, and the tools that make all of that happen!
Let’s get started!
First finding AEM, you can do a simple google search, below are some searches you can do and the results of one quick search.
What we are searching for:
Inurl:/content/dam/
inurl:/content/geometrixx/
inurl:/etc.clientlibs
inurl: /libs/cq/security/userinfo.json
Then look for targets that have a bug bounty on HackerOne or BugCrowd for instance. Once you find targets explore the HTML on the main page looking for references to etc.clientlibs, content, or dam. These are dead giveaways the site is using AEM, an example below.
I should mention if you think only small sites have this issue, even bigger sites can slightly misconfigure AEM, exposing information.
If your search doesn’t turn up good candidates, you can also go to https://chaos.projectdiscovery.io/#/, and download lists of targets.
Once you have a list of targets you can run Nuclei against them.
If you haven’t heard of Nuclei you should start using it, it’s a fast-configurable targeted scanner. I will go over how I use it to find a bunch of things along with other tricks in a book I’m writing that hopefully will be released next year called “The Side Hustlers Guide to Hacking”.
The link for Nuclei is below.
https://github.com/projectdiscovery/nuclei
Gather a list of targets and put this in the urls.txt. The URLs should like below.
https://example
http://example
I like to add HTTP:// and HTTPS:// just in case there are systems running with HTTP as well, they are out there. Next, I use the command below to do a scan for the use of AEM.
nuclei -l /nuclei/files/urls.txt -t /Users/me/nuclei/nuclei-templates/technologies/tech-detect.yaml
This script looks for these two directories in particular.
“/etc/clientlibs/”
“/content/dam/”
If it finds these directories, it assumes the system has AEM running. I find that it has yet to be wrong, sometimes I have to dig a little bit deeper to find it, but I have yet to see Nuclei be wrong.
Ok, now you have a few targets with AEM, now what? Now it’s time to see what information we can find. I like to run AEM Hacker, which is a toolset to look for AEM vulnerabilities. Github page below.
https://github.com/0ang3el/aem-hacker
Once you have it downloaded and running you can run the command below.
Python3 ./aem_hacker.py –u https://example — host localhost
This will search for some very common AEM bypasses. If this doesn’t work, I have been compiling a list of bypasses that I have tested and have worked for me. This list is nothing special, but it is a combined list from other sources, you can find below.
https://github.com/clarkvoss/AEM-List/blob/main/paths
Using Burp Community Edition and using the intruder tab. You can load the list I have and run it against the target by adding § to the content directory, like below.
And Start Attack!
Keep in mind you may be up against an AkamaiGhost or some other WAF on top of the dispatcher trying to stop you, so you may have to try harder (OSCP)! You are only hindered by your creativity and the person who configured the WAF.
So you ran all these tools against a target, now what? Good question!
You may get lucky with the methods above and the information obtained may be enough to submit a report to HackerOne. If not, we move on to the manual process of taking it to the next level. It’s why you are here, right?
Let’s say you have a target and you can see directories and files by appending a .json, ;.html, or %0Aa.css to the end of the URL like so https://example/content/.json. By appending .json will give you a JSON view of the directories which is great. To look in the directories, you can tell AEM at the level at which you want to see in those directories like adding .1.json or see the children underneath like .children.1.json.
This output can be a huge list, recently I could see all the files under the path /content/dam by appending .children.400.json. This will allow you to see all the folders and files under /content/dam for instance. You can then go to these images, PDFs, and other files to find very sensitive data to really show impact.
What other data can you extract, server snapshots.
And Disk Usage.
Let’s say you want to see a page, I found you can add ;.html to see the contents of the page’s HTML. For instance, you happen to find a page under the content directory like the regent.html which is a health check tool for AEM but you go there and the dispatcher stops you. Add ;.html to the end like below and you can then see the contents of the page. I even found recently I had to append .json;.html as well which really throws the dispatcher for a loop and lets you see the contents of pages that normally would require a username and password to access.
If you find that the sling login is exposed with the above method letting you view the page. Using Burp you can add basic authentication to the request by adding Authorization: Basic YWRtaW46YWRtaW4= to the request like below.
GET /system/sling/cqform/defaultlogin.html;%0aa.css HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Authorization: Basic YWRtaW46YWRtaW4=
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
And using the small word list below, encoding the list into base64 to gain access if you can’t seem to log in.
admin:admin
author:author
anonymous:anonymous
replication-receiver:replication-receiver
jdoe@geometrixx.info:jdoe
aparker@geometrixx.info:aparker
If you find all the info you gathered is just not enough to show impact, and you can’t access any directories exposing sensitive data, the last thing you can try is adding a page! If the /content/usergenerated/ directory is exposed you may be able to POST to it. Using a similar request like below, you can create a page. You may also be able to write to other pages in other directories.
POST /content/usergenerated/x11-test.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:83.0) Gecko/20100101 Firefox/83.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 25<html>@x11 created</html>
You can try adding an XSS payload, but this may not work if the WAF is configured correctly. If all the above doesn’t work, move on! As I’m sure you can imagine there are a lot of web applications out there misconfigured.
The last thing you may be wondering is there any documentation or advice you can give to a developer on how to fix these issues to close the loop. The quick answer is there is an Adobe Security Checklist and ensuring any WAF setup is blocking requests to any sensitive AEM directories.
Adobes Security Checklist below.
Now go out and find these! If I can find them, so can you, don’t get discouraged! I hope you enjoyed reading.