@@ -8,45 +8,42 @@
|
|||||||
* The XssRays Tab panel for the selected zombie.
|
* The XssRays Tab panel for the selected zombie.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//TODO: fix positioning issues, probably because we are not creating a nested (fucking) panel
|
|
||||||
ZombieTab_XssRaysTab = function(zombie) {
|
ZombieTab_XssRaysTab = function(zombie) {
|
||||||
|
var commands_statusbar = new Beef_StatusBar('xssrays-bbar-zombie-'+zombie.session);
|
||||||
|
var req_pagesize = 30;
|
||||||
|
|
||||||
var commands_statusbar = new Beef_StatusBar('xssrays-bbar-zombie-'+zombie.session);
|
// RESTful API token
|
||||||
|
var token = BeefWUI.get_rest_token();
|
||||||
|
|
||||||
var req_pagesize = 30;
|
var xssrays_config_panel = new Ext.Panel({
|
||||||
|
id: 'xssrays-config-zombie-'+zombie.session,
|
||||||
|
title: 'Scan Config',
|
||||||
|
layout: 'fit'
|
||||||
|
});
|
||||||
|
|
||||||
var xssrays_config_panel = new Ext.Panel({
|
var xssrays_logs_store = new Ext.ux.data.PagingJsonStore({
|
||||||
id: 'xssrays-config-zombie-'+zombie.session,
|
storeId: 'xssrays-logs-store-zombie-' + zombie.session,
|
||||||
title: 'Scan Config',
|
remoteSort: false,
|
||||||
layout: 'fit'
|
autoDestroy: true,
|
||||||
});
|
autoLoad: false,
|
||||||
|
proxy: new Ext.data.HttpProxy({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/api/xssrays/rays/' + zombie.session + '?token=' + token
|
||||||
|
}),
|
||||||
|
root: 'rays',
|
||||||
|
fields: ['id', 'vector_method', 'vector_name', 'vector_poc'],
|
||||||
|
sortInfo: {field: 'id', direction: 'DESC'},
|
||||||
|
});
|
||||||
|
|
||||||
var xssrays_logs_store = new Ext.ux.data.PagingJsonStore({
|
var xssrays_logs_bbar = new Ext.PagingToolbar({
|
||||||
storeId: 'xssrays-logs-store-zombie-' + zombie.session,
|
pageSize: req_pagesize,
|
||||||
url: '<%= @base_path %>/xssrays/zombie.json',
|
store: xssrays_logs_store,
|
||||||
remoteSort: false,
|
displayInfo: true,
|
||||||
autoDestroy: true,
|
displayMsg: 'Displaying history {0} - {1} of {2}',
|
||||||
autoLoad: false,
|
emptyMsg: 'No history to display'
|
||||||
root: 'logs',
|
});
|
||||||
|
|
||||||
fields: ['id', 'vector_method', 'vector_name', 'vector_poc'],
|
var xssrays_logs_grid = new Ext.grid.GridPanel({
|
||||||
sortInfo: {field: 'id', direction: 'DESC'},
|
|
||||||
|
|
||||||
baseParams: {
|
|
||||||
nonce: Ext.get("nonce").dom.value,
|
|
||||||
zombie_session: zombie.session
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var xssrays_logs_bbar = new Ext.PagingToolbar({
|
|
||||||
pageSize: req_pagesize,
|
|
||||||
store: xssrays_logs_store,
|
|
||||||
displayInfo: true,
|
|
||||||
displayMsg: 'Displaying history {0} - {1} of {2}',
|
|
||||||
emptyMsg: 'No history to display'
|
|
||||||
});
|
|
||||||
|
|
||||||
var xssrays_logs_grid = new Ext.grid.GridPanel({
|
|
||||||
id: 'xssrays-logs-grid-zombie-' + zombie.session,
|
id: 'xssrays-logs-grid-zombie-' + zombie.session,
|
||||||
store: xssrays_logs_store,
|
store: xssrays_logs_store,
|
||||||
bbar: xssrays_logs_bbar,
|
bbar: xssrays_logs_bbar,
|
||||||
@@ -75,9 +72,9 @@ ZombieTab_XssRaysTab = function(zombie) {
|
|||||||
datagrid.store.reload({params:{start:0,limit:req_pagesize, sort: "date", dir:"DESC"}});
|
datagrid.store.reload({params:{start:0,limit:req_pagesize, sort: "date", dir:"DESC"}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var xssrays_logs_panel = new Ext.Panel({
|
var xssrays_logs_panel = new Ext.Panel({
|
||||||
id: 'xssrays-logs-panel-zombie-'+zombie.session,
|
id: 'xssrays-logs-panel-zombie-'+zombie.session,
|
||||||
title: 'Logs',
|
title: 'Logs',
|
||||||
items:[xssrays_logs_grid],
|
items:[xssrays_logs_grid],
|
||||||
@@ -88,9 +85,9 @@ ZombieTab_XssRaysTab = function(zombie) {
|
|||||||
xssrays_logs_panel.items.items[0].store.reload();
|
xssrays_logs_panel.items.items[0].store.reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function genScanSettingsPanel(zombie, bar, value) {
|
function genScanSettingsPanel(zombie, bar, value) {
|
||||||
var form = new Ext.FormPanel({
|
var form = new Ext.FormPanel({
|
||||||
title: 'Scan settings',
|
title: 'Scan settings',
|
||||||
id: 'xssrays-config-form-zombie'+zombie.session,
|
id: 'xssrays-config-form-zombie'+zombie.session,
|
||||||
@@ -157,7 +154,7 @@ ZombieTab_XssRaysTab = function(zombie) {
|
|||||||
genScanSettingsPanel(zombie, commands_statusbar);
|
genScanSettingsPanel(zombie, commands_statusbar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Ext.extend(ZombieTab_XssRaysTab, Ext.TabPanel, {} );
|
Ext.extend(ZombieTab_XssRaysTab, Ext.TabPanel, {} );
|
||||||
|
|||||||
@@ -6,22 +6,24 @@
|
|||||||
module BeEF
|
module BeEF
|
||||||
module Extension
|
module Extension
|
||||||
module Xssrays
|
module Xssrays
|
||||||
|
|
||||||
module RegisterHttpHandler
|
module RegisterHttpHandler
|
||||||
|
|
||||||
BeEF::API::Registrar.instance.register(BeEF::Extension::Xssrays::RegisterHttpHandler, BeEF::API::Server, 'mount_handler')
|
BeEF::API::Registrar.instance.register(BeEF::Extension::Xssrays::RegisterHttpHandler, BeEF::API::Server, 'mount_handler')
|
||||||
|
|
||||||
# We register the http handler for the requester.
|
#
|
||||||
# This http handler will retrieve the http responses for all requests
|
# Mounts the handlers and REST interface for processing XSS rays
|
||||||
|
#
|
||||||
|
# @param beef_server [BeEF::Core::Server] HTTP server instance
|
||||||
|
#
|
||||||
def self.mount_handler(beef_server)
|
def self.mount_handler(beef_server)
|
||||||
|
# We register the http handler for the requester.
|
||||||
|
# This http handler will retrieve the http responses for all requests
|
||||||
beef_server.mount('/xssrays', BeEF::Extension::Xssrays::Handler.new)
|
beef_server.mount('/xssrays', BeEF::Extension::Xssrays::Handler.new)
|
||||||
|
# REST API endpoint
|
||||||
|
beef_server.mount('/api/xssrays', BeEF::Extension::Xssrays::XssraysRest.new)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
module RegisterPreHookCallback
|
module RegisterPreHookCallback
|
||||||
|
|
||||||
BeEF::API::Registrar.instance.register(BeEF::Extension::Xssrays::RegisterPreHookCallback, BeEF::API::Server::Hook, 'pre_hook_send')
|
BeEF::API::Registrar.instance.register(BeEF::Extension::Xssrays::RegisterPreHookCallback, BeEF::API::Server::Hook, 'pre_hook_send')
|
||||||
|
|
||||||
# checks at every polling if there are new scans to be started
|
# checks at every polling if there are new scans to be started
|
||||||
@@ -31,9 +33,7 @@ module Xssrays
|
|||||||
xssrays.start_scan(hooked_browser, body)
|
xssrays.start_scan(hooked_browser, body)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -22,64 +22,43 @@ class Xssrays < BeEF::Extension::AdminUI::HttpController
|
|||||||
super({
|
super({
|
||||||
'paths' => {
|
'paths' => {
|
||||||
'/set_scan_target' => method(:set_scan_target),
|
'/set_scan_target' => method(:set_scan_target),
|
||||||
'/zombie.json' => method(:get_xssrays_logs),
|
|
||||||
'/createNewScan' => method(:create_new_scan)
|
'/createNewScan' => method(:create_new_scan)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
# called by the UI when rendering xssrays_details table content in the XssRays zombie tab
|
# called by the UI. needed to pass the hooked browser ID/session and store a new scan in the DB.
|
||||||
def get_xssrays_logs
|
# This is called when right-clicking the hooked browser from the tree.
|
||||||
# validate nonce
|
# Default config options are read from config.yaml
|
||||||
nonce = @params['nonce'] || nil
|
def set_scan_target
|
||||||
(print_error "nonce is nil";return @body = {'success' => 'false'}.to_json) if nonce.nil?
|
|
||||||
(print_error "nonce incorrect";return @body = {'success' => 'false'}.to_json) if @session.get_nonce != nonce
|
|
||||||
|
|
||||||
# validate that the hooked browser's session has been sent
|
|
||||||
zombie_session = @params['zombie_session'] || nil
|
|
||||||
(print_error "Zombie session is nil";return @body = {'success' => 'false'}.to_json) if zombie_session.nil?
|
|
||||||
|
|
||||||
# validate that the hooked browser exists in the db
|
|
||||||
zombie = Z.first(:session => zombie_session) || nil
|
|
||||||
(print_error "Invalid hooked browser session";return @body = {'success' => 'false'}.to_json) if zombie.nil?
|
|
||||||
|
|
||||||
logs = []
|
|
||||||
BeEF::Core::Models::Xssraysdetail.all(:hooked_browser_id => zombie.id).each{|log|
|
|
||||||
logs << {
|
|
||||||
'id' => log.id,
|
|
||||||
'vector_method' => log.vector_method,
|
|
||||||
'vector_name' => log.vector_name,
|
|
||||||
'vector_poc' => log.vector_poc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@body = {'success' => 'true', 'logs' => logs}.to_json
|
|
||||||
end
|
|
||||||
|
|
||||||
# called by the UI. needed to pass the hooked browser ID/session and store a new scan in the DB.
|
|
||||||
# This is called when right-clicking the hooked browser from the tree. Default config options are read from config.yaml
|
|
||||||
def set_scan_target
|
|
||||||
hooked_browser = HB.first(:session => @params['hb_id'].to_s)
|
hooked_browser = HB.first(:session => @params['hb_id'].to_s)
|
||||||
if(hooked_browser != nil)
|
|
||||||
xssrays_scan = XS.new(
|
|
||||||
:hooked_browser_id => hooked_browser.id,
|
|
||||||
:scan_start => Time.now,
|
|
||||||
:domain => hooked_browser.domain,
|
|
||||||
:cross_domain => CROSS_DOMAIN, #check also cross-domain URIs found by the spider
|
|
||||||
:clean_timeout => CLEAN_TIMEOUT #check also cross-domain URIs found by the spider
|
|
||||||
)
|
|
||||||
xssrays_scan.save
|
|
||||||
|
|
||||||
print_info("[XSSRAYS] Starting XSSRays [ip:#{hooked_browser.ip.to_s}], hooked domain [#{hooked_browser.domain.to_s}]")
|
if hooked_browser.nil?
|
||||||
|
print_error "[XSSRAYS] Invalid hooked browser ID"
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
xssrays_scan = XS.new(
|
||||||
|
:hooked_browser_id => hooked_browser.id,
|
||||||
|
:scan_start => Time.now,
|
||||||
|
:domain => hooked_browser.domain,
|
||||||
|
:cross_domain => CROSS_DOMAIN, #check also cross-domain URIs found by the spider
|
||||||
|
:clean_timeout => CLEAN_TIMEOUT #check also cross-domain URIs found by the spider
|
||||||
|
)
|
||||||
|
xssrays_scan.save
|
||||||
|
|
||||||
# called by the UI, in the XssRays zombie tab
|
print_info("[XSSRAYS] Starting XSSRays [ip:#{hooked_browser.ip}], hooked domain [#{hooked_browser.domain}]")
|
||||||
# Needed if we want to start a scan overriding default scan parameters without rebooting BeEF
|
end
|
||||||
|
|
||||||
|
# called by the UI, in the XssRays zombie tab
|
||||||
|
# Needed if we want to start a scan overriding default scan parameters without rebooting BeEF
|
||||||
def create_new_scan
|
def create_new_scan
|
||||||
hooked_browser = HB.first(:session => @params['zombie_session'].to_s)
|
hooked_browser = HB.first(:session => @params['zombie_session'].to_s)
|
||||||
if(hooked_browser != nil)
|
|
||||||
|
if hooked_browser.nil?
|
||||||
|
print_error "[XSSRAYS] Invalid hooked browser ID"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
# set Cross-domain settings
|
# set Cross-domain settings
|
||||||
cross_domain = @params['cross_domain']
|
cross_domain = @params['cross_domain']
|
||||||
@@ -106,8 +85,7 @@ class Xssrays < BeEF::Extension::AdminUI::HttpController
|
|||||||
)
|
)
|
||||||
xssrays_scan.save
|
xssrays_scan.save
|
||||||
|
|
||||||
print_info("[XSSRAYS] Starting XSSRays [ip:#{hooked_browser.ip.to_s}], hooked domain [#{hooked_browser.domain.to_s}]")
|
print_info("[XSSRAYS] Starting XSSRays [ip:#{hooked_browser.ip}], hooked domain [#{hooked_browser.domain}]")
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -16,3 +16,5 @@ require 'extensions/xssrays/models/xssraysdetail'
|
|||||||
require 'extensions/xssrays/api/scan'
|
require 'extensions/xssrays/api/scan'
|
||||||
require 'extensions/xssrays/handler'
|
require 'extensions/xssrays/handler'
|
||||||
require 'extensions/xssrays/api'
|
require 'extensions/xssrays/api'
|
||||||
|
require 'extensions/xssrays/rest/xssrays'
|
||||||
|
|
||||||
|
|||||||
@@ -56,16 +56,20 @@ module BeEF
|
|||||||
xssrays_scan = XS.first(:id => rays_scan_id)
|
xssrays_scan = XS.first(:id => rays_scan_id)
|
||||||
hooked_browser = HB.first(:session => params[:hbsess])
|
hooked_browser = HB.first(:session => params[:hbsess])
|
||||||
|
|
||||||
if (xssrays_scan != nil)
|
if xssrays_scan.nil?
|
||||||
xssrays_detail = XD.new(
|
print_error "[XSSRAYS] Invalid scan"
|
||||||
:hooked_browser_id => hooked_browser.id,
|
return
|
||||||
:vector_name => params[:n],
|
|
||||||
:vector_method => params[:m],
|
|
||||||
:vector_poc => params[:p],
|
|
||||||
:xssraysscan_id => xssrays_scan.id
|
|
||||||
)
|
|
||||||
xssrays_detail.save
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
xssrays_detail = XD.new(
|
||||||
|
:hooked_browser_id => hooked_browser.session,
|
||||||
|
:vector_name => params[:n],
|
||||||
|
:vector_method => params[:m],
|
||||||
|
:vector_poc => params[:p],
|
||||||
|
:xssraysscan_id => xssrays_scan.id
|
||||||
|
)
|
||||||
|
xssrays_detail.save
|
||||||
|
|
||||||
print_info("[XSSRAYS] Scan id [#{xssrays_scan.id}] received ray [ip:#{hooked_browser.ip}], hooked domain [#{hooked_browser.domain}]")
|
print_info("[XSSRAYS] Scan id [#{xssrays_scan.id}] received ray [ip:#{hooked_browser.ip}], hooked domain [#{hooked_browser.domain}]")
|
||||||
print_debug("[XSSRAYS] Ray info: \n #{request.query_string}")
|
print_debug("[XSSRAYS] Ray info: \n #{request.query_string}")
|
||||||
end
|
end
|
||||||
@@ -74,10 +78,13 @@ module BeEF
|
|||||||
def finalize_scan(rays_scan_id)
|
def finalize_scan(rays_scan_id)
|
||||||
xssrays_scan = BeEF::Core::Models::Xssraysscan.first(:id => rays_scan_id)
|
xssrays_scan = BeEF::Core::Models::Xssraysscan.first(:id => rays_scan_id)
|
||||||
|
|
||||||
if (xssrays_scan != nil)
|
if xssrays_scan.nil?
|
||||||
xssrays_scan.update(:is_finished => true, :scan_finish => Time.now)
|
print_error "[XSSRAYS] Invalid scan"
|
||||||
print_info("[XSSRAYS] Scan id [#{xssrays_scan.id}] finished at [#{xssrays_scan.scan_finish}]")
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
xssrays_scan.update(:is_finished => true, :scan_finish => Time.now)
|
||||||
|
print_info("[XSSRAYS] Scan id [#{xssrays_scan.id}] finished at [#{xssrays_scan.scan_finish}]")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
184
extensions/xssrays/rest/xssrays.rb
Normal file
184
extensions/xssrays/rest/xssrays.rb
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
#
|
||||||
|
# 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 Extension
|
||||||
|
module Xssrays
|
||||||
|
|
||||||
|
# This class handles the routing of RESTful API requests for XssRays
|
||||||
|
class XssraysRest < BeEF::Core::Router::Router
|
||||||
|
|
||||||
|
HB = BeEF::Core::Models::HookedBrowser
|
||||||
|
XS = BeEF::Core::Models::Xssraysscan
|
||||||
|
XD = BeEF::Core::Models::Xssraysdetail
|
||||||
|
|
||||||
|
# Filters out bad requests before performing any routing
|
||||||
|
before do
|
||||||
|
config = BeEF::Core::Configuration.instance
|
||||||
|
@nh = BeEF::Core::Models::NetworkHost
|
||||||
|
@ns = BeEF::Core::Models::NetworkService
|
||||||
|
|
||||||
|
# Require a valid API token from a valid IP address
|
||||||
|
halt 401 unless params[:token] == config.get('beef.api_token')
|
||||||
|
halt 403 unless BeEF::Core::Rest.permitted_source?(request.ip)
|
||||||
|
|
||||||
|
headers 'Content-Type' => 'application/json; charset=UTF-8',
|
||||||
|
'Pragma' => 'no-cache',
|
||||||
|
'Cache-Control' => 'no-cache',
|
||||||
|
'Expires' => '0'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the entire list of rays for all zombies
|
||||||
|
get '/rays' do
|
||||||
|
begin
|
||||||
|
rays = XD.all(:unique => true, :order => [:id.asc])
|
||||||
|
count = rays.length
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
result[:count] = count
|
||||||
|
result[:rays] = []
|
||||||
|
rays.each do |ray|
|
||||||
|
result[:rays] << ray2hash(ray)
|
||||||
|
end
|
||||||
|
result.to_json
|
||||||
|
rescue StandardError => e
|
||||||
|
print_error "Internal error while retrieving rays (#{e.message})"
|
||||||
|
halt 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns all rays given a specific hooked browser id
|
||||||
|
get '/rays/:id' do
|
||||||
|
begin
|
||||||
|
id = params[:id]
|
||||||
|
|
||||||
|
rays = XD.all(:hooked_browser_id => id, :unique => true, :order => [:id.asc])
|
||||||
|
count = rays.length
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
result[:count] = count
|
||||||
|
result[:rays] = []
|
||||||
|
rays.each do |ray|
|
||||||
|
result[:rays] << ray2hash(ray)
|
||||||
|
end
|
||||||
|
result.to_json
|
||||||
|
rescue InvalidParamError => e
|
||||||
|
print_error e.message
|
||||||
|
halt 400
|
||||||
|
rescue StandardError => e
|
||||||
|
print_error "Internal error while retrieving rays list for hooked browser with id #{id} (#{e.message})"
|
||||||
|
halt 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the entire list of scans for all zombies
|
||||||
|
get '/scans' do
|
||||||
|
begin
|
||||||
|
scans = XS.all(:unique => true, :order => [:id.asc])
|
||||||
|
count = scans.length
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
result[:count] = count
|
||||||
|
result[:scans] = []
|
||||||
|
scans.each do |scan|
|
||||||
|
result[:scans] << scan2hash(scan)
|
||||||
|
end
|
||||||
|
result.to_json
|
||||||
|
rescue StandardError => e
|
||||||
|
print_error "Internal error while retrieving scans (#{e.message})"
|
||||||
|
halt 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns all scans given a specific hooked browser id
|
||||||
|
get '/scans/:id' do
|
||||||
|
begin
|
||||||
|
id = params[:id]
|
||||||
|
|
||||||
|
scans = XS.all(:hooked_browser_id => id, :unique => true, :order => [:id.asc])
|
||||||
|
count = scans.length
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
result[:count] = count
|
||||||
|
result[:scans] = []
|
||||||
|
scans.each do |scans|
|
||||||
|
result[:scans] << scan2hash(scan)
|
||||||
|
end
|
||||||
|
result.to_json
|
||||||
|
rescue InvalidParamError => e
|
||||||
|
print_error e.message
|
||||||
|
halt 400
|
||||||
|
rescue StandardError => e
|
||||||
|
print_error "Internal error while retrieving scans list for hooked browser with id #{id} (#{e.message})"
|
||||||
|
halt 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Starts a new scan on the specified zombie ID
|
||||||
|
=begin
|
||||||
|
post '/scan/:id' do
|
||||||
|
begin
|
||||||
|
# TODO
|
||||||
|
rescue InvalidParamError => e
|
||||||
|
print_error e.message
|
||||||
|
halt 400
|
||||||
|
rescue StandardError => e
|
||||||
|
print_error "Internal error while retrieving host with id #{id} (#{e.message})"
|
||||||
|
halt 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
=end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Convert a ray object to JSON
|
||||||
|
def ray2hash(ray)
|
||||||
|
{
|
||||||
|
:id => ray.id,
|
||||||
|
:hooked_browser_id => ray.hooked_browser_id,
|
||||||
|
:vector_name => ray.vector_name,
|
||||||
|
:vector_method => ray.vector_method,
|
||||||
|
:vector_poc => ray.vector_poc
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Convert a scan object to JSON
|
||||||
|
def scan2hash(scan)
|
||||||
|
{
|
||||||
|
:id => scan.id,
|
||||||
|
:hooked_browser_id => scan.hooked_browser_id,
|
||||||
|
:scan_start=> scan.scan_start,
|
||||||
|
:scan_finish=> scan.scan_finish,
|
||||||
|
:domain => scan.domain,
|
||||||
|
:cross_domain => scan.cross_domain,
|
||||||
|
:clean_timeout => scan.clean_timeout,
|
||||||
|
:is_started => scan.is_started,
|
||||||
|
:is_finished => scan.is_finished
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Raised when invalid JSON input is passed to an /api/xssrays handler.
|
||||||
|
class InvalidJsonError < StandardError
|
||||||
|
DEFAULT_MESSAGE = 'Invalid JSON input passed to /api/xssrays handler'
|
||||||
|
|
||||||
|
def initialize(message = nil)
|
||||||
|
super(message || DEFAULT_MESSAGE)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Raised when an invalid named parameter is passed to an /api/xssrays handler.
|
||||||
|
class InvalidParamError < StandardError
|
||||||
|
DEFAULT_MESSAGE = 'Invalid parameter passed to /api/xssrays handler'
|
||||||
|
|
||||||
|
def initialize(message = nil)
|
||||||
|
str = "Invalid \"%s\" parameter passed to /api/xssrays handler"
|
||||||
|
message = sprintf str, message unless message.nil?
|
||||||
|
super(message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -348,6 +348,57 @@ def network_services session
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
### XssRays API
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# get all rays
|
||||||
|
def xssrays_rays_all
|
||||||
|
print_verbose "Retrieving all rays"
|
||||||
|
response = RestClient.get "#{@url}xssrays/rays", {:params => {:token => @token}}
|
||||||
|
details = JSON.parse(response.body)
|
||||||
|
print_good "Retrieved #{details['count']} rays"
|
||||||
|
details
|
||||||
|
rescue => e
|
||||||
|
print_error "Could not retrieve rays: #{e.message}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# get rays by session
|
||||||
|
def xssrays_rays session
|
||||||
|
print_verbose "Retrieving rays for hooked browser [session: #{session}]"
|
||||||
|
response = RestClient.get "#{@url}xssrays/rays/#{session}", {:params => {:token => @token}}
|
||||||
|
details = JSON.parse(response.body)
|
||||||
|
print_good "Retrieved #{details['count']} rays"
|
||||||
|
details
|
||||||
|
rescue => e
|
||||||
|
print_error "Could not retrieve rays: #{e.message}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# get all scans
|
||||||
|
def xssrays_scans_all
|
||||||
|
print_verbose "Retrieving all scans"
|
||||||
|
response = RestClient.get "#{@url}xssrays/scans", {:params => {:token => @token}}
|
||||||
|
details = JSON.parse(response.body)
|
||||||
|
print_good "Retrieved #{details['count']} scans"
|
||||||
|
details
|
||||||
|
rescue => e
|
||||||
|
print_error "Could not retrieve scans: #{e.message}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# get scans by session
|
||||||
|
def xssrays_scans session
|
||||||
|
print_verbose "Retrieving scans for hooked browser [session: #{session}]"
|
||||||
|
response = RestClient.get "#{@url}xssrays/scans/#{session}", {:params => {:token => @token}}
|
||||||
|
details = JSON.parse(response.body)
|
||||||
|
print_good "Retrieved #{details['count']} scans"
|
||||||
|
details
|
||||||
|
rescue => e
|
||||||
|
print_error "Could not retrieve scans: #{e.message}"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
### DNS API
|
### DNS API
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|||||||
104
tools/rest_api_examples/xssrays
Executable file
104
tools/rest_api_examples/xssrays
Executable file
@@ -0,0 +1,104 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
# xssrays - Example BeEF RESTful API script
|
||||||
|
# Refer to the wiki for info: https://github.com/beefproject/beef/wiki/BeEF-RESTful-API
|
||||||
|
##
|
||||||
|
require 'rest-client'
|
||||||
|
require 'json'
|
||||||
|
require 'optparse'
|
||||||
|
require 'pp'
|
||||||
|
require './lib/string' # colored strings
|
||||||
|
require './lib/print' # print wrappers
|
||||||
|
require './lib/beef_rest_api'
|
||||||
|
|
||||||
|
if ARGV.length == 0
|
||||||
|
puts "#{$0}:"
|
||||||
|
puts "| Example BeEF RESTful API script"
|
||||||
|
puts "| Use --help for help"
|
||||||
|
puts "|_ Use verbose mode (-v) and debug mode (-d) for more output"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
# API config
|
||||||
|
proto = 'http'
|
||||||
|
host = '127.0.0.1'
|
||||||
|
port = '3000'
|
||||||
|
user = 'beef'
|
||||||
|
pass = 'beef'
|
||||||
|
|
||||||
|
# Command line options
|
||||||
|
@debug = false
|
||||||
|
@verbose = false
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.on('-h', '--help', 'Shows this help screen') do
|
||||||
|
puts opts
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
opts.on('--host HOST', "Set BeEF host (default: #{host})") do |h|
|
||||||
|
host = h
|
||||||
|
end
|
||||||
|
opts.on('--port PORT', "Set BeEF port (default: #{port})") do |p|
|
||||||
|
port = p
|
||||||
|
end
|
||||||
|
opts.on('--user USERNAME', "Set BeEF username (default: #{user})") do |u|
|
||||||
|
user = u
|
||||||
|
end
|
||||||
|
opts.on('--pass PASSWORD', "Set BeEF password (default: #{pass})") do |p|
|
||||||
|
pass = p
|
||||||
|
end
|
||||||
|
opts.on('--ssl', 'Use HTTPS') do
|
||||||
|
proto = 'https'
|
||||||
|
end
|
||||||
|
opts.on('-v', '--verbose', 'Enable verbose output') do
|
||||||
|
@verbose = true
|
||||||
|
end
|
||||||
|
opts.on('-d', '--debug', 'Enable debug output') do
|
||||||
|
@debug = true
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
@api = BeefRestAPI.new proto, host, port, user, pass
|
||||||
|
|
||||||
|
# Retrieve the RESTful API token
|
||||||
|
print_status "Authenticating to: #{proto}://#{host}:#{port}"
|
||||||
|
@api.auth
|
||||||
|
|
||||||
|
# Retrieve BeEF version
|
||||||
|
@api.version
|
||||||
|
|
||||||
|
# Retrieve all scans
|
||||||
|
scans = @api.xssrays_scans_all
|
||||||
|
print_debug scans
|
||||||
|
|
||||||
|
# Retrieve all rays
|
||||||
|
rays = @api.xssrays_rays_all
|
||||||
|
print_debug rays
|
||||||
|
|
||||||
|
# Retrieve online hooked browser list
|
||||||
|
hooks = @api.online_browsers.flatten
|
||||||
|
exit 1 if hooks.empty?
|
||||||
|
print_debug hooks
|
||||||
|
|
||||||
|
# Retrieve rays for each hooked browser
|
||||||
|
hooks.each do |hook|
|
||||||
|
next if hook['id'].nil?
|
||||||
|
print_status "Retrieving rays for browser [id: #{hook['id']}]"
|
||||||
|
rays = @api.xssrays_rays(hook['session'])
|
||||||
|
print_debug rays
|
||||||
|
rays['rays'].each do |ray|
|
||||||
|
next if ray['id'].nil?
|
||||||
|
print_verbose "#{ray['vector_name']} (#{ray['vector_method']})"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Retrieve scans for each hooked browser
|
||||||
|
hooks.each do |hook|
|
||||||
|
next if hook['id'].nil?
|
||||||
|
print_status "Retrieving scans for browser [id: #{hook['id']}]"
|
||||||
|
scans = @api.xssrays_scans(hook['session'])
|
||||||
|
print_debug scans
|
||||||
|
scans['scans'].each do |scan|
|
||||||
|
next if scan['id'].nil?
|
||||||
|
print_verbose "Scan [#{scan['id']}] on domain #{scan['domain']}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
Reference in New Issue
Block a user