Merge pull request #1670 from bcoles/geoip

Update GeoIP to use MaxMind GeoLite2
This commit is contained in:
bcoles
2019-02-10 23:48:57 +11:00
committed by GitHub
7 changed files with 127 additions and 42 deletions

View File

@@ -42,7 +42,7 @@ end
# Geolocation support
group :geoip do
gem 'geoip'
gem 'maxmind-db'
end
gem 'parseconfig'

5
beef
View File

@@ -215,6 +215,11 @@ end
#
print_info "RESTful API key: #{BeEF::Core::Crypto::api_token}"
#
# @note Load the GeoIP database
#
BeEF::Core::GeoIp.instance
#
# @note Call the API method 'pre_http_start'
#

View File

@@ -135,11 +135,12 @@ beef:
# IP Geolocation
# NOTE: requires MaxMind database:
# curl -O http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
# gunzip GeoLiteCity.dat.gz && mkdir /opt/GeoIP && mv GeoLiteCity.dat /opt/GeoIP
# /usr/bin/curl -O https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
# /bin/gunzip GeoLite2-City.tar.gz && /bin/tar xvf GeoLite2-City.tar && /bin/rm GeoLite2-City.tar
# /bin/mkdir -p /opt/GeoIP && /bin/mv GeoLite2-City_*/* /opt/GeoIP && /bin/rmdir GeoLite2-City_*
geoip:
enable: false
database: '/opt/GeoIP/GeoLiteCity.dat'
enable: true
database: '/opt/GeoIP/GeoLite2-City.mmdb'
# Integration with PhishingFrenzy
# If enabled BeEF will try to get the UID parameter value from the hooked URI, as this is used by PhishingFrenzy

View File

@@ -32,6 +32,7 @@ require 'core/main/command'
require 'core/main/crypto'
require 'core/main/logger'
require 'core/main/migration'
require 'core/main/geoip'
# @note Include the command line parser and the banner printer
require 'core/main/console/commandline'

59
core/main/geoip.rb Normal file
View File

@@ -0,0 +1,59 @@
#
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
module BeEF
module Core
class GeoIp
include Singleton
def initialize
@config = BeEF::Core::Configuration.instance
@enabled = @config.get('beef.geoip.enable') ? true : false
return unless @enabled
geoip_file = @config.get('beef.geoip.database')
unless File.exists? geoip_file
print_error "[GeoIP] Could not find MaxMind GeoIP database: '#{geoip_file}'"
@enabled = false
return
end
require 'maxmind/db'
@geoip_reader = MaxMind::DB.new(geoip_file, mode: MaxMind::DB::MODE_MEMORY)
@geoip_reader.freeze
rescue => e
print_error "[GeoIP] Failed to load GeoIP database: #{e.message}"
@enabled = false
end
#
# Check if GeoIP functionality is enabled and functional
#
# @return [Boolean] GeoIP functionality enabled?
#
def enabled?
@enabled
end
#
# Search the MaxMind GeoLite2 database for the specified IP address
#
# @param [String] The IP address to lookup
#
# @return [Hash] IP address lookup results
#
def lookup(ip)
raise Exception::TypeError, '"ip" needs to be a string' unless ip.string?
return unless @enabled
@geoip_reader.get(ip)
end
end
end
end

View File

@@ -103,32 +103,53 @@ module BeEF
# geolocation
BD.set(session_id, 'LocationCity', 'Unknown')
BD.set(session_id, 'LocationCountry', 'Unknown')
if config.get('beef.geoip.enable')
require 'geoip'
geoip_file = config.get('beef.geoip.database')
if File.exists? geoip_file
geoip = GeoIP.new(geoip_file).city(zombie.ip)
if geoip.nil?
print_debug "[INIT] Geolocation failed - No results for IP address '#{zombie.ip}'"
else
#print_debug "[INIT] Geolocation results: #{geoip}"
BeEF::Core::Logger.instance.register('Zombie', "#{zombie.ip} is connecting from: #{geoip}", "#{zombie.id}")
BD.set(session_id, 'LocationCity', "#{geoip['city_name']}")
BD.set(session_id, 'LocationCountry', "#{geoip['country_name']}")
BD.set(session_id, 'LocationCountryCode2', "#{geoip['country_code2']}")
BD.set(session_id, 'LocationCountryCode3', "#{geoip['country_code3']}")
BD.set(session_id, 'LocationContinentCode', "#{geoip['continent_code']}")
BD.set(session_id, 'LocationPostCode', "#{geoip['postal_code']}")
BD.set(session_id, 'LocationLatitude', "#{geoip['latitude']}")
BD.set(session_id, 'LocationLongitude', "#{geoip['longitude']}")
BD.set(session_id, 'LocationDMACode', "#{geoip['dma_code']}")
BD.set(session_id, 'LocationAreaCode', "#{geoip['area_code']}")
BD.set(session_id, 'LocationTimezone', "#{geoip['timezone']}")
BD.set(session_id, 'LocationRegionName', "#{geoip['real_region_name']}")
end
if BeEF::Core::GeoIp.instance.enabled?
geoip = BeEF::Core::GeoIp.instance.lookup(zombie.ip)
if geoip.nil?
print_debug "[INIT] Geolocation failed - No results for IP address '#{zombie.ip}'"
else
print_error "[INIT] Geolocation failed - Could not find MaxMind GeoIP database '#{geoip_file}'"
print_more "Download: http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz"
# print_debug "[INIT] Geolocation results: #{geoip}"
BeEF::Core::Logger.instance.register('Zombie', "#{zombie.ip} is connecting from: #{geoip}", "#{zombie.id}")
BD.set(
session_id,
'LocationCity',
"#{geoip['city']['names']['en'] rescue 'Unknown'}")
BD.set(
session_id,
'LocationCountry',
"#{geoip['country']['names']['en'] rescue 'Unknown' }")
BD.set(
session_id,
'LocationCountryIsoCode',
"#{geoip['country']['iso_code'] rescue ''}")
BD.set(
session_id,
'LocationRegisteredCountry',
"#{geoip['registered_country']['names']['en'] rescue ''}")
BD.set(
session_id,
'LocationRegisteredCountryIsoCode',
"#{geoip['registered_country']['iso_code'] rescue ''}")
BD.set(
session_id,
'LocationContinent',
"#{geoip['continent']['names']['en'] rescue ''}")
BD.set(
session_id,
'LocationContinentCode',
"#{geoip['continent']['code'] rescue ''}")
BD.set(
session_id,
'LocationLatitude',
"#{geoip['location']['latitude'] rescue ''}")
BD.set(
session_id,
'LocationLongitude',
"#{geoip['location']['longitude'] rescue ''}")
BD.set(
session_id,
'LocationTimeZone',
"#{geoip['location']['time_zone'] rescue ''}")
end
end

View File

@@ -98,18 +98,16 @@ class Modules < BeEF::Extension::AdminUI::HttpController
['Browser Components', 'Foxit', 'HasFoxit'],
# Geolocation
['Location', 'City', 'LocationCity'],
['Location', 'Country', 'LocationCountry'],
['Location', 'CountryCode2', 'LocationCountryCode2'],
['Location', 'CountryCode3', 'LocationCountryCode3'],
['Location', 'Continent', 'LocationContinentCode'],
['Location', 'Post Code', 'LocationPostCode'],
['Location', 'Latitude', 'LocationLatitude'],
['Location', 'Longitude', 'LocationLongitude'],
['Location', 'DMA Code', 'LocationDMACode'],
['Location', 'Area Code', 'LocationAreaCode'],
['Location', 'Timezone', 'LocationTimezone'],
['Location', 'Region', 'LocationRegionName'],
['Location', 'City', 'LocationCity'],
['Location', 'Country', 'LocationCountry'],
['Location', 'Country Code', 'LocationCountryIsoCode'],
['Location', 'Registered Country', 'LocationRegisteredCountry'],
['Location', 'Registered Country Code', 'LocationRegisteredCountryIsoCode'],
['Location', 'Continent', 'LocationContinent'],
['Location', 'Continent Code', 'LocationContinentCode'],
['Location', 'Latitude', 'LocationLatitude'],
['Location', 'Longitude', 'LocationLongitude'],
['Location', 'Time Zone', 'LocationTimeZone'],
# Hooked Page
['Hooked Page', 'Page Title', 'PageTitle'],