diff --git a/config.yaml b/config.yaml index fcec9db00..a43d8b96c 100644 --- a/config.yaml +++ b/config.yaml @@ -130,6 +130,13 @@ beef: enable: false database: '/opt/GeoIP/GeoLiteCity.dat' + # Integration with PhishingFrenzy + # If enabled BeEF will try to get the UID parameter value from the hooked URI, as this is used by PhishingFrenzy + # to uniquely identify the victims. In this way you can easily associate phishing emails with hooked browser. + integration: + phishing_frenzy: + enable: false + # You may override default extension configuration parameters here extension: requester: diff --git a/core/main/client/browser.js b/core/main/client/browser.js index 91c030050..ce956b9ff 100644 --- a/core/main/client/browser.js +++ b/core/main/client/browser.js @@ -726,12 +726,12 @@ beef.browser = { }, /** - * Returns true if Chrome for iOS 31. - * @example: beef.browser.isC31iOS() - */ - isC31iOS: function () { - return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 31) ? true : false); - }, + * Returns true if Chrome for iOS 31. + * @example: beef.browser.isC31iOS() + */ + isC31iOS: function () { + return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 31) ? true : false); + }, /** * Returns true if Chrome 32. @@ -742,9 +742,9 @@ beef.browser = { }, /** - * Returns true if Chrome for iOS 32. - * @example: beef.browser.isC32iOS() - */ + * Returns true if Chrome for iOS 32. + * @example: beef.browser.isC32iOS() + */ isC32iOS: function () { return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 32) ? true : false); }, @@ -758,9 +758,9 @@ beef.browser = { }, /** - * Returns true if Chrome for iOS 33. - * @example: beef.browser.isC33iOS() - */ + * Returns true if Chrome for iOS 33. + * @example: beef.browser.isC33iOS() + */ isC33iOS: function () { return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 33) ? true : false); }, @@ -774,9 +774,9 @@ beef.browser = { }, /** - * Returns true if Chrome for iOS 34. - * @example: beef.browser.isC34iOS() - */ + * Returns true if Chrome for iOS 34. + * @example: beef.browser.isC34iOS() + */ isC34iOS: function () { return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 34) ? true : false); }, @@ -790,9 +790,9 @@ beef.browser = { }, /** - * Returns true if Chrome for iOS 35. - * @example: beef.browser.isC35iOS() - */ + * Returns true if Chrome for iOS 35. + * @example: beef.browser.isC35iOS() + */ isC35iOS: function () { return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 35) ? true : false); }, @@ -806,9 +806,9 @@ beef.browser = { }, /** - * Returns true if Chrome for iOS 36. - * @example: beef.browser.isC36iOS() - */ + * Returns true if Chrome for iOS 36. + * @example: beef.browser.isC36iOS() + */ isC36iOS: function () { return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 36) ? true : false); }, @@ -822,9 +822,9 @@ beef.browser = { }, /** - * Returns true if Chrome for iOS 37. - * @example: beef.browser.isC37iOS() - */ + * Returns true if Chrome for iOS 37. + * @example: beef.browser.isC37iOS() + */ isC37iOS: function () { return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 37) ? true : false); }, @@ -890,13 +890,13 @@ beef.browser = { * Returns a hash of string keys representing a given capability * @example: beef.browser.capabilities()["navigator.plugins"] */ - capabilities: function() { - var out = {}; - var type = this.type(); + capabilities: function () { + var out = {}; + var type = this.type(); - out["navigator.plugins"] = (type.IE11 || !type.IE); + out["navigator.plugins"] = (type.IE11 || !type.IE); - return out; + return out; }, /** @@ -2145,6 +2145,24 @@ beef.browser = { if (has_wmp) details['HasWMP'] = has_wmp; if (has_foxit) details['HasFoxit'] = has_foxit; + var pf_integration = "<%= @phishing_frenzy_enable %>"; + if (pf_integration) { + var pf_param = "UID"; + var pf_victim_uid = ""; + var location_search = window.location.search.substring(1); + var params = location_search.split('&'); + for (var i = 0; i < params.length; i++) { + var param_entry = params[i].split('='); + if (param_entry[0] == pf_param) { + pf_victim_uid = param_entry[1]; + details['PhishingFrenzyUID'] = pf_victim_uid; + break; + } + } + } else { + details['PhishingFrenzyUID'] = "N/A"; + } + return details; }, @@ -2346,11 +2364,12 @@ beef.browser = { /** * Get the browser language */ - getBrowserLanguage: function(){ + getBrowserLanguage: function () { var l = 'Unknown'; - try{ - l = window.navigator.userLanguage || window.navigator.language; - }catch(e){} + try { + l = window.navigator.userLanguage || window.navigator.language; + } catch (e) { + } return l; }, diff --git a/core/main/handlers/browserdetails.rb b/core/main/handlers/browserdetails.rb index 8e3916e79..98bb5a73b 100644 --- a/core/main/handlers/browserdetails.rb +++ b/core/main/handlers/browserdetails.rb @@ -68,10 +68,10 @@ module BeEF #Parse http_headers. Unfortunately Rack doesn't provide a util-method to get them :( @http_headers = Hash.new - http_header = @data['request'].env.select {|k,v| k.to_s.start_with? 'HTTP_'} - .each {|key,value| - @http_headers[key.sub(/^HTTP_/, '')] = value - } + http_header = @data['request'].env.select { |k, v| k.to_s.start_with? 'HTTP_' } + .each { |key, value| + @http_headers[key.sub(/^HTTP_/, '')] = value + } zombie.httpheaders = @http_headers.to_json zombie.save #print_debug "[INIT] HTTP Headers: #{zombie.httpheaders}" @@ -112,37 +112,37 @@ module BeEF 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, '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']}") + 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 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_more "Download: http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz" end end # detect browser proxy using_proxy = false [ - 'CLIENT_IP', - 'FORWARDED_FOR', - 'FORWARDED', - 'FORWARDED_FOR_IP', - 'PROXY_CONNECTION', - 'PROXY_AUTHENTICATE', - 'X_FORWARDED', - 'X_FORWARDED_FOR', - 'VIA' + 'CLIENT_IP', + 'FORWARDED_FOR', + 'FORWARDED', + 'FORWARDED_FOR_IP', + 'PROXY_CONNECTION', + 'PROXY_AUTHENTICATE', + 'X_FORWARDED', + 'X_FORWARDED_FOR', + 'VIA' ].each do |header| unless JSON.parse(zombie.httpheaders)[header].nil? using_proxy = true @@ -153,12 +153,12 @@ module BeEF # retrieve proxy client IP proxy_clients = [] [ - 'CLIENT_IP', - 'FORWARDED_FOR', - 'FORWARDED', - 'FORWARDED_FOR_IP', - 'X_FORWARDED', - 'X_FORWARDED_FOR' + 'CLIENT_IP', + 'FORWARDED_FOR', + 'FORWARDED', + 'FORWARDED_FOR_IP', + 'X_FORWARDED', + 'X_FORWARDED_FOR' ].each do |header| proxy_clients << "#{JSON.parse(zombie.httpheaders)[header]}" unless JSON.parse(zombie.httpheaders)[header].nil? end @@ -311,10 +311,10 @@ module BeEF # get and store the yes|no value for browser components components = [ - 'VBScriptEnabled', 'HasFlash', 'HasPhonegap', 'HasGoogleGears', - 'HasFoxit', 'HasWebSocket', 'HasWebRTC', 'HasActiveX', - 'HasSilverlight', 'HasQuickTime', 'HasRealPlayer', 'HasWMP', - 'hasSessionCookies', 'hasPersistentCookies' + 'VBScriptEnabled', 'HasFlash', 'HasPhonegap', 'HasGoogleGears', + 'HasFoxit', 'HasWebSocket', 'HasWebRTC', 'HasActiveX', + 'HasSilverlight', 'HasQuickTime', 'HasRealPlayer', 'HasWMP', + 'hasSessionCookies', 'hasPersistentCookies' ] components.each do |k| v = get_param(@data['results'], k) @@ -366,6 +366,16 @@ module BeEF print_info "Autorun executed[#{autorun.join(', ')}] against Hooked browser [id:#{zombie.id}, ip:#{zombie.ip}, type:#{browser_name}-#{browser_version}, os:#{os_name}]" end end + + if config.get('beef.integration.phishing_frenzy.enable') + # get and store the browser plugins + victim_uid = get_param(@data['results'], 'PhishingFrenzyUID') + if BeEF::Filters.alphanums_only?(victim_uid) + BD.set(session_id, 'PhishingFrenzyUID', victim_uid) + else + self.err_msg "Invalid PhishingFrenzy Victim UID returned from the hook browser's initial connection." + end + end end def get_param(query, key) diff --git a/core/main/handlers/modules/beefjs.rb b/core/main/handlers/modules/beefjs.rb index ff7d57f12..7fb7f118a 100644 --- a/core/main/handlers/modules/beefjs.rb +++ b/core/main/handlers/modules/beefjs.rb @@ -38,7 +38,7 @@ module BeEF # @note If Evasion is enabled, the final ext_js string will be ext_js_to_obfuscate + ext_js_to_not_obfuscate # @note If Evasion is disabled, the final ext_js will be just ext_js_to_not_obfuscate - ext_js_sub_files.each{ |ext_js_sub_file| + ext_js_sub_files.each { |ext_js_sub_file| if config.get("beef.extension.evasion.enable") if config.get("beef.extension.evasion.exclude_core_js").include?(ext_js_sub_file) print_debug "Excluding #{ext_js_sub_file} from core files obfuscation list" @@ -103,6 +103,11 @@ module BeEF hook_session_config['websocket_sec_port']= config.get("beef.http.websocket.secure_port") end + # @note Set if PhishingFrenzy integration is enabled + if config.get("beef.integration.phishing_frenzy.enable") + hook_session_config['phishing_frenzy_enable'] = config.get("beef.integration.phishing_frenzy.enable") + end + # @note populate place holders in the beef_js string and set the response body eruby = Erubis::FastEruby.new(beef_js) @hook = eruby.evaluate(hook_session_config) diff --git a/core/main/rest/handlers/hookedbrowsers.rb b/core/main/rest/handlers/hookedbrowsers.rb index 9bc703a34..74abe896a 100644 --- a/core/main/rest/handlers/hookedbrowsers.rb +++ b/core/main/rest/handlers/hookedbrowsers.rb @@ -98,15 +98,15 @@ module BeEF details = BeEF::Core::Models::BrowserDetails { - 'id' => hb.id, - 'session' => hb.session, - 'name' => details.get(hb.session, 'BrowserName'), - 'version' => details.get(hb.session, 'BrowserVersion'), - 'os' => details.get(hb.session, 'OsName'), + 'id' => hb.id, + 'session' => hb.session, + 'name' => details.get(hb.session, 'BrowserName'), + 'version' => details.get(hb.session, 'BrowserVersion'), + 'os' => details.get(hb.session, 'OsName'), 'platform' => details.get(hb.session, 'BrowserPlatform'), - 'ip' => hb.ip, - 'domain' => details.get(hb.session, 'HostName'), - 'port' => hb.port.to_s, + 'ip' => hb.ip, + 'domain' => details.get(hb.session, 'HostName'), + 'port' => hb.port.to_s, 'page_uri' => details.get(hb.session, 'PageURI') } end @@ -129,7 +129,8 @@ module BeEF details.get(hb.session, 'LocationCity'), details.get(hb.session, 'LocationCountry'), details.get(hb.session, 'LocationLatitude'), - details.get(hb.session, 'LocationLongitude') + details.get(hb.session, 'LocationLongitude'), + details.get(hb.session, 'PhishingFrenzyUID') ] end hbs_online