@@ -277,11 +277,13 @@ def cmd_dump_sms(*args)
277
277
end
278
278
279
279
def cmd_dump_contacts ( *args )
280
- path = "contacts_dump_#{ Time . new . strftime ( '%Y%m%d%H%M%S' ) } .txt"
280
+ path = "contacts_dump_#{ Time . new . strftime ( '%Y%m%d%H%M%S' ) } "
281
+ format = :text
281
282
282
283
dump_contacts_opts = Rex ::Parser ::Arguments . new (
283
284
'-h' => [ false , 'Help Banner' ] ,
284
- '-o' => [ true , 'Output path for contacts list' ]
285
+ '-o' => [ true , 'Output path for contacts list' ] ,
286
+ '-f' => [ true , 'Output format for contacts list (text, csv, vcard)' ]
285
287
)
286
288
287
289
dump_contacts_opts . parse ( args ) do |opt , _idx , val |
@@ -293,6 +295,18 @@ def cmd_dump_contacts(*args)
293
295
return
294
296
when '-o'
295
297
path = val
298
+ when '-f'
299
+ case val
300
+ when 'text'
301
+ format = :text
302
+ when 'csv'
303
+ format = :csv
304
+ when 'vcard'
305
+ format = :vcard
306
+ else
307
+ print_error ( 'Invalid output format specified' )
308
+ return
309
+ end
296
310
end
297
311
end
298
312
@@ -301,33 +315,62 @@ def cmd_dump_contacts(*args)
301
315
if contact_list . count > 0
302
316
print_status ( "Fetching #{ contact_list . count } #{ contact_list . count == 1 ? 'contact' : 'contacts' } into list" )
303
317
begin
304
- info = client . sys . config . sysinfo
318
+ data = ''
305
319
306
- data = ""
307
- data << " \n ====================== \n "
308
- data << "[+] Contacts list dump \n "
309
- data << "====================== \n \n "
320
+ case format
321
+ when :text
322
+ info = client . sys . config . sysinfo
323
+ path << '.txt' unless path . end_with? ( '.txt' )
310
324
311
- time = Time . new
312
- data << "Date: #{ time . inspect } \n "
313
- data << "OS: #{ info [ 'OS' ] } \n "
314
- data << "Remote IP: #{ client . sock . peerhost } \n "
315
- data << "Remote Port: #{ client . sock . peerport } \n \n "
325
+ data << "\n ======================\n "
326
+ data << "[+] Contacts list dump\n "
327
+ data << "======================\n \n "
316
328
317
- contact_list . each_with_index do |c , index |
329
+ time = Time . new
330
+ data << "Date: #{ time . inspect } \n "
331
+ data << "OS: #{ info [ 'OS' ] } \n "
332
+ data << "Remote IP: #{ client . sock . peerhost } \n "
333
+ data << "Remote Port: #{ client . sock . peerport } \n \n "
318
334
319
- data << "##{ index . to_i + 1 } \n "
320
- data << "Name\t : #{ c [ 'name' ] } \n "
335
+ contact_list . each_with_index do |c , index |
336
+
337
+ data << "##{ index . to_i + 1 } \n "
338
+ data << "Name\t : #{ c [ 'name' ] } \n "
339
+
340
+ c [ 'number' ] . each do |n |
341
+ data << "Number\t : #{ n } \n "
342
+ end
343
+
344
+ c [ 'email' ] . each do |n |
345
+ data << "Email\t : #{ n } \n "
346
+ end
321
347
322
- c [ 'number' ] . each do |n |
323
- data << "Number\t : #{ n } \n "
348
+ data << "\n "
324
349
end
350
+ when :csv
351
+ path << '.csv' unless path . end_with? ( '.csv' )
325
352
326
- c [ 'email' ] . each do |n |
327
- data << "Email \t : #{ n } \n "
353
+ contact_list . each do |contact |
354
+ data << contact . values . to_csv
328
355
end
356
+ when :vcard
357
+ path << '.vcf' unless path . end_with? ( '.vcf' )
329
358
330
- data << "\n "
359
+ contact_list . each do |contact |
360
+ data << "BEGIN:VCARD\n "
361
+ data << "VERSION:3.0\n "
362
+ data << "FN:#{ contact [ 'name' ] } \n "
363
+
364
+ contact [ 'number' ] . each do |number |
365
+ data << "TEL:#{ number } \n "
366
+ end
367
+
368
+ contact [ 'email' ] . each do |email |
369
+ data << "EMAIL:#{ email } \n "
370
+ end
371
+
372
+ data << "END:VCARD\n "
373
+ end
331
374
end
332
375
333
376
::File . write ( path , data )
0 commit comments