mirror of
https://github.com/beefproject/beef
synced 2026-06-08 13:15:56 +00:00
TEST: main autorun specs
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
#
|
||||
# Copyright (c) 2006-2026 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - https://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe BeEF::Core::AutorunEngine::Parser do
|
||||
let(:parser) { described_class.instance }
|
||||
|
||||
def valid_minimal_args
|
||||
{
|
||||
name: 'Test Rule',
|
||||
author: 'Test Author',
|
||||
browser: 'ALL',
|
||||
browser_version: 'ALL',
|
||||
os: 'Windows',
|
||||
os_version: 'ALL',
|
||||
modules: [],
|
||||
execution_order: [],
|
||||
execution_delay: [],
|
||||
chain_mode: 'sequential'
|
||||
}
|
||||
end
|
||||
|
||||
describe '#parse' do
|
||||
it 'returns true for valid minimal args (empty modules)' do
|
||||
result = parser.parse(
|
||||
valid_minimal_args[:name],
|
||||
valid_minimal_args[:author],
|
||||
valid_minimal_args[:browser],
|
||||
valid_minimal_args[:browser_version],
|
||||
valid_minimal_args[:os],
|
||||
valid_minimal_args[:os_version],
|
||||
valid_minimal_args[:modules],
|
||||
valid_minimal_args[:execution_order],
|
||||
valid_minimal_args[:execution_delay],
|
||||
valid_minimal_args[:chain_mode]
|
||||
)
|
||||
|
||||
expect(result).to be true
|
||||
end
|
||||
|
||||
it 'raises ArgumentError for empty name' do
|
||||
expect do
|
||||
parser.parse('', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [], [], [], 'sequential')
|
||||
end.to raise_error(ArgumentError, /Invalid rule name/)
|
||||
end
|
||||
|
||||
it 'raises ArgumentError for nil name' do
|
||||
expect do
|
||||
parser.parse(nil, 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [], [], [], 'sequential')
|
||||
end.to raise_error(ArgumentError, /Invalid rule name/)
|
||||
end
|
||||
|
||||
it 'raises ArgumentError for empty author' do
|
||||
expect do
|
||||
parser.parse('Name', '', 'ALL', 'ALL', 'Windows', 'ALL', [], [], [], 'sequential')
|
||||
end.to raise_error(ArgumentError, /Invalid author name/)
|
||||
end
|
||||
|
||||
it 'raises ArgumentError for invalid chain_mode' do
|
||||
expect do
|
||||
parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [], [], [], 'invalid')
|
||||
end.to raise_error(ArgumentError, /Invalid chain_mode definition/)
|
||||
end
|
||||
|
||||
it 'raises ArgumentError for invalid os' do
|
||||
expect do
|
||||
parser.parse('Name', 'Author', 'ALL', 'ALL', 'InvalidOS', 'ALL', [], [], [], 'sequential')
|
||||
end.to raise_error(ArgumentError, /Invalid os definition/)
|
||||
end
|
||||
|
||||
it 'raises ArgumentError when execution_delay size does not match modules size' do
|
||||
expect do
|
||||
parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [{ 'name' => 'a' }], [1], [], 'sequential')
|
||||
end.to raise_error(ArgumentError, /execution_delay.*consistent with number of modules/)
|
||||
end
|
||||
|
||||
it 'raises ArgumentError when execution_order size does not match modules size' do
|
||||
expect do
|
||||
parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [{ 'name' => 'a' }], [], [0], 'sequential')
|
||||
end.to raise_error(ArgumentError, /execution_order.*consistent with number of modules/)
|
||||
end
|
||||
|
||||
it 'raises TypeError when execution_delay contains non-Integer' do
|
||||
# Use one module so sizes match; then type check runs on execution_delay
|
||||
expect do
|
||||
parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [{}], [1], ['not_an_int'], 'sequential')
|
||||
end.to raise_error(TypeError, /execution_delay.*Integers/)
|
||||
end
|
||||
|
||||
it 'raises TypeError when execution_order contains non-Integer' do
|
||||
# Use one module so sizes match; then type check runs on execution_order
|
||||
expect do
|
||||
parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [{}], ['x'], [0], 'sequential')
|
||||
end.to raise_error(TypeError, /execution_order.*Integers/)
|
||||
end
|
||||
|
||||
it 'raises ArgumentError for invalid browser' do
|
||||
expect do
|
||||
parser.parse('Name', 'Author', 'XX', 'ALL', 'Windows', 'ALL', [], [], [], 'sequential')
|
||||
end.to raise_error(ArgumentError, /Invalid browser definition/)
|
||||
end
|
||||
|
||||
it 'accepts nested-forward as chain_mode' do
|
||||
result = parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [], [], [], 'nested-forward')
|
||||
expect(result).to be true
|
||||
end
|
||||
|
||||
it 'accepts valid os values' do
|
||||
%w[Linux Windows OSX Android iOS BlackBerry ALL].each do |os|
|
||||
result = parser.parse('Name', 'Author', 'ALL', 'ALL', os, 'ALL', [], [], [], 'sequential')
|
||||
expect(result).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,83 @@
|
||||
#
|
||||
# Copyright (c) 2006-2026 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - https://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe BeEF::Core::AutorunEngine::RuleLoader do
|
||||
let(:loader) { described_class.instance }
|
||||
|
||||
def valid_rule_data
|
||||
{
|
||||
'name' => 'Test Rule',
|
||||
'author' => 'Test Author',
|
||||
'browser' => 'ALL',
|
||||
'browser_version' => 'ALL',
|
||||
'os' => 'Windows',
|
||||
'os_version' => 'ALL',
|
||||
'modules' => [],
|
||||
'execution_order' => [],
|
||||
'execution_delay' => [],
|
||||
'chain_mode' => 'sequential'
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow(loader).to receive(:print_error)
|
||||
allow(loader).to receive(:print_info)
|
||||
allow(loader).to receive(:print_more)
|
||||
end
|
||||
|
||||
describe '#load_rule_json' do
|
||||
it 'returns success and rule_id when parse succeeds and rule is new' do
|
||||
# Parser will succeed with valid minimal data; no existing rule
|
||||
result = loader.load_rule_json(valid_rule_data)
|
||||
|
||||
expect(result['success']).to be true
|
||||
expect(result).to have_key('rule_id')
|
||||
expect(result['rule_id']).to be_a(Integer)
|
||||
end
|
||||
|
||||
it 'returns success false and error when parse raises' do
|
||||
allow(BeEF::Core::AutorunEngine::Parser.instance).to receive(:parse).and_raise(ArgumentError.new('Invalid rule name'))
|
||||
|
||||
result = loader.load_rule_json(valid_rule_data.merge('name' => 'x'))
|
||||
|
||||
expect(result['success']).to be false
|
||||
expect(result['error']).to include('Invalid rule name')
|
||||
end
|
||||
|
||||
it 'returns success false and error when rule already exists' do
|
||||
# Create the rule first so it already exists
|
||||
BeEF::Core::Models::Rule.create!(
|
||||
name: 'Duplicate Rule',
|
||||
author: 'Test Author',
|
||||
browser: 'ALL',
|
||||
browser_version: 'ALL',
|
||||
os: 'Windows',
|
||||
os_version: 'ALL',
|
||||
modules: [].to_json,
|
||||
execution_order: [].to_s,
|
||||
execution_delay: [].to_s,
|
||||
chain_mode: 'sequential'
|
||||
)
|
||||
|
||||
result = loader.load_rule_json(
|
||||
valid_rule_data.merge('name' => 'Duplicate Rule')
|
||||
)
|
||||
|
||||
expect(result['success']).to be false
|
||||
expect(result['error']).to include('Duplicate rule already exists')
|
||||
end
|
||||
|
||||
it 'uses default chain_mode sequential when missing' do
|
||||
data = valid_rule_data.except('chain_mode')
|
||||
result = loader.load_rule_json(data)
|
||||
|
||||
expect(result['success']).to be true
|
||||
expect(result).to have_key('rule_id')
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user