Merge branch 'rspec-conversion'
* Converted tests to rspec for future releases + travis integration. * Files remaining in test/ are integrations that require verification if they are still relevant/working.
This commit is contained in:
62
spec/beef/api/auth_rate_spec.rb
Normal file
62
spec/beef/api/auth_rate_spec.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
#
|
||||
# Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
RSpec.describe 'BeEF API Rate Limit' do
|
||||
|
||||
before(:all) do
|
||||
DataMapper.setup(:default, 'sqlite3::memory:')
|
||||
DataMapper.auto_migrate!
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
http_hook_server = BeEF::Core::Server.instance
|
||||
http_hook_server.prepare
|
||||
BeEF::API::Registrar.instance.fire(BeEF::API::Server, 'pre_http_start', http_hook_server)
|
||||
@pid = fork do
|
||||
http_hook_server.start
|
||||
end
|
||||
# wait for server to start
|
||||
sleep 1
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
Process.kill("INT",@pid)
|
||||
end
|
||||
|
||||
it 'adheres to auth rate limits' do
|
||||
passwds = (1..9).map { |i| "broken_pass"}
|
||||
passwds.push BEEF_PASSWD
|
||||
apis = passwds.map { |pswd| BeefRestClient.new('http', ATTACK_DOMAIN, '3000', BEEF_USER, pswd) }
|
||||
l = apis.length
|
||||
(0..2).each do |again| # multiple sets of auth attempts
|
||||
# first pass -- apis in order, valid passwd on 9th attempt
|
||||
# subsequent passes apis shuffled
|
||||
puts "speed requesets" # all should return 401
|
||||
(0..50).each do |i|
|
||||
# t = Time.now()
|
||||
#puts "#{i} : #{t - t0} : #{apis[i%l].auth()[:payload]}"
|
||||
test_api = apis[i%l]
|
||||
expect(test_api.auth()[:payload]).to eql("401 Unauthorized") # all (unless the valid is first 1 in 10 chance)
|
||||
# t0 = t
|
||||
end
|
||||
# again with more time between calls -- there should be success (1st iteration)
|
||||
puts "delayed requests"
|
||||
(0..(l*2)).each do |i|
|
||||
# t = Time.now()
|
||||
#puts "#{i} : #{t - t0} : #{apis[i%l].auth()[:payload]}"
|
||||
test_api = apis[i%l]
|
||||
if (test_api.is_pass?(BEEF_PASSWD))
|
||||
expect(test_api.auth()[:payload]["success"]).to be(true) # valid pass should succeed
|
||||
else
|
||||
expect(test_api.auth()[:payload]).to eql("401 Unauthorized")
|
||||
end
|
||||
sleep(0.5)
|
||||
# t0 = t
|
||||
end
|
||||
apis.shuffle! # new order for next iteration
|
||||
apis.reverse if (apis[0].is_pass?(BEEF_PASSWD)) # prevent the first from having valid passwd
|
||||
end # multiple sets of auth attempts
|
||||
end
|
||||
|
||||
end
|
||||
22
spec/beef/core/extensions_spec.rb
Normal file
22
spec/beef/core/extensions_spec.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
RSpec.describe 'BeEF Extensions' do
|
||||
|
||||
it 'loaded successfully' do
|
||||
expect {
|
||||
BeEF::Extensions.load
|
||||
}.to_not raise_error
|
||||
|
||||
exts = BeEF::Core::Configuration.instance.get('beef.extension').select{|k,v|
|
||||
v['enable']
|
||||
}
|
||||
expect(exts.length).to be > 0
|
||||
|
||||
exts.each do |k,v|
|
||||
expect(v).to have_key('name')
|
||||
expect(v).to have_key('enable')
|
||||
expect(v).to have_key('loaded')
|
||||
expect(v['loaded']).to be(true)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
354
spec/beef/core/filter/filters_spec.rb
Normal file
354
spec/beef/core/filter/filters_spec.rb
Normal file
@@ -0,0 +1,354 @@
|
||||
RSpec.describe 'BeEF Filters' do
|
||||
|
||||
context 'is_non_empty_string?' do
|
||||
|
||||
it 'nil' do
|
||||
expect(BeEF::Filters::is_non_empty_string?(nil)).to be(false)
|
||||
end
|
||||
|
||||
it 'Integer' do
|
||||
expect(BeEF::Filters::is_non_empty_string?(1)).to be(false)
|
||||
end
|
||||
|
||||
it 'Empty String' do
|
||||
expect(BeEF::Filters::is_non_empty_string?("")).to be(false)
|
||||
end
|
||||
|
||||
it 'null' do
|
||||
expect(BeEF::Filters::is_non_empty_string?("\x00")).to be(true)
|
||||
end
|
||||
|
||||
it 'First char is num' do
|
||||
expect(BeEF::Filters::is_non_empty_string?("0")).to be(true)
|
||||
end
|
||||
|
||||
it 'First char is alpha' do
|
||||
expect(BeEF::Filters::is_non_empty_string?("A")).to be(true)
|
||||
end
|
||||
|
||||
it 'Four num chars' do
|
||||
expect(BeEF::Filters::is_non_empty_string?("3333")).to be(true)
|
||||
end
|
||||
|
||||
it 'Four num chars begining with alpha' do
|
||||
expect(BeEF::Filters::is_non_empty_string?("A3333")).to be(true)
|
||||
end
|
||||
|
||||
it 'Four num chars begining with null' do
|
||||
expect(BeEF::Filters::is_non_empty_string?("\x003333")).to be(true)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'only?' do
|
||||
|
||||
it 'success' do
|
||||
expect(BeEF::Filters::only?('A', 'A')).to be(true)
|
||||
end
|
||||
|
||||
it 'fail' do
|
||||
expect(BeEF::Filters::only?('A', 'B')).to be(false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'exists?' do
|
||||
|
||||
it 'success' do
|
||||
expect(BeEF::Filters::exists?('A', 'A')).to be(true)
|
||||
end
|
||||
|
||||
it 'fail' do
|
||||
expect(BeEF::Filters::exists?('A', 'B')).to be(false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'has_null?' do
|
||||
|
||||
context 'false with' do
|
||||
|
||||
it 'general' do
|
||||
chars = [nil, "", "\x01", "\xFF", "A", "A3333", "0", "}", ".", "+", "-", "-1", "0.A", "3333", "33 33", " AAAAA", "AAAAAA "]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::has_null?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'alphabet' do
|
||||
(1..255).each do |c|
|
||||
str = ''
|
||||
str.concat(c)
|
||||
expect(BeEF::Filters::has_null?(str)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'true with' do
|
||||
|
||||
it 'general' do
|
||||
chars = ["\x00", "A\x00", "AAAAAA\x00", "\x00A", "\x00AAAAAAAA", "A\x00A", "AAAAA\x00AAAA", "A\n\r\x00", "\x00\n\rA", "A\n\r\x00\n\rA", "\tA\x00A"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::has_null?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'alphabet null after' do
|
||||
(1..255).each do |c|
|
||||
str = ''
|
||||
str.concat(c)
|
||||
str += "\x00"
|
||||
expect(BeEF::Filters::has_null?(str)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'alphabet null before' do
|
||||
(1..255).each do |c|
|
||||
str = "\x00"
|
||||
str.concat(c)
|
||||
expect(BeEF::Filters::has_null?(str)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'has_non_printable_char?' do
|
||||
|
||||
context 'false with' do
|
||||
|
||||
it 'general' do
|
||||
chars = [nil, "", "A", "A3333", "0", "}", ".", "+", "-", "-1", "0.A", "3333", " 0AAAAA", " 0AAA "]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::has_non_printable_char?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'lowercase' do
|
||||
('a'..'z').each do |c|
|
||||
expect(BeEF::Filters::has_non_printable_char?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'uppercase' do
|
||||
('A'..'Z').each do |c|
|
||||
expect(BeEF::Filters::has_non_printable_char?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'numbers' do
|
||||
('0'..'9').each do |c|
|
||||
expect(BeEF::Filters::has_non_printable_char?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'true with' do
|
||||
|
||||
it 'general' do
|
||||
chars = ["\x00", "\x01", "\x02", "A\x03", "\x04A", "\x0033333", "\x00AAAAAA", " AAAAA\x00", "\t\x00AAAAA", "\n\x00AAAAA", "\n\r\x00AAAAAAAAA", "AAAAAAA\x00AAAAAAA", "\n\x00"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::has_non_printable_char?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'alphabet null before' do
|
||||
(1..255).each do |c|
|
||||
str = ''
|
||||
str.concat(c)
|
||||
str += "\x00"
|
||||
expect(BeEF::Filters::has_non_printable_char?(str)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'nums_only?' do
|
||||
|
||||
it 'false with general' do
|
||||
chars = [nil, 1, "", "A", "A3333", "\x003333", "}", ".", "+", "-", "-1"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::nums_only?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'true with general' do
|
||||
chars = ["0", "333"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::nums_only?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'is_valid_float?' do
|
||||
|
||||
it 'false with general' do
|
||||
chars = [nil, 1, "", "A", "A3333", "\x003333", "}", ".", "+", "-", "-1", "0", "333", "0.A"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::is_valid_float?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'true with general' do
|
||||
chars = ["33.33", "0.0", "1.0", "0.1"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::is_valid_float?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'hexs_only?' do
|
||||
|
||||
it 'false with general' do
|
||||
chars = [nil, 1, "", "\x003333", "}", ".", "+", "-", "-1", "0.A", "33.33", "0.0", "1.0", "0.1"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::hexs_only?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'true with general' do
|
||||
chars = ["0123456789ABCDEFabcdef", "0", "333", "A33333", "A"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::hexs_only?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'first_char_is_num?' do
|
||||
|
||||
it 'false with general' do
|
||||
chars = ["", "A", "A33333", "\x0033333"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::first_char_is_num?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'true with general' do
|
||||
chars = ["333", "0AAAAAA", "0"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::first_char_is_num?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'has_whitespace_char?' do
|
||||
|
||||
it 'false with general' do
|
||||
chars = ["", "A", "A33333", "\x0033333", "0", "}", ".", "+", "-", "-1", "0.A"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::has_whitespace_char?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'true with general' do
|
||||
chars = ["33 33", " ", " ", " 0AAAAAAA", " 0AAAAAAA ", "\t0AAAAAAA", "\n0AAAAAAAA"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::has_whitespace_char?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'alphanums_only?' do
|
||||
|
||||
context 'false with' do
|
||||
|
||||
it 'general' do
|
||||
chars = [nil, "", "\n", "\r", "\x01", "}", ".", "+", "-", "-1", "ee-!@$%^&*}=0.A", "33 33", " AAAA", "AAA "]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::alphanums_only?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'additional nulls' do
|
||||
chars = ["\x00", "A\x00", "AAAAAAAAA\x00", "\x00A", "\x00AAAAAAAAA", "A\x00A", "AAAAAAAA\x00AAAAAAAA", "A\n\r\x00", "\x00\n\rA", "A\n\r\x00\n\rA", "\tA\x00A"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::alphanums_only?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'alphabet null after' do
|
||||
(1..255).each do |c|
|
||||
str = ''
|
||||
str.concat(c)
|
||||
str += "\x00"
|
||||
expect(BeEF::Filters::alphanums_only?(str)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'alphabet null before' do
|
||||
(1..255).each do |c|
|
||||
str = "\x00"
|
||||
str.concat(c)
|
||||
expect(BeEF::Filters::alphanums_only?(str)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'alphabet around null' do
|
||||
(1..255).each do |c|
|
||||
str = ''
|
||||
str.concat(c)
|
||||
str += "\x00"
|
||||
str.concat(c)
|
||||
expect(BeEF::Filters::alphanums_only?(str)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'true with' do
|
||||
|
||||
it 'general' do
|
||||
chars = ["A", "A3333", "0", "3333"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::alphanums_only?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'uppercase' do
|
||||
('A'..'Z').each do |c|
|
||||
expect(BeEF::Filters::alphanums_only?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'lowercase' do
|
||||
('a'..'z').each do |c|
|
||||
expect(BeEF::Filters::alphanums_only?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'numbers' do
|
||||
('0'..'9').each do |c|
|
||||
expect(BeEF::Filters::alphanums_only?(c)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'has_valid_param_chars?' do
|
||||
|
||||
it 'false' do
|
||||
chars = [nil, "", "+"]
|
||||
chars.each do |c|
|
||||
expect(BeEF::Filters::has_valid_param_chars?(c)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'true' do
|
||||
expect(BeEF::Filters::has_valid_param_chars?("A")).to be(true)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
34
spec/beef/core/main/models/browser_details_spec.rb
Normal file
34
spec/beef/core/main/models/browser_details_spec.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
RSpec.describe 'BeEF BrowserDetails' do
|
||||
|
||||
before(:all) do
|
||||
@session = (0...10).map { ('a'..'z').to_a[rand(26)] }.join
|
||||
DataMapper.setup(:default, 'sqlite3::memory:')
|
||||
DataMapper.auto_migrate!
|
||||
end
|
||||
|
||||
it 'set nil value' do
|
||||
BeEF::Core::Models::BrowserDetails.set(@session, 'key_with_nil_value', nil)
|
||||
expect(BeEF::Core::Models::BrowserDetails.get(@session, 'key_with_nil_value')).to be_empty
|
||||
end
|
||||
|
||||
it 'set value' do
|
||||
key_name = (0...10).map { ('a'..'z').to_a[rand(26)] }.join
|
||||
key_value = (0...10).map { ('a'..'z').to_a[rand(26)] }.join
|
||||
BeEF::Core::Models::BrowserDetails.set(@session, key_name, key_value)
|
||||
expect(BeEF::Core::Models::BrowserDetails.get(@session, key_name)).to eql(key_value)
|
||||
end
|
||||
|
||||
it 'update value' do
|
||||
key_name = (0...10).map { ('a'..'z').to_a[rand(26)] }.join
|
||||
|
||||
original_key_value = (0...10).map { ('a'..'z').to_a[rand(26)] }.join
|
||||
BeEF::Core::Models::BrowserDetails.set(@session, key_name, original_key_value).to_s
|
||||
expect(BeEF::Core::Models::BrowserDetails.get(@session, key_name)).to eql(original_key_value)
|
||||
|
||||
new_key_value = (0...10).map { ('a'..'z').to_a[rand(26)] }.join
|
||||
BeEF::Core::Models::BrowserDetails.set(@session, key_name, new_key_value).to_s
|
||||
expect(BeEF::Core::Models::BrowserDetails.get(@session, key_name)).to_not eql(original_key_value)
|
||||
expect(BeEF::Core::Models::BrowserDetails.get(@session, key_name)).to eql(new_key_value)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
RSpec.describe 'BeEF Dynamic Reconsturction' do
|
||||
|
||||
before(:all) do
|
||||
@port = 2001
|
||||
config = {}
|
||||
config[:BindAddress] = '127.0.0.1'
|
||||
config[:Port] = @port.to_s
|
||||
@mounts = {}
|
||||
@mounts['/test'] = BeEF::Core::NetworkStack::Handlers::DynamicReconstruction.new
|
||||
@rackApp = Rack::URLMap.new(@mounts)
|
||||
Thin::Logging.silent = true
|
||||
@server = Thin::Server.new('127.0.0.1', @port.to_s, @rackApp)
|
||||
trap("INT") { @server.stop }
|
||||
trap("TERM") { @server.stop }
|
||||
@pid = fork do
|
||||
@server.start!
|
||||
end
|
||||
# wait for server to start
|
||||
sleep 1
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
Process.kill("INT",@pid)
|
||||
end
|
||||
|
||||
it 'delete' do
|
||||
response = Curl::Easy.http_delete("http://127.0.0.1:#{@port}/test")
|
||||
expect(response.response_code).to eql(404)
|
||||
end
|
||||
|
||||
it 'put' do
|
||||
response = Curl::Easy.http_put("http://127.0.0.1:#{@port}/test", nil)
|
||||
expect(response.response_code).to eql(404)
|
||||
end
|
||||
|
||||
it 'head' do
|
||||
response = Curl::Easy.http_head("http://127.0.0.1:#{@port}/test")
|
||||
expect(response.response_code).to eql(404)
|
||||
end
|
||||
|
||||
context 'get' do
|
||||
|
||||
it 'no params' do
|
||||
response = Curl::Easy.http_get("http://127.0.0.1:#{@port}/test")
|
||||
expect(response.response_code).to eql(404)
|
||||
end
|
||||
|
||||
it 'zero values' do
|
||||
response = Curl::Easy.http_get("http://127.0.0.1:#{@port}/test?bh=0&sid=0&pid=0&pc=0&d=0")
|
||||
expect(response.response_code).to eql(200)
|
||||
expect(response.body_str).to be_empty
|
||||
end
|
||||
|
||||
it 'one values' do
|
||||
response = Curl::Easy.http_get("http://127.0.0.1:#{@port}/test?bh=1&sid=1&pid=1&pc=1&d=1")
|
||||
expect(response.response_code).to eql(200)
|
||||
expect(response.body_str).to be_empty
|
||||
end
|
||||
|
||||
it 'negative one values' do
|
||||
response = Curl::Easy.http_get("http://127.0.0.1:#{@port}/test?bh=-1&sid=-1&pid=-1&pc=-1&d=-1")
|
||||
expect(response.response_code).to eql(200)
|
||||
expect(response.body_str).to be_empty
|
||||
end
|
||||
|
||||
# Fails gracefully
|
||||
it 'ascii values' do
|
||||
response = Curl::Easy.http_get("http://127.0.0.1:#{@port}/test?bh=z&sid=z&pid=z&pc=z&d=z")
|
||||
expect(response.response_code).to eql(200)
|
||||
expect(response.body_str).to be_empty
|
||||
end
|
||||
|
||||
# Fails gracefully
|
||||
it 'array values' do
|
||||
response = Curl::Easy.http_get("http://127.0.0.1:#{@port}/test?bh[]=1&sid[]=1&pid[]=1&pc[]=1&d[]=1")
|
||||
expect(response.response_code).to eql(200)
|
||||
expect(response.body_str).to be_empty
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
RSpec.describe 'BeEF Redirector' do
|
||||
|
||||
before(:all) do
|
||||
@port = 2002
|
||||
config = {}
|
||||
config[:BindAddress] = '127.0.0.1'
|
||||
config[:Port] = @port.to_s
|
||||
@mounts = {}
|
||||
@mounts['/test'] = BeEF::Core::NetworkStack::Handlers::Redirector.new('http://www.beefproject.com')
|
||||
@rackApp = Rack::URLMap.new(@mounts)
|
||||
Thin::Logging.silent = true
|
||||
@server = Thin::Server.new('127.0.0.1', @port.to_s, @rackApp)
|
||||
trap("INT") { @server.stop }
|
||||
trap("TERM") { @server.stop }
|
||||
@pid = fork do
|
||||
@server.start!
|
||||
end
|
||||
# wait for server to start
|
||||
sleep 0.8
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
Process.kill("INT",@pid)
|
||||
end
|
||||
|
||||
it 'redirects' do
|
||||
response = Curl::Easy.http_get("http://127.0.0.1:#{@port}/test/")
|
||||
expect(response.response_code).to eql(302)
|
||||
expect(response.body_str).to eql("302 found")
|
||||
expect(response.header_str).to match(/Location: http:\/\/www.beefproject\.com/)
|
||||
end
|
||||
|
||||
end
|
||||
48
spec/beef/core/modules_spec.rb
Normal file
48
spec/beef/core/modules_spec.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
RSpec.describe 'BeEF Modules' do
|
||||
|
||||
it 'loaded successfully' do
|
||||
expect {
|
||||
BeEF::Modules.load
|
||||
}.to_not raise_error
|
||||
|
||||
modules = BeEF::Core::Configuration.instance.get('beef.module').select do |k,v|
|
||||
v['enable'] == true and v['category'] != nil
|
||||
end
|
||||
expect(modules.length).to be > 0
|
||||
|
||||
modules.each do |k,v|
|
||||
expect(BeEF::Module.is_present(k)).to be(true)
|
||||
expect(BeEF::Module.is_enabled(k)).to be(true)
|
||||
expect {
|
||||
BeEF::Module.hard_load(k)
|
||||
}.to_not raise_error
|
||||
expect(BeEF::Module.is_loaded(k)).to be(true)
|
||||
BeEF::Core::Configuration.instance.get("beef.module.#{k}.target").each do |k,v|
|
||||
expect(v).to_not be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'safe client debug log' do
|
||||
Dir['../../modules/**/*.js'].each do |path|
|
||||
next unless File.file?(path)
|
||||
File.open(path) do |f|
|
||||
f.grep(/\bconsole\.log\W*\(/m) do |line|
|
||||
fail "Function 'console.log' instead of 'beef.debug' inside\n Path: #{path}\nLine: #{line}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'safe variable decleration' do
|
||||
Dir['../../modules/**/*.js'].each do |path|
|
||||
next unless File.file?(path)
|
||||
File.open(path) do |f|
|
||||
f.grep(/\blet\W+[a-zA-Z0-9_\.]+\W*=/) do |line|
|
||||
fail "Variable declared with 'let' instead of 'var' inside\n Path: #{path}\nLine: #{line}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
15
spec/beef/extensions/console_spec.rb
Normal file
15
spec/beef/extensions/console_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
RSpec.describe 'BeEF Extension Console' do
|
||||
|
||||
before(:all) do
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@config.load_extensions_config
|
||||
end
|
||||
|
||||
it 'loads configuration' do
|
||||
expect(@config.get('beef.extension.console')).to have_key('enable')
|
||||
console_shell = @config.get('beef.extension.console.shell')
|
||||
expect(console_shell).to have_key('historyfolder')
|
||||
expect(console_shell).to have_key('historyfile')
|
||||
end
|
||||
|
||||
end
|
||||
340
spec/beef/extensions/dns_spec.rb
Normal file
340
spec/beef/extensions/dns_spec.rb
Normal file
@@ -0,0 +1,340 @@
|
||||
require 'resolv'
|
||||
require 'extensions/dns/extension.rb'
|
||||
|
||||
RSpec.describe 'BeEF Extension DNS' do
|
||||
|
||||
IN = Resolv::DNS::Resource::IN
|
||||
|
||||
before(:all) do
|
||||
DataMapper.setup(:default, 'sqlite3::memory:')
|
||||
DataMapper.auto_migrate!
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@config.load_extensions_config
|
||||
@dns = BeEF::Extension::Dns::Server.instance
|
||||
end
|
||||
|
||||
it 'loaded configuration' do
|
||||
config = @config.get('beef.extension.dns')
|
||||
expect(config).to have_key('protocol')
|
||||
expect(config).to have_key('address')
|
||||
expect(config).to have_key('port')
|
||||
expect(config).to have_key('upstream')
|
||||
end
|
||||
|
||||
it 'responds to interfaces' do
|
||||
expect(@dns).to respond_to(:add_rule)
|
||||
expect(@dns).to respond_to(:get_rule)
|
||||
expect(@dns).to respond_to(:remove_rule!)
|
||||
expect(@dns).to respond_to(:get_ruleset)
|
||||
expect(@dns).to respond_to(:remove_ruleset!)
|
||||
end
|
||||
|
||||
context 'add good rule' do
|
||||
|
||||
it '1.2.3.4' do
|
||||
id = nil
|
||||
response = '1.2.3.4'
|
||||
expect {
|
||||
id = @dns.add_rule(
|
||||
:pattern => 'foo.bar',
|
||||
:resource => IN::A,
|
||||
:response => [response] ) do |transaction|
|
||||
transaction.respond!(response)
|
||||
end
|
||||
}.to_not raise_error
|
||||
expect(id).to_not be_nil
|
||||
end
|
||||
|
||||
it '9.9.9.9' do
|
||||
id = nil
|
||||
response = '9.9.9.9'
|
||||
expect {
|
||||
id = @dns.add_rule(
|
||||
:pattern => %r{i\.(love|hate)\.beef\.com?},
|
||||
:resource => IN::A,
|
||||
:response => [response] ) do |transaction|
|
||||
transaction.respond!(response)
|
||||
end
|
||||
}.to_not raise_error
|
||||
expect(id).to_not be_nil
|
||||
end
|
||||
|
||||
it 'domains' do
|
||||
response = '9.9.9.9'
|
||||
domains = %w(
|
||||
i.hate.beef.com
|
||||
i.love.beef.com
|
||||
i.love.beef.co
|
||||
i.love.beef.co )
|
||||
domains.each do |d|
|
||||
id = nil
|
||||
expect {
|
||||
id = @dns.add_rule(
|
||||
:pattern => %r{i\.(love|hate)\.beef\.com?},
|
||||
:resource => IN::A,
|
||||
:response => [response] ) do |transaction|
|
||||
transaction.respond!(response)
|
||||
end
|
||||
}.to_not raise_error
|
||||
expect(id).to_not be_nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'add bad rule' do
|
||||
|
||||
it '4.2.4.2' do
|
||||
id = nil
|
||||
same_id = nil
|
||||
pattern = 'j.random.hacker'
|
||||
response = '4.2.4.2'
|
||||
|
||||
expect {
|
||||
id = @dns.add_rule(
|
||||
:pattern => pattern,
|
||||
:resource => IN::A,
|
||||
:response => [response] ) do |transaction|
|
||||
transaction.respond!(response)
|
||||
end
|
||||
}.to_not raise_error
|
||||
|
||||
expect {
|
||||
same_id = @dns.add_rule(
|
||||
:pattern => pattern,
|
||||
:resource => IN::A,
|
||||
:response => [response] ) do |transaction|
|
||||
transaction.respond!(response)
|
||||
end
|
||||
}.to_not raise_error
|
||||
|
||||
expect {
|
||||
same_id = @dns.add_rule(
|
||||
:pattern => pattern,
|
||||
:resource => IN::A,
|
||||
:response => [response] ) do |transaction|
|
||||
transaction.respond!(response)
|
||||
end
|
||||
}.to_not raise_error
|
||||
|
||||
expect(id).to eql(same_id)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
it 'id format' do
|
||||
pattern = 'dead.beef'
|
||||
response = '2.2.2.2'
|
||||
id = nil
|
||||
|
||||
expect {
|
||||
id = @dns.add_rule(
|
||||
:pattern => pattern,
|
||||
:resource => IN::A,
|
||||
:response => [response] ) do |transaction|
|
||||
transaction.respond!(response)
|
||||
end
|
||||
}.to_not raise_error
|
||||
|
||||
expect(id.length).to eql(8)
|
||||
expect(id).to match(/^\h{8}$/)
|
||||
end
|
||||
|
||||
|
||||
it 'get good rule' do
|
||||
pattern = 'be.ef'
|
||||
response = '1.1.1.1'
|
||||
id = nil
|
||||
|
||||
expect {
|
||||
id = @dns.add_rule(
|
||||
:pattern => pattern,
|
||||
:resource => IN::A,
|
||||
:response => [response] ) do |transaction|
|
||||
transaction.respond!(response)
|
||||
end
|
||||
}.to_not raise_error
|
||||
|
||||
expect(id).to_not be_nil
|
||||
rule = @dns.get_rule(id)
|
||||
|
||||
expect(rule).to be_a(Hash)
|
||||
expect(rule.length).to be > 0
|
||||
expect(rule).to have_key(:id)
|
||||
expect(rule).to have_key(:pattern)
|
||||
expect(rule).to have_key(:resource)
|
||||
expect(rule).to have_key(:response)
|
||||
expect(rule[:id]).to eql(id)
|
||||
expect(rule[:pattern]).to eql(pattern)
|
||||
expect(rule[:resource]).to eql('A')
|
||||
expect(rule[:response]).to be_a(Array)
|
||||
expect(rule[:response].length).to be > 0
|
||||
expect(rule[:response].first).to eql(response)
|
||||
end
|
||||
|
||||
it 'get bad rule' do
|
||||
expect(@dns.get_rule(42)).to be_nil
|
||||
end
|
||||
|
||||
it 'remove good rule' do
|
||||
pattern = 'hack.the.gibson'
|
||||
response = '1.9.9.5'
|
||||
id = nil
|
||||
|
||||
expect {
|
||||
id = @dns.add_rule(
|
||||
:pattern => pattern,
|
||||
:resource => IN::A,
|
||||
:response => [response] ) do |transaction|
|
||||
transaction.respond!(response)
|
||||
end
|
||||
}.to_not raise_error
|
||||
|
||||
expect(@dns.remove_rule!(id)).to be(true)
|
||||
end
|
||||
|
||||
it 'remove bad rule' do
|
||||
expect(@dns.remove_rule!(42)).to be_nil
|
||||
end
|
||||
|
||||
it 'get ruleset' do
|
||||
rules = [
|
||||
{ pattern: 'be.ef', resource: 'A', response: '1.1.1.1' },
|
||||
{ pattern: 'dead.beef', resource: 'A', response: '2.2.2.2' },
|
||||
{ pattern: 'foo.bar', resource: 'A', response: '1.2.3.4' },
|
||||
{ pattern: 'i\.(love|hate)\.beef.com?', resource: 'A', response: '9.9.9.9' },
|
||||
{ pattern: 'j.random.hacker', resource: 'A', response: '4.2.4.2' }
|
||||
]
|
||||
|
||||
@dns.remove_ruleset!
|
||||
expect(@dns.get_ruleset.length).to eql(0)
|
||||
|
||||
rules.each do |r|
|
||||
@dns.add_rule(
|
||||
:pattern => r[:pattern],
|
||||
:resource => IN::A,
|
||||
:response => r[:response]
|
||||
)
|
||||
end
|
||||
|
||||
ruleset = @dns.get_ruleset
|
||||
ruleset.sort! { |a, b| a[:pattern] <=> b[:pattern] }
|
||||
expect(ruleset).to be_a(Array)
|
||||
expect(ruleset.length).to eql(5)
|
||||
|
||||
rules.each_with_index do |v,i|
|
||||
expect(ruleset[i][:pattern]).to eql(v[:pattern])
|
||||
expect(ruleset[i][:resource]).to eql(v[:resource])
|
||||
expect(ruleset[i][:response]).to eql(v[:response])
|
||||
end
|
||||
end
|
||||
|
||||
it 'remove ruleset' do
|
||||
expect(@dns.remove_ruleset!).to be(true)
|
||||
expect(@dns.get_ruleset.length).to eql(0)
|
||||
end
|
||||
|
||||
it 'failure types' do
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
# Tests each supported type of query failure
|
||||
# def test_13_failure_types
|
||||
# begin
|
||||
# id = @@dns.add_rule(
|
||||
# :pattern => 'noerror.beef.com',
|
||||
# :resource => IN::A,
|
||||
# :response => ['1.2.3.4'] ) do |transaction|
|
||||
# transaction.failure!(:NoError)
|
||||
# end
|
||||
# #check_failure_status(id, :NoError)
|
||||
# end
|
||||
#
|
||||
# begin
|
||||
# id = @@dns.add_rule(
|
||||
# :pattern => 'formerr.beef.com',
|
||||
# :resource => IN::A,
|
||||
# :response => ['1.2.3.4'] ) do |transaction|
|
||||
# transaction.failure!(:FormErr)
|
||||
# end
|
||||
## #check_failure_status(id, :FormErr)
|
||||
# end
|
||||
#
|
||||
# begin
|
||||
# id = @@dns.add_rule(
|
||||
# :pattern => 'servfail.beef.com',
|
||||
# :resource => IN::A,
|
||||
# :response => ['1.2.3.4'] ) do |transaction|
|
||||
# transaction.failure!(:ServFail)
|
||||
# end
|
||||
# #check_failure_status(id, :ServFail)
|
||||
# end
|
||||
#
|
||||
# begin
|
||||
# id = @@dns.add_rule(
|
||||
# :pattern => 'nxdomain.beef.com',
|
||||
# :resource => IN::A,
|
||||
# :response => ['1.2.3.4'] ) do |transaction|
|
||||
# transaction.failure!(:NXDomain)
|
||||
# end
|
||||
# #check_failure_status(id, :NXDomain)
|
||||
# end
|
||||
#
|
||||
# begin
|
||||
# id = @@dns.add_rule(
|
||||
# :pattern => 'notimp.beef.com',
|
||||
# :resource => IN::A,
|
||||
## :response => ['1.2.3.4'] ) do |transaction|
|
||||
# transaction.failure!(:NotImp)
|
||||
# end
|
||||
# #check_failure_status(id, :NotImp)
|
||||
# end
|
||||
#
|
||||
# begin
|
||||
# id = @@dns.add_rule(
|
||||
# :pattern => 'refused.beef.com',
|
||||
# :resource => IN::A,
|
||||
# :response => ['1.2.3.4'] ) do |transaction|
|
||||
### transaction.failure!(:Refused)
|
||||
# end
|
||||
# #check_failure_status(id, :Refused)
|
||||
# end
|
||||
#
|
||||
# begin
|
||||
# id = @@dns.add_rule(
|
||||
# :pattern => 'notauth.beef.com',
|
||||
# :resource => IN::A,
|
||||
# :response => ['1.2.3.4'] ) do |transaction|
|
||||
# transaction.failure!(:NotAuth)
|
||||
# end
|
||||
## #check_failure_status(id, :NotAuth)
|
||||
# end
|
||||
# end
|
||||
#
|
||||
## private
|
||||
##
|
||||
# # Confirms that a query for the rule given in 'id' returns a 'resource' failure status
|
||||
## def check_failure_status(id, resource)
|
||||
## rule = @@dns.get_rule(id)
|
||||
# status = resource.to_s.force_encoding('UTF-8').upcase
|
||||
# assert_equal(status, rule[:response][0])
|
||||
#
|
||||
# check_dns_response(/status: #{status}/, rule[:resource], rule[:pattern])
|
||||
# end
|
||||
#
|
||||
# # Compares output of dig command against regex
|
||||
# def check_dns_response(regex, type, pattern)
|
||||
# address = @@config.get('beef.extension.dns.address')
|
||||
# port = @@config.get('beef.extension.dns.port')
|
||||
### dig_output = IO.popen(["dig", "@#{address}", "-p", "#{port}", "-t", "#{type}", "#{pattern}"], 'r+').read
|
||||
# assert_match(regex, dig_output)
|
||||
# end
|
||||
##
|
||||
##end
|
||||
###
|
||||
20
spec/beef/extensions/ipec_tunnel_spec.rb
Normal file
20
spec/beef/extensions/ipec_tunnel_spec.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
require 'extensions/ipec/extension'
|
||||
|
||||
RSpec.describe 'BeEF Extension IPEC' do
|
||||
|
||||
before(:all) do
|
||||
DataMapper.setup(:default, 'sqlite3::memory:')
|
||||
DataMapper.auto_migrate!
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@config.load_extensions_config
|
||||
end
|
||||
|
||||
it 'loads configuration' do
|
||||
expect(@config.get('beef.extension.ipec')).to have_key('enable')
|
||||
end
|
||||
|
||||
it 'interface' do
|
||||
expect(BeEF::Extension::Ipec::JunkCalculator.instance).to respond_to(:bind_junk_calculator)
|
||||
end
|
||||
|
||||
end
|
||||
26
spec/beef/extensions/network_spec.rb
Normal file
26
spec/beef/extensions/network_spec.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
require 'extensions/network/models/network_service'
|
||||
require 'extensions/network/models/network_host'
|
||||
|
||||
RSpec.describe 'BeEF Extension Network' do
|
||||
|
||||
before(:all) do
|
||||
DataMapper.setup(:default, 'sqlite3::memory:')
|
||||
DataMapper.auto_migrate!
|
||||
end
|
||||
|
||||
it 'add good host' do
|
||||
expect {
|
||||
BeEF::Core::Models::NetworkHost.add(:hooked_browser_id => '1234', :ip => '127.0.0.1')
|
||||
}.to_not raise_error
|
||||
expect(BeEF::Core::Models::NetworkHost.all(hooked_browser_id: '1234', ip: '127.0.0.1')).to_not be_empty
|
||||
end
|
||||
|
||||
it 'add good service' do
|
||||
expect {
|
||||
BeEF::Core::Models::NetworkService.add(:hooked_browser_id => '1234', :proto => 'http', :ip => '127.0.0.1', :port => 80, :type => 'Apache')
|
||||
}.to_not raise_error
|
||||
expect(BeEF::Core::Models::NetworkService.all(hooked_browser_id: '1234', ip: '127.0.0.1')).to_not be_empty
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
21
spec/beef/extensions/proxy_spec.rb
Normal file
21
spec/beef/extensions/proxy_spec.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
require 'extensions/proxy/extension'
|
||||
|
||||
RSpec.describe 'BeEF Extension Proxy' do
|
||||
|
||||
before(:all) do
|
||||
DataMapper.setup(:default, 'sqlite3::memory:')
|
||||
DataMapper.auto_migrate!
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@config.load_extensions_config
|
||||
end
|
||||
|
||||
it 'loads configuration' do
|
||||
config = @config.get('beef.extension.proxy')
|
||||
expect(config).to have_key('enable')
|
||||
expect(config).to have_key('address')
|
||||
expect(config).to have_key('port')
|
||||
expect(config).to have_key('key')
|
||||
expect(config).to have_key('cert')
|
||||
end
|
||||
|
||||
end
|
||||
20
spec/beef/extensions/qrcode_spec.rb
Normal file
20
spec/beef/extensions/qrcode_spec.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
require 'extensions/qrcode/extension'
|
||||
|
||||
RSpec.describe 'BeEF Extension QRCode' do
|
||||
|
||||
before(:all) do
|
||||
DataMapper.setup(:default, 'sqlite3::memory:')
|
||||
DataMapper.auto_migrate!
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@config.load_extensions_config
|
||||
end
|
||||
|
||||
it 'loads configuration' do
|
||||
config = @config.get('beef.extension.qrcode')
|
||||
expect(config).to have_key('enable')
|
||||
expect(config).to have_key('targets')
|
||||
expect(config).to have_key('qrsize')
|
||||
expect(config).to have_key('qrborder')
|
||||
end
|
||||
|
||||
end
|
||||
23
spec/beef/extensions/requester_spec.rb
Normal file
23
spec/beef/extensions/requester_spec.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
require 'extensions/requester/extension'
|
||||
|
||||
RSpec.describe 'BeEF Extension Requester' do
|
||||
|
||||
before(:all) do
|
||||
DataMapper.setup(:default, 'sqlite3::memory:')
|
||||
DataMapper.auto_migrate!
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@config.load_extensions_config
|
||||
end
|
||||
|
||||
it 'loads configuration' do
|
||||
expect(@config.get('beef.extension.requester')).to have_key('enable')
|
||||
end
|
||||
|
||||
it 'has interface' do
|
||||
requester = BeEF::Extension::Requester::API::Hook.new
|
||||
expect(requester).to respond_to(:requester_run)
|
||||
expect(requester).to respond_to(:add_to_body)
|
||||
expect(requester).to respond_to(:requester_parse_db_request)
|
||||
end
|
||||
|
||||
end
|
||||
67
spec/beef/extensions/webrtc_spec.rb
Normal file
67
spec/beef/extensions/webrtc_spec.rb
Normal file
@@ -0,0 +1,67 @@
|
||||
require 'rest-client'
|
||||
|
||||
RSpec.describe 'BeEF Extension WebRTC' do
|
||||
|
||||
before(:all) do
|
||||
DataMapper.setup(:default, 'sqlite3::memory:')
|
||||
DataMapper.auto_migrate!
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@config.load_extensions_config
|
||||
|
||||
# json = {:username => BEEF_USER, :password => BEEF_PASSWD}.to_json
|
||||
# @headers = {:content_type => :json, :accept => :json}
|
||||
# response = RestClient.post("#{RESTAPI_ADMIN}/login", json, @headers)
|
||||
# result = JSON.parse(response.body)
|
||||
# @token = result['token']
|
||||
# @activated = @config.get('beef.extension.webrtc.enable') || false
|
||||
|
||||
# @victim1 = BeefTest.new_victim
|
||||
# @victim2 = BeefTest.new_victim
|
||||
|
||||
# sleep 8
|
||||
|
||||
# # Fetch last online browsers' ids
|
||||
# rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => { :token => @token}}
|
||||
# result = JSON.parse(rest_response.body)
|
||||
# browsers = result["hooked-browsers"]["online"]
|
||||
# browsers.each_with_index do |elem, index|
|
||||
# if index == browsers.length - 1
|
||||
# @victim2id = browsers["#{index}"]["id"].to_s
|
||||
# end
|
||||
# if index == browsers.length - 2
|
||||
# @victim1id = browsers["#{index}"]["id"].to_s
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
# @victim1.driver.browser.close unless @victim1.nil?
|
||||
# @victim2.driver.browser.close unless @victim2.nil?
|
||||
end
|
||||
|
||||
it 'loads configuration' do
|
||||
config = @config.get('beef.extension.webrtc')
|
||||
expect(config).to have_key('enable')
|
||||
expect(config).to have_key('stunservers')
|
||||
expect(config).to have_key('turnservers')
|
||||
end
|
||||
|
||||
# it 'check two hooked browsers' do
|
||||
# expect(@activated).to be(true)
|
||||
|
||||
# response = nil
|
||||
# expect {
|
||||
# response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {:token => @token}}
|
||||
# }.to_not raise_error
|
||||
# expect(response).to_not be_nil
|
||||
# expect(response.body).to_not be_nil
|
||||
# expect(response.code).to eql(200)
|
||||
|
||||
# result = JSON.parse(rest_response.body)
|
||||
# browsers = result["hooked-browsers"]["online"]
|
||||
# expect(browsers).to_not be_nil
|
||||
# expect(browsers.length).to be >= 2
|
||||
# end
|
||||
|
||||
|
||||
end
|
||||
24
spec/beef/extensions/xssrays_spec.rb
Normal file
24
spec/beef/extensions/xssrays_spec.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
require 'extensions/xssrays/extension'
|
||||
|
||||
RSpec.describe 'BeEF Extension XSSRays' do
|
||||
|
||||
before(:all) do
|
||||
DataMapper.setup(:default, 'sqlite3::memory:')
|
||||
DataMapper.auto_migrate!
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@config.load_extensions_config
|
||||
end
|
||||
|
||||
it 'loads configuration' do
|
||||
config = @config.get('beef.extension.xssrays')
|
||||
expect(config).to have_key('enable')
|
||||
expect(config).to have_key('clean_timeout')
|
||||
expect(config).to have_key('cross_domain')
|
||||
end
|
||||
|
||||
it 'interface' do
|
||||
xssrays = BeEF::Extension::Xssrays::API::Scan.new
|
||||
expect(xssrays).to respond_to(:start_scan)
|
||||
expect(xssrays).to respond_to(:add_to_body)
|
||||
end
|
||||
end
|
||||
30
spec/beef/filesystem_checks_spec.rb
Normal file
30
spec/beef/filesystem_checks_spec.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
RSpec.describe 'BeEF Filesystem' do
|
||||
|
||||
def file_test(file)
|
||||
expect(File.file?(file)).to be(true)
|
||||
expect(File.zero?(file)).to be(false)
|
||||
end
|
||||
|
||||
it 'required files' do
|
||||
files = [
|
||||
'beef',
|
||||
'config.yaml',
|
||||
'install'
|
||||
]
|
||||
files.each do |f|
|
||||
file_test(f)
|
||||
end
|
||||
end
|
||||
|
||||
it 'executable directories' do
|
||||
dirs = [
|
||||
'core',
|
||||
'modules',
|
||||
'extensions'
|
||||
]
|
||||
dirs.each do |d|
|
||||
expect(File.executable?(d)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
17
spec/beef/security_checks_spec.rb
Normal file
17
spec/beef/security_checks_spec.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
RSpec.describe 'BeEF Security Checks' do
|
||||
|
||||
it 'dangerous eval usage' do
|
||||
Dir['**/*.rb'].each do |path|
|
||||
File.open(path) do |f|
|
||||
next if /#{File.basename(__FILE__)}/.match(path) # skip this file
|
||||
next if /\/msf-test\//.match(path) # skip this file
|
||||
next if /extensions\/dns/.match(path) # skip this file
|
||||
|
||||
f.grep(/\Weval\W/im) do |line|
|
||||
fail "Illegal use of 'eval' found in\n Path: #{path}\nLine: #{line}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
30
spec/spec_helper.rb
Normal file
30
spec/spec_helper.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
require 'core/loader.rb'
|
||||
|
||||
# Notes
|
||||
# We need to load vairables that 'beef' usually does for us
|
||||
## config
|
||||
config = BeEF::Core::Configuration.new('config.yaml')
|
||||
## home_dir
|
||||
$home_dir = Dir.pwd
|
||||
## root_dir
|
||||
$root_dir = Dir.pwd
|
||||
|
||||
require 'core/bootstrap.rb'
|
||||
require 'rack/test'
|
||||
require 'curb'
|
||||
require 'rest-client'
|
||||
|
||||
# Require supports
|
||||
Dir['spec/support/*.rb'].each do |f|
|
||||
require f
|
||||
end
|
||||
|
||||
ENV['RACK_ENV'] ||= 'test'
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.disable_monkey_patching!
|
||||
config.include Rack::Test::Methods
|
||||
config.expect_with :rspec do |c|
|
||||
c.syntax = :expect
|
||||
end
|
||||
end
|
||||
50
spec/support/beef_test.rb
Normal file
50
spec/support/beef_test.rb
Normal file
@@ -0,0 +1,50 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
require 'test/unit'
|
||||
|
||||
require 'capybara'
|
||||
require 'capybara/rspec'
|
||||
Capybara.run_server = false # we need to run our own BeEF server
|
||||
|
||||
require 'selenium-webdriver'
|
||||
|
||||
class BeefTest
|
||||
|
||||
def self.save_screenshot(session)
|
||||
Dir.mkdir(BEEF_TEST_DIR) unless File.directory?(BEEF_TEST_DIR)
|
||||
session.driver.browser.save_screenshot(BEEF_TEST_DIR + Time.now.strftime("%Y-%m-%d--%H-%M-%S-%N") + ".png")
|
||||
end
|
||||
|
||||
def self.login(session = nil)
|
||||
session = Capybara::Session.new(:selenium_headless) if session.nil?
|
||||
session.visit(ATTACK_URL)
|
||||
sleep 2.0
|
||||
session.has_content?('BeEF Authentication')
|
||||
session.fill_in 'user', :with => BEEF_USER
|
||||
session.fill_in 'pass', :with => BEEF_PASSWD
|
||||
session.click_button('Login')
|
||||
sleep 10.0
|
||||
|
||||
session
|
||||
end
|
||||
|
||||
def self.logout(session)
|
||||
session.click_link('Logout')
|
||||
|
||||
session
|
||||
end
|
||||
|
||||
def self.new_attacker
|
||||
self.login
|
||||
end
|
||||
|
||||
def self.new_victim
|
||||
victim = Capybara::Session.new(:selenium_headless)
|
||||
victim.visit(VICTIM_URL)
|
||||
victim
|
||||
end
|
||||
|
||||
end
|
||||
27
spec/support/constants.rb
Normal file
27
spec/support/constants.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
BEEF_TEST_DIR = "/tmp/beef-test/"
|
||||
|
||||
# General constants
|
||||
ATTACK_DOMAIN = "127.0.0.1"
|
||||
VICTIM_DOMAIN = "localhost"
|
||||
ATTACK_URL = "http://" + ATTACK_DOMAIN + ":3000/ui/panel"
|
||||
VICTIM_URL = "http://" + VICTIM_DOMAIN + ":3000/demos/basic.html"
|
||||
|
||||
# Credentials
|
||||
BEEF_USER = ENV["TEST_BEEF_USER"] || 'beef'
|
||||
BEEF_PASSWD = ENV["TEST_BEEF_PASS"] || "beef"
|
||||
|
||||
# RESTful API root endpoints
|
||||
RESTAPI_HOOKS = "http://" + ATTACK_DOMAIN + ":3000/api/hooks"
|
||||
RESTAPI_LOGS = "http://" + ATTACK_DOMAIN + ":3000/api/logs"
|
||||
RESTAPI_MODULES = "http://" + ATTACK_DOMAIN + ":3000/api/modules"
|
||||
RESTAPI_NETWORK = "http://" + ATTACK_DOMAIN + ":3000/api/network"
|
||||
RESTAPI_PROXY = "http://" + ATTACK_DOMAIN + ":3000/api/proxy"
|
||||
RESTAPI_DNS = "http://" + ATTACK_DOMAIN + ":3000/api/dns"
|
||||
RESTAPI_SENG = "http://" + ATTACK_DOMAIN + ":3000/api/seng"
|
||||
RESTAPI_ADMIN = "http://" + ATTACK_DOMAIN + ":3000/api/admin"
|
||||
RESTAPI_WEBRTC = "http://" + ATTACK_DOMAIN + ":3000/api/webrtc"
|
||||
49
spec/support/simple_rest_client.rb
Normal file
49
spec/support/simple_rest_client.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
# less noisy verson of BeeRestAPI found in tools.
|
||||
class BeefRestClient
|
||||
def initialize proto, host, port, user, pass
|
||||
@user = user
|
||||
@pass = pass
|
||||
@url = "#{proto}://#{host}:#{port}/api/"
|
||||
@token = nil
|
||||
end
|
||||
|
||||
|
||||
def is_pass?(passwd)
|
||||
@pass == passwd
|
||||
end
|
||||
|
||||
|
||||
def auth
|
||||
begin
|
||||
response = RestClient.post "#{@url}admin/login",
|
||||
{ 'username' => "#{@user}",
|
||||
'password' => "#{@pass}" }.to_json,
|
||||
:content_type => :json,
|
||||
:accept => :json
|
||||
result = JSON.parse(response.body)
|
||||
@token = result['token']
|
||||
{:success => result['success'], :payload => result}
|
||||
rescue => e
|
||||
{:success => false, :payload => e.message }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def version
|
||||
return {:success => false, :payload => 'no token'} if @token.nil?
|
||||
begin
|
||||
response = RestClient.get "#{@url}server/version", {:params => {:token => @token}}
|
||||
result = JSON.parse(response.body)
|
||||
|
||||
{:success => result['success'], :payload => result}
|
||||
rescue => e
|
||||
print_error "Could not retrieve BeEF version: #{e.message}"
|
||||
{:success => false, :payload => e.message}
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user