|
1 | 1 | require 'extensions/requester/extension'
|
2 | 2 |
|
3 | 3 | RSpec.describe 'BeEF Extension Requester' do
|
4 |
| - |
5 | 4 | before(:all) do
|
6 | 5 | @config = BeEF::Core::Configuration.instance
|
7 | 6 | @config.load_extensions_config
|
|
18 | 17 | expect(requester).to respond_to(:requester_parse_db_request)
|
19 | 18 | end
|
20 | 19 |
|
21 |
| - # default skipped because browser hooking not working properly in travis-CI |
22 | 20 | xit 'requester works' do
|
23 |
| - # start beef server |
24 |
| - |
25 |
| - @config = BeEF::Core::Configuration.instance |
26 |
| - @config.set('beef.credentials.user', "beef") |
27 |
| - @config.set('beef.credentials.passwd', "beef") |
28 |
| - |
29 |
| - #generate api token |
30 |
| - BeEF::Core::Crypto::api_token |
31 |
| - |
32 |
| - # load up DB |
33 |
| - # Connect to DB |
34 |
| - ActiveRecord::Base.logger = nil |
35 |
| - OTR::ActiveRecord.migrations_paths = [File.join('core', 'main', 'ar-migrations')] |
36 |
| - OTR::ActiveRecord.configure_from_hash!(adapter:'sqlite3', database:'beef.db') |
37 |
| - # otr-activerecord require you to manually establish the connection with the following line |
38 |
| - #Also a check to confirm that the correct Gem version is installed to require it, likely easier for old systems. |
39 |
| - if Gem.loaded_specs['otr-activerecord'].version > Gem::Version.create('1.4.2') |
40 |
| - OTR::ActiveRecord.establish_connection! |
41 |
| - end |
42 |
| -# Migrate (if required) |
43 |
| - context = ActiveRecord::Migration.new.migration_context |
44 |
| - |
45 |
| - |
46 |
| - if context.needs_migration? |
47 |
| - puts "migrating db" |
48 |
| - ActiveRecord::Migrator.new(:up, context.migrations, context.schema_migration).migrate |
49 |
| - end |
50 |
| - |
51 |
| - |
52 |
| - http_hook_server = BeEF::Core::Server.instance |
53 |
| - http_hook_server.prepare |
54 |
| - @pids = fork do |
55 |
| - BeEF::API::Registrar.instance.fire(BeEF::API::Server, 'pre_http_start', http_hook_server) |
56 |
| - end |
57 |
| - @pid = fork do |
58 |
| - http_hook_server.start |
59 |
| - end |
60 |
| - # wait for server to start |
61 |
| - sleep 1 |
62 |
| - |
63 |
| - https = BeEF::Core::Models::Http |
64 |
| - |
65 |
| - ### hook a new victim, use rest API to send request ########### |
66 |
| - |
67 |
| - api = BeefRestClient.new('http', ATTACK_DOMAIN, '3000', BEEF_USER, BEEF_PASSWD) |
68 |
| - response = api.auth() |
69 |
| - @token = response[:token] |
70 |
| - puts "authenticated. api token: #{@token}" |
71 |
| - |
72 |
| - response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {:token => @token}} |
73 |
| - puts "hooks response: #{response}" |
74 |
| - hb_details = JSON.parse(response.body) |
75 |
| - puts "hb_details is empty: #{hb_details.empty?}" |
76 |
| - while hb_details["hooked-browsers"]["online"].empty? |
77 |
| - # get victim session |
78 |
| - response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {:token => @token}} |
79 |
| - puts "hooks response: #{response}" |
80 |
| - hb_details = JSON.parse(response.body) |
81 |
| - puts "json: #{hb_details}" |
82 |
| - puts "online hooked browsers empty: #{hb_details["hooked-browsers"]["online"].empty?}" |
83 |
| - |
| 21 | + begin |
| 22 | + # Start beef server |
| 23 | + @config = BeEF::Core::Configuration.instance |
| 24 | + @config.set('beef.credentials.user', 'beef') |
| 25 | + @config.set('beef.credentials.passwd', 'beef') |
84 | 26 |
|
| 27 | + # Generate API token |
| 28 | + BeEF::Core::Crypto::api_token |
| 29 | + |
| 30 | + # Connect to DB |
| 31 | + ActiveRecord::Base.logger = nil |
| 32 | + OTR::ActiveRecord.migrations_paths = [File.join('core', 'main', 'ar-migrations')] |
| 33 | + OTR::ActiveRecord.configure_from_hash!(adapter: 'sqlite3', database: 'beef.db') |
| 34 | + OTR::ActiveRecord.establish_connection! if Gem.loaded_specs['otr-activerecord'].version > Gem::Version.create('1.4.2') |
| 35 | + |
| 36 | + # Migrate if required |
| 37 | + context = ActiveRecord::Migration.new.migration_context |
| 38 | + ActiveRecord::Migrator.new(:up, context.migrations, context.schema_migration).migrate if context.needs_migration? |
| 39 | + |
| 40 | + # Start HTTP hook server |
| 41 | + http_hook_server = BeEF::Core::Server.instance |
| 42 | + http_hook_server.prepare |
| 43 | + @pids = fork { BeEF::API::Registrar.instance.fire(BeEF::API::Server, 'pre_http_start', http_hook_server) } |
| 44 | + @pid = fork { http_hook_server.start } |
| 45 | + |
| 46 | + # Wait for server to start |
| 47 | + sleep 2 |
| 48 | + |
| 49 | + # Hook a new victim and use REST API to send request |
| 50 | + api = BeefRestClient.new('http', ATTACK_DOMAIN, '3000', BEEF_USER, BEEF_PASSWD) |
| 51 | + response = api.auth() |
| 52 | + @token = response[:token] |
| 53 | + |
| 54 | + while (response = RestClient.get("#{RESTAPI_HOOKS}", {params: {token: @token}})) && |
| 55 | + (hb_details = JSON.parse(response.body)) && |
| 56 | + hb_details['hooked-browsers']['online'].empty? |
| 57 | + sleep 2 |
| 58 | + end |
| 59 | + |
| 60 | + hb_session = hb_details['hooked-browsers']['online']['0']['session'] |
| 61 | + randreq = (0...8).map { (65 + rand(26)).chr }.join |
| 62 | + RestClient.post("#{RESTAPI_REQUESTER}/send/#{hb_session}?token=#{@token}", "proto=http&raw_request=GET%20%2Ftest#{randreq}%20HTTP%2F1.1%0AHost%3A%20localhost%3A3000%0A") |
| 63 | + |
| 64 | + sleep 2 |
| 65 | + sent_request = RestClient.get("#{RESTAPI_REQUESTER}/requests/#{hb_session}?token=#{@token}") |
| 66 | + reqid = JSON.parse(sent_request)['requests'][0]['id'] |
| 67 | + |
| 68 | + response = RestClient.get("#{RESTAPI_REQUESTER}/response/#{reqid}?token=#{@token}") |
| 69 | + expect(response) |
| 70 | + ensure |
| 71 | + # Clean up |
| 72 | + BeEF::Core::Models::Http.where(hooked_browser_id: hb_session).delete_all if defined? hb_session |
| 73 | + Process.kill('KILL', @pid) if defined? @pid |
| 74 | + Process.kill('KILL', @pids) if defined? @pids |
85 | 75 | end
|
86 |
| - |
87 |
| - hb_session = hb_details["hooked-browsers"]["online"]["0"]["session"] |
88 |
| - |
89 |
| - puts "hooked browser: #{hb_session}" |
90 |
| - |
91 |
| - # clear all previous victim requests |
92 |
| - cleared = https.where(:hooked_browser_id => hb_session).delete_all |
93 |
| - puts "cleared #{cleared} previous request entries" |
94 |
| - |
95 |
| - # send a random request to localhost port 3000 |
96 |
| - randreq = (0...8).map { (65 + rand(26)).chr }.join |
97 |
| - |
98 |
| - response = RestClient.post "#{RESTAPI_REQUESTER}/send/#{hb_session}?token=#{@token}", "proto=http&raw_request=GET%20%2Ftest#{randreq}%20HTTP%2F1.1%0AHost%3A%20localhost%3A3000%0A" |
99 |
| - |
100 |
| - |
101 |
| - sleep 0.5 |
102 |
| - sent_request = RestClient.get "#{RESTAPI_REQUESTER}/requests/#{hb_session}?token=#{@token}" |
103 |
| - |
104 |
| - puts "request sent: #{sent_request.to_json}" |
105 |
| - sent_request = JSON.parse(sent_request) |
106 |
| - reqid = sent_request["requests"][0]["id"] |
107 |
| - |
108 |
| - puts "getting response for id #{reqid}" |
109 |
| - |
110 |
| - response = RestClient.get "#{RESTAPI_REQUESTER}/response/#{reqid}?token=#{@token}" |
111 |
| - |
112 |
| - expect(response) |
113 |
| - |
114 |
| - ############################################################### |
115 |
| - |
116 |
| - # cleanup: delete test browser entries |
117 |
| - https.where(:hooked_browser_id => hb_session).delete_all |
118 |
| - |
119 |
| - # kill the server |
120 |
| - Process.kill('KILL', @pid) |
121 |
| - Process.kill('KILL', @pids) |
122 |
| - |
123 |
| - puts "waiting for server to die.." |
124 |
| - sleep 1 |
125 | 76 | end
|
126 | 77 | end
|
0 commit comments