This issue was found back in around november 2020 by me and my friend who would rather not come out publicly with his name, so let’s call him purpl3 (his wish :D).
This was one of my first 0day’s so we choose to audit some of the ecommerce platforms since they’re usually fun to play around.
In the end we found a preauth RCE in Maian Cart 3.8 (latest) but we procrastinated to report it ever since because we already started working on new projects, so 2021 here we come :)
I hope this post can also help out some people out there that are trying to get into source code review (although this one was pretty easy).
Finding the issue
To start with, if you are interested, you can setup the source code locally by following this guide and make it more of a challenge to play around & learn.
You can also setup a vhost for localhost and make it look like a real deployed website in the wild by editing /etc/hosts
:
Usually when starting out a fresh target i starting grepping out interesting pieces of code or approaching it the blackbox way until i come by some interesting endpoints from where the whitebox testing starts.
Also, it’s worth looking into post-admin-auth side vulnerabilities as they could be a part of a exploit chain later on.
We found many XSS’s on the post-admin-auth side but it wasn’t really worth anything.. until purpl3 noticed a file manager plugin at /admin/index.php?p=dl-manager#elf_l1_Lw
:
It allowed an administrator to upload files, including a shell. So that was a simple post-admin-auth RCE, but still that means pretty much nothing as it’s intended to allow all admin’s to upload/manage file’s unless it’s chained with something ;)
Let’s take a look at the plugin’s source .
We started grepping the files to find where it’s being used or to just gather some additional info on how the plugin works.
For this you can use grep -r -E "elfinder" *
:
Quickly enough i was able to find a few interesting files, admin/control/classes/_elfinder/elFinder.class.php
being one of them as it contained a lot of useful information.
It looked like the Elfinder plugin also provides a API-like thing which allows the following calls to it:
protected $commands = array(
'open' => array('target' => false, 'tree' => false, 'init' => false, 'mimes' => false, 'compare' => false),
'ls' => array('target' => true, 'mimes' => false, 'intersect' => false),
'tree' => array('target' => true),
'parents' => array('target' => true),
'tmb' => array('targets' => true),
'file' => array('target' => true, 'download' => false),
'zipdl' => array('targets' => true, 'download' => false),
'size' => array('targets' => true),
'mkdir' => array('target' => true, 'name' => true),
'mkfile' => array('target' => true, 'name' => true, 'mimes' => false),
'rm' => array('targets' => true),
'rename' => array('target' => true, 'name' => true, 'mimes' => false),
'duplicate' => array('targets' => true, 'suffix' => false),
'paste' => array('dst' => true, 'targets' => true, 'cut' => false, 'mimes' => false, 'renames' => false, 'hashes' => false, 'suffix' => false),
'upload' => array('target' => true, 'FILES' => true, 'mimes' => false, 'html' => false, 'upload' => false, 'name' => false, 'upload_path' => false, 'chunk' => false,'cid' => false, 'node' => false, 'renames' => false, 'hashes' => false, 'suffix' => false),
'get' => array('target' => true, 'conv' => false),
'put' => array('target' => true, 'content' => '', 'mimes' => false),
'archive' => array('targets' => true, 'type' => true, 'mimes' => false, 'name' => false),
'extract' => array('target' => true, 'mimes' => false, 'makedir' => false),
'search' => array('q' => true, 'mimes' => false, 'target' => false),
'info' => array('targets' => true, 'compare' => false),
'dim' => array('target' => true),
'resize' => array('target' => true, 'width' => true, 'height' => true, 'mode' => false, 'x' => false, 'y' => false, 'degree' => false, 'quality' => false),
'netmount' => array('protocol' => true, 'host' => true, 'path' => false, 'port' => false, 'user' => false, 'pass' => false, 'alias' => false, 'options' => false),
'url' => array('target' => true, 'options' => false),
'callback' => array('node' => true, 'json' => false, 'bind' => false, 'done' => false),
'chmod' => array('targets' => true, 'mode' => true)
);
While trying to upload an actual file through the web UI and intercepting the request i found the exact parameter where i can pass all these:
So i decided to do a quick request with curl and use the ls
value on the cmd
parameter to get a list of files (note - this all is still on the post-admin-auth side):
Notice something wrong here 8-)
Okay, cool, we can do CRUD operations using the Elfinder API , but what’s the point of it when it’s all from the admin side?
Let’s jump on the Exploitation section of this blog.
Exploitation
So as you have read the title of this blog post, it clearly says preauth. How? If you haven’t noticed from the last image how the bug was chained to a preauth RCE, i’ll explain.
This part required being a little lucky (i suppose xD) ! I tried curling the admin side endpoint without any session initiated and it still returned the output - fun right?
So, this started sounding like a Broken Access Control
issue.
The API was clearly misconfigured and didn’t have any permission check, so any unauthorized attacker could make a request to it
Since i can’t trigger the shell in one API call, i gathered all the needed param values to upload & execute a shell:
-
Make a file:
/admin/index.php?p=ajax-ops&op=elfinder&cmd=mkfile&name=shell.php&target=l1_Lw
-
Write to the file: POST request with the
cmd=put
param to/admin/index.php?p=ajax-ops&op=elfinder
-
Execute the file/shell:
/product-downloads/shell.php
So here we chained a BAC
issue on a misconfigured API with a post-admin-auth RCE.
I automated the whole exploit chain with a quick python script that you can find on my github.
Let’s explain the exploit
So first it makes a file:
Then it gets the file id which is contained in the json response body:
Writes a url-encoded php web shell to the file with a POST request with cmd=put
and the file id & content as params:
Then, finally execute the shell:
I also added a little fun addition to it which removes the shell as soon as we close the exploit:
Video PoC
Outro
This isssue was reported to the holders of Maian Cart, you can check out the referrence of this issue on their website.
It should be patched in the upcoming Maian Cart v3.9 and all of their customers were contacted to patch their systems.
The CVE assigned number is CVE-2021-32172
I hope you enjoyed one of my first blog post and aswell got to learn a little bit of source code analysis & exploit development from it!
Till the next time :)