Path: blob/master/tools/rest_api_examples/lib/beef_rest_api.rb
1154 views
class BeefRestAPI12# initialize3def initialize proto = 'https', host = '127.0.0.1', port = '3000', user = 'beef', pass = 'beef'4@user = user5@pass = pass6@url = "#{proto}://#{host}:#{port}/api/"7@token = nil8end910################################################################################11### BeEF core API12################################################################################1314# authenticate and get API token15def auth16print_verbose "Retrieving authentication token"17begin18response = RestClient.post "#{@url}admin/login",19{ 'username' => "#{@user}",20'password' => "#{@pass}" }.to_json,21:content_type => :json,22:accept => :json23result = JSON.parse(response.body)24@token = result['token']25print_good "Retrieved RESTful API token: #{@token}"26rescue => e27print_error "Could not retrieve RESTful API token: #{e.message}"28end29end3031# get BeEF version32def version33begin34response = RestClient.get "#{@url}server/version", {:params => {:token => @token}}35result = JSON.parse(response.body)36print_good "Retrieved BeEF version: #{result['version']}"37result['version']38rescue => e39print_error "Could not retrieve BeEF version: #{e.message}"40end41end4243# get server mounts44def mounts45begin46response = RestClient.get "#{@url}server/mounts", {:params => {:token => @token}}47result = JSON.parse(response.body)48print_good "Retrieved BeEF server mounts: #{result['mounts']}"49result['mounts']50rescue => e51print_error "Could not retrieve BeEF version: #{e.message}"52end53end5455# get online hooked browsers56def online_browsers57begin58print_verbose "Retrieving online browsers"59response = RestClient.get "#{@url}hooks", {:params => {:token => @token}}60result = JSON.parse(response.body)61browsers = result["hooked-browsers"]["online"]62print_good "Retrieved online browser list [#{browsers.size} online]"63browsers64rescue => e65print_error "Could not retrieve browser details: #{e.message}"66end67end6869# get offline hooked browsers70def offline_browsers71begin72print_verbose "Retrieving offline browsers"73response = RestClient.get "#{@url}hooks", {:params => {:token => @token}}74result = JSON.parse(response.body)75browsers = result["hooked-browsers"]["offline"]76print_good "Retrieved offline browser list [#{browsers.size} offline]"77browsers78rescue => e79print_error "Could not retrieve browser details: #{e.message}"80end81end8283# get hooked browser details by session84def browser_details session85begin86print_verbose "Retrieving browser details for hooked browser [session: #{session}]"87response = RestClient.get "#{@url}browserdetails/#{session}", {:params => {:token => @token}}88result = JSON.parse(response.body)89details = result['details']90print_good "Retrieved #{details.size} browser details"91details92rescue => e93print_error "Could not retrieve browser details: #{e.message}"94end95end9697# delete a browser by session98def delete_browser session99begin100print_verbose "Removing hooked browser [session: #{session}]"101response = RestClient.get "#{@url}hooks/#{session}/delete", {:params => {:token => @token}}102print_good "Removed browser [session: #{session}]" if response.code == 200103response104rescue => e105print_error "Could not delete hooked browser: #{e.message}"106end107end108109# get BeEF logs110def logs111begin112print_verbose "Retrieving logs"113response = RestClient.get "#{@url}logs", {:params => {:token => @token}}114logs = JSON.parse(response.body)115print_good "Retrieved #{logs['logs_count']} log entries"116logs117rescue => e118print_error "Could not retrieve logs: #{e.message}"119end120end121122# get hooked browser logs by session123def browser_logs session124begin125print_verbose "Retrieving browser logs [session: #{session}]"126response = RestClient.get "#{@url}logs/#{session}", {:params => {:token => @token}}127logs = JSON.parse(response.body)128print_good "Retrieved #{logs['logs'].size} browser logs"129logs130rescue => e131print_error "Could not retrieve browser logs: #{e.message}"132end133end134135################################################################################136### command module API137################################################################################138139# get command module categories140def categories141begin142print_verbose "Retrieving module categories"143response = RestClient.get "#{@url}categories", {:params => {:token => @token}}144categories = JSON.parse(response.body)145print_good "Retrieved #{categories.size} module categories"146categories147rescue => e148print_error "Could not retrieve logs: #{e.message}"149end150end151152# get command modules153def modules154begin155print_verbose "Retrieving modules"156response = RestClient.get "#{@url}modules", {:params => {:token => @token}}157@modules = JSON.parse(response.body)158print_good "Retrieved #{@modules.size} available command modules"159@modules160rescue => e161print_error "Could not retrieve modules: #{e.message}"162end163end164165# get module id by module short name166def get_module_id mod_name167print_verbose "Retrieving id for module [name: #{mod_name}]"168@modules.each do |mod|169# normal modules170if mod_name.capitalize == mod[1]["class"]171return mod[1]["id"]172break173# metasploit modules174elsif mod[1]["class"] == "Msf_module" && mod_name.capitalize == mod[1]["name"]175return mod[1]["id"]176break177end178end179nil180end181182# get command module details183def module_details id184begin185print_verbose "Retrieving details for command module [id: #{id}]"186response = RestClient.get "#{@url}modules/#{id}", {:params => {:token => @token}}187details = JSON.parse(response.body)188print_good "Retrieved details for module [#{details['name']}]"189details190rescue => e191print_error "Could not retrieve modules: #{e.message}"192end193end194195# execute module196def execute_module session, mod_id, options197print_verbose "Executing module [id: #{mod_id}, #{options}]"198begin199response = RestClient.post "#{@url}modules/#{session}/#{mod_id}?token=#{@token}", options.to_json,200:content_type => :json,201:accept => :json202result = JSON.parse(response.body)203if result['success'] == 'true'204print_good "Executed module [id: #{mod_id}]"205else206print_error "Could not execute module [id: #{mod_id}]"207end208result209rescue => e210print_error "Could not start payload handler: #{e.message}"211end212end213214215################################################################################216### Metasploit API217################################################################################218219# get metasploit version220def msf_version221begin222response = RestClient.get "#{@url}msf/version", {:params => {:token => @token}}223result = JSON.parse(response.body)224version = result['version']['version']225print_good "Retrieved Metasploit version: #{version}"226version227rescue => e228print_error "Could not retrieve Metasploit version: #{e.message}"229end230end231232# get metasploit jobs233def msf_jobs234begin235response = RestClient.get "#{@url}msf/jobs", {:params => {:token => @token}}236result = JSON.parse(response.body)237jobs = result['jobs']238print_good "Retrieved job list [#{jobs.size} jobs]"239jobs240rescue => e241print_error "Could not retrieve Metasploit job list: #{e.message}"242end243end244245# get metasploit job info246def msf_job_info id247begin248response = RestClient.get "#{@url}msf/job/#{id}/info", {:params => {:token => @token}}249details = JSON.parse(response.body)250print_good "Retrieved job information [id: #{id}]"251details252rescue => e253print_error "Could not retrieve job info: #{e.message}"254end255end256257# start metasploit payload handler258def msf_handler options259print_verbose "Starting Metasploit payload handler [#{options}]"260begin261response = RestClient.post "#{@url}msf/handler?token=#{@token}", options.to_json,262:content_type => :json,263:accept => :json264result = JSON.parse(response.body)265job_id = result['id']266if job_id.nil?267print_error "Could not start payload handler: Job id is nil"268else269print_good "Started payload handler [id: #{job_id}]"270end271job_id272rescue => e273print_error "Could not start payload handler: #{e.message}"274end275end276277# stop metasploit job278def msf_job_stop id279print_verbose "Stopping Metasploit job [id: #{id}]"280begin281response = RestClient.get "#{@url}msf/job/#{id}/stop", {:params => {:token => @token}}282result = JSON.parse(response.body)283if result['success'].nil?284print_error "Could not stop Metasploit job [id: #{id}]: No such job ?"285else286print_good "Stopped job [id: #{id}]"287end288result289rescue => e290print_error "Could not stop Metasploit job [id: #{id}]: #{e.message}"291end292end293294295################################################################################296### Network API297################################################################################298299# get all network hosts300def network_hosts_all301begin302print_verbose "Retrieving all network hosts"303response = RestClient.get "#{@url}network/hosts", {:params => {:token => @token}}304details = JSON.parse(response.body)305print_good "Retrieved #{details['count']} network hosts"306details307rescue => e308print_error "Could not retrieve network hosts: #{e.message}"309end310end311312# get all network services313def network_services_all314begin315print_verbose "Retrieving all network services"316response = RestClient.get "#{@url}network/services", {:params => {:token => @token}}317details = JSON.parse(response.body)318print_good "Retrieved #{details['count']} network services"319details320rescue => e321print_error "Could not retrieve network services: #{e.message}"322end323end324325# get network hosts by session326def network_hosts session327begin328print_verbose "Retrieving network hosts for hooked browser [session: #{session}]"329response = RestClient.get "#{@url}network/hosts/#{session}", {:params => {:token => @token}}330details = JSON.parse(response.body)331print_good "Retrieved #{details['count']} network hosts"332details333rescue => e334print_error "Could not retrieve network hosts: #{e.message}"335end336end337338# get network services by session339def network_services session340begin341print_verbose "Retrieving network services for hooked browser [session: #{session}]"342response = RestClient.get "#{@url}network/services/#{session}", {:params => {:token => @token}}343details = JSON.parse(response.body)344print_good "Retrieved #{details['count']} network services"345details346rescue => e347print_error "Could not retrieve network services: #{e.message}"348end349end350351352################################################################################353### XssRays API354################################################################################355356# get all rays357def xssrays_rays_all358print_verbose "Retrieving all rays"359response = RestClient.get "#{@url}xssrays/rays", {:params => {:token => @token}}360details = JSON.parse(response.body)361print_good "Retrieved #{details['count']} rays"362details363rescue => e364print_error "Could not retrieve rays: #{e.message}"365end366367# get rays by session368def xssrays_rays session369print_verbose "Retrieving rays for hooked browser [session: #{session}]"370response = RestClient.get "#{@url}xssrays/rays/#{session}", {:params => {:token => @token}}371details = JSON.parse(response.body)372print_good "Retrieved #{details['count']} rays"373details374rescue => e375print_error "Could not retrieve rays: #{e.message}"376end377378# get all scans379def xssrays_scans_all380print_verbose "Retrieving all scans"381response = RestClient.get "#{@url}xssrays/scans", {:params => {:token => @token}}382details = JSON.parse(response.body)383print_good "Retrieved #{details['count']} scans"384details385rescue => e386print_error "Could not retrieve scans: #{e.message}"387end388389# get scans by session390def xssrays_scans session391print_verbose "Retrieving scans for hooked browser [session: #{session}]"392response = RestClient.get "#{@url}xssrays/scans/#{session}", {:params => {:token => @token}}393details = JSON.parse(response.body)394print_good "Retrieved #{details['count']} scans"395details396rescue => e397print_error "Could not retrieve scans: #{e.message}"398end399400401402################################################################################403### DNS API404################################################################################405406# get ruleset407def dns_ruleset408begin409print_verbose "Retrieving DNS ruleset"410response = RestClient.get "#{@url}dns/ruleset", {:params => {:token => @token}}411details = JSON.parse(response.body)412print_good "Retrieved #{details['count']} rules"413details414rescue => e415print_error "Could not retrieve DNS ruleset: #{e.message}"416end417end418419# add a rule420def dns_add_rule(dns_pattern, dns_resource, dns_response)421dns_response = [dns_response] if dns_response.is_a?(String)422print_verbose "Adding DNS rule [pattern: #{dns_pattern}, resource: #{dns_resource}, response: #{dns_response}]"423response = RestClient.post "#{@url}dns/rule?token=#{@token}", {424'pattern' => dns_pattern,425'resource' => dns_resource,426'response' => dns_response }.to_json,427:content_type => :json,428:accept => :json429details = JSON.parse(response.body)430rule_id = details['id']431432if rule_id.nil?433print_error("Could not add DNS rule: #{details['error']}")434return details435end436437print_good "Added rule [id: #{details['id']}]"438details439rescue => e440print_error "Could not add DNS rule: #{e.message}"441end442443# get rule details444def dns_get_rule(id)445begin446print_verbose "Retrieving DNS rule details [id: #{id}]"447response = RestClient.get "#{@url}dns/rule/#{id}", {:params => {:token => @token}}448details = JSON.parse(response.body)449print_good "Retrieved rule [id: #{details['id']}]"450details451rescue => e452print_error "Could not retrieve DNS rule: #{e.message}"453end454end455456# delete a rule457def dns_delete_rule(id)458response = RestClient.delete "#{@url}dns/rule/#{id}?token=#{@token}"459details = JSON.parse(response.body)460print_good "Deleted rule [id: #{id}]"461details462rescue => e463print_error "Could not delete DNS rule: #{e.message}"464end465466467################################################################################468### Autorun469################################################################################470471def autorun_rules472print_verbose "Retrieving Autorun rules"473response = RestClient.get "#{@url}autorun/rules", {:params => {:token => @token}}474details = JSON.parse(response.body)475print_good("Retrieved #{details['count']} rules")476details477rescue => e478print_error("Could not retrieve Autorun rules: #{e.message}")479end480481def autorun_delete_rule(id)482print_verbose "Deleting Autorun rule with ID: #{id}"483response = RestClient.delete "#{@url}autorun/rule/#{id}?token=#{@token}"484details = JSON.parse(response.body)485print_good("Deleted rule [id: #{id}]")486details487rescue => e488print_error("Could not delete Autorun rule: #{e.message}")489end490491def autorun_add_rule(data)492print_verbose "Adding Autorun rule: #{data}"493response = RestClient.post "#{@url}autorun/rule/add?token=#{@token}",494data.to_json,495:content_type => :json,496:accept => :json497details = JSON.parse(response.body)498rule_id = details['rule_id']499500if rule_id.nil?501print_error("Could not add Autorun rule: #{details['error']}")502return details503end504505print_good("Added rule [id: #{details['id']}]")506details507rescue => e508print_error("Could not add Autorun rule: #{e.message}")509end510511def autorun_run_rule_on_all_browsers(rule_id)512print_verbose "Running Autorun rule #{rule_id} on all browsers"513response = RestClient.get "#{@url}autorun/run/#{rule_id}", {:params => {:token => @token}}514details = JSON.parse(response.body)515print_debug details516print_good('Done')517details518rescue => e519print_error "Could not run Autorun rule #{rule_id}: #{e.message}"520end521522def autorun_run_rule_on_browser(rule_id, hb_id)523print_verbose "Running Autorun rule #{rule_id} on browser #{hb_id}"524response = RestClient.get "#{@url}autorun/run/#{rule_id}/#{hb_id}", {:params => {:token => @token}}525details = JSON.parse(response.body)526print_good('Done')527details528rescue => e529print_error "Could not run Autorun rule #{rule_id}: #{e.message}"530end531532533################################################################################534### WebRTC535################################################################################536537# get webrtc status for hooked browser by session538def webrtc_status id539begin540print_verbose "Retrieving status for hooked browser [id: #{id}]"541response = RestClient.get "#{@url}webrtc/status/#{id}", {:params => {:token => @token}}542details = JSON.parse(response.body)543print_good "Retrieved status for hooked browser [id: #{id}]"544details545rescue => e546print_error "Could not retrieve status: #{e.message}"547end548end549550################################################################################551### Social Engineering552################################################################################553554# bind dropper to path555def bind(fname, path)556print_verbose "Binding 'extensions/social_engineering/droppers/#{fname}' to '#{path}'"557begin558response = RestClient.post "#{@url}/server/bind?token=#{@token}",559{ 'mount' => "#{path}",560'local_file' => "#{fname}" }.to_json,561:content_type => :json,562:accept => :json563print_good "Bound '#{fname}' successfully" if response.code == 200564rescue => e565print_error "Could not bind file #{fname}: #{e.message}"566end567end568569# clone page and bind to path570def clone_page(url, path, use_existing, dns_spoof)571print_verbose "Binding '#{url}' to '#{path}'"572begin573response = RestClient.post "#{@url}/seng/clone_page?token=#{@token}",574{ 'mount' => "#{path}",575'url' => "#{url}",576'use_existing' => use_existing,577'dns_spoof' => dns_spoof }.to_json,578:content_type => :json,579:accept => :json580print_good "Bound '#{url}' successfully" if response.code == 200581rescue => e582print_error "Could not bind URL #{url}: #{e.message}"583end584end585586end587588589