1808 lines
50 KiB
Ruby
1808 lines
50 KiB
Ruby
require 'spec_helper'
|
|
|
|
RSpec.describe Msf::Ui::Debug do
|
|
let(:file_fixtures_path) { File.join(Msf::Config.install_root, 'spec', 'file_fixtures') }
|
|
let(:features) do
|
|
[
|
|
{
|
|
name: 'filtered_options',
|
|
description: 'Add option filtering functionality to Metasploit',
|
|
enabled: false
|
|
},
|
|
{
|
|
name: 'new_search_capabilities',
|
|
description: 'Add new search capabilities to Metasploit',
|
|
enabled: true
|
|
}
|
|
]
|
|
end
|
|
|
|
it 'error parsing correctly parses framework.log and msf-ws.log' do
|
|
allow(::Msf::Config).to receive(:log_directory).and_return(Pathname.new(file_fixtures_path).join('debug', 'error_logs', 'basic'))
|
|
|
|
error_log_output = <<~LOG
|
|
## %grnFramework Errors%clr
|
|
|
|
The following framework errors occurred before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 1
|
|
|
|
[11/11/1111 11:11:11] [e(0)] core: [-] Error 2
|
|
Call stack:
|
|
Stack_Trace
|
|
stack trace
|
|
STACK-TRACE
|
|
|
|
[22/22/2222 22:22:22] [e(0)] core: [-] Error 3
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
## %grnWeb Service Errors%clr
|
|
|
|
The following web service errors occurred before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[-] Error 1
|
|
|
|
[-] Error 2
|
|
[-] Error 3
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
LOG
|
|
|
|
expect(subject.errors).to eql(error_log_output)
|
|
end
|
|
|
|
it 'error parsing correctly parses log files larger than the log line total' do
|
|
allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'error_logs', 'long'))
|
|
|
|
logs = ''
|
|
digits = 11..20
|
|
|
|
digits.each do |d|
|
|
logs += "[00/00/0000 00:00:00] [e(0)] core: [-] Error #{d}\n\n"
|
|
end
|
|
|
|
error_log_output = <<~LOG
|
|
## %grnFramework Errors%clr
|
|
|
|
The following framework errors occurred before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 11
|
|
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 12
|
|
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 13
|
|
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 14
|
|
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 15
|
|
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 16
|
|
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 17
|
|
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 18
|
|
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 19
|
|
|
|
[00/00/0000 00:00:00] [e(0)] core: [-] Error 20
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
## %grnWeb Service Errors%clr
|
|
|
|
The following web service errors occurred before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[-] Error 11
|
|
|
|
[-] Error 12
|
|
|
|
[-] Error 13
|
|
|
|
[-] Error 14
|
|
|
|
[-] Error 15
|
|
|
|
[-] Error 16
|
|
|
|
[-] Error 17
|
|
|
|
[-] Error 18
|
|
|
|
[-] Error 19
|
|
|
|
[-] Error 20
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
LOG
|
|
|
|
expect(subject.errors).to eql(error_log_output)
|
|
end
|
|
|
|
it 'error parsing correctly parses empty log files' do
|
|
allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'error_logs', 'empty'))
|
|
|
|
error_log_output = <<~EMPTY
|
|
## %grnFramework Errors%clr
|
|
|
|
The following framework errors occurred before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
No matching patterns were found in framework.log.
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
## %grnWeb Service Errors%clr
|
|
|
|
The following web service errors occurred before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
No matching patterns were found in msf-ws.log.
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
EMPTY
|
|
|
|
expect(subject.errors).to eql(error_log_output)
|
|
end
|
|
|
|
it 'error parsing correctly returns a missing log file message' do
|
|
allow(::Msf::Config).to receive(:log_directory).and_return('FAKE_PATH')
|
|
|
|
error_log_output = <<~EMPTY
|
|
## %grnFramework Errors%clr
|
|
|
|
The following framework errors occurred before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
framework.log does not exist.
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
## %grnWeb Service Errors%clr
|
|
|
|
The following web service errors occurred before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
msf-ws.log does not exist.
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
EMPTY
|
|
|
|
expect(subject.errors).to eql(error_log_output)
|
|
end
|
|
|
|
it 'correctly retrieves and parses a command history shorter than the command total' do
|
|
stub_const('Readline::HISTORY', Array.new(4) { |i| "Command #{i + 1}" })
|
|
|
|
driver = instance_double(
|
|
Msf::Ui::Console::Driver,
|
|
hist_last_saved: 0
|
|
)
|
|
|
|
stub_const('Msf::Ui::Debug::COMMAND_HISTORY_TOTAL', 10)
|
|
|
|
history_output = <<~E_LOG
|
|
## %grnHistory%clr
|
|
|
|
The following commands were ran during the session and before this issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
0 Command 1
|
|
1 Command 2
|
|
2 Command 3
|
|
3 Command 4
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
E_LOG
|
|
|
|
expect(subject.history(driver)).to eql(history_output)
|
|
end
|
|
|
|
it 'correctly retrieves and parses a command history equal in length to the command total' do
|
|
driver = instance_double(
|
|
::Msf::Ui::Console::Driver,
|
|
hist_last_saved: 0
|
|
)
|
|
|
|
stub_const('Msf::Ui::Debug::COMMAND_HISTORY_TOTAL', 10)
|
|
|
|
stub_const('Readline::HISTORY', Array.new(10) { |i| "Command #{i + 1}" })
|
|
|
|
history_output = <<~E_LOG
|
|
## %grnHistory%clr
|
|
|
|
The following commands were ran during the session and before this issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
0 Command 1
|
|
1 Command 2
|
|
2 Command 3
|
|
3 Command 4
|
|
4 Command 5
|
|
5 Command 6
|
|
6 Command 7
|
|
7 Command 8
|
|
8 Command 9
|
|
9 Command 10
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
E_LOG
|
|
|
|
expect(subject.history(driver)).to eql(history_output)
|
|
end
|
|
|
|
it 'correctly retrieves and parses a command history larger than the command total' do
|
|
driver = instance_double(
|
|
::Msf::Ui::Console::Driver,
|
|
hist_last_saved: 0
|
|
)
|
|
|
|
stub_const('Msf::Ui::Debug::COMMAND_HISTORY_TOTAL', 10)
|
|
stub_const('Readline::HISTORY', Array.new(15) { |i| "Command #{i + 1}" })
|
|
|
|
history_output = <<~E_LOG
|
|
## %grnHistory%clr
|
|
|
|
The following commands were ran during the session and before this issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
5 Command 6
|
|
6 Command 7
|
|
7 Command 8
|
|
8 Command 9
|
|
9 Command 10
|
|
10 Command 11
|
|
11 Command 12
|
|
12 Command 13
|
|
13 Command 14
|
|
14 Command 15
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
E_LOG
|
|
|
|
expect(subject.history(driver)).to eql(history_output)
|
|
end
|
|
|
|
it 'correctly retrieves and parses a command history larger than the command total and a session command count smaller than the command total' do
|
|
driver = instance_double(
|
|
::Msf::Ui::Console::Driver,
|
|
hist_last_saved: 10
|
|
)
|
|
|
|
stub_const('Msf::Ui::Debug::COMMAND_HISTORY_TOTAL', 10)
|
|
stub_const('Readline::HISTORY', Array.new(15) { |i| "Command #{i + 1}" })
|
|
|
|
history_output = <<~E_LOG
|
|
## %grnHistory%clr
|
|
|
|
The following commands were ran during the session and before this issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
10 Command 11
|
|
11 Command 12
|
|
12 Command 13
|
|
13 Command 14
|
|
14 Command 15
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
E_LOG
|
|
|
|
expect(subject.history(driver)).to eql(history_output)
|
|
end
|
|
|
|
it 'correctly retrieves and parses an empty config file and datastore' do
|
|
allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'empty.ini'))
|
|
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
datastore: Msf::DataStore.new
|
|
)
|
|
|
|
driver = instance_double(
|
|
::Msf::Ui::Console::Driver,
|
|
get_config_core: 'config_core',
|
|
get_config: {},
|
|
get_config_group: 'config_group',
|
|
active_module: nil
|
|
)
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnModule/Datastore%clr
|
|
|
|
The following global/module datastore, and database setup was configured before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
The local config file is empty, no global variables are set, and there is no active module.
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.datastore(framework, driver)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves and parses a populated global datastore' do
|
|
allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'empty.ini'))
|
|
|
|
framework_datastore = Msf::DataStore.new
|
|
framework_datastore.merge!(
|
|
{
|
|
'key1' => 'val1',
|
|
'key2' => 'val2',
|
|
'key3' => 'val3'
|
|
}
|
|
)
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
datastore: framework_datastore
|
|
)
|
|
|
|
driver = instance_double(
|
|
::Msf::Ui::Console::Driver,
|
|
get_config_core: 'group/name/1',
|
|
get_config: {},
|
|
get_config_group: 'config_group',
|
|
active_module: nil
|
|
)
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnModule/Datastore%clr
|
|
|
|
The following global/module datastore, and database setup was configured before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[group/name/1]
|
|
key1=val1
|
|
key2=val2
|
|
key3=val3
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.datastore(framework, driver)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves and parses a populated global datastore and current module' do
|
|
allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'empty.ini'))
|
|
|
|
datastore = Msf::DataStore.new
|
|
datastore.merge!(
|
|
{
|
|
'key1' => 'val1',
|
|
'key2' => 'val2',
|
|
'key3' => 'val3'
|
|
}
|
|
)
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
datastore: datastore
|
|
)
|
|
|
|
driver = instance_double(
|
|
::Msf::Ui::Console::Driver,
|
|
get_config_core: 'group/name/1',
|
|
get_config: {
|
|
'key4' => 'val4',
|
|
'key5' => 'val5',
|
|
'key6' => 'val6'
|
|
},
|
|
get_config_group: 'group/name/2',
|
|
active_module: nil
|
|
)
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnModule/Datastore%clr
|
|
|
|
The following global/module datastore, and database setup was configured before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[group/name/1]
|
|
key1=val1
|
|
key2=val2
|
|
key3=val3
|
|
|
|
[group/name/2]
|
|
key4=val4
|
|
key5=val5
|
|
key6=val6
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.datastore(framework, driver)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves and parses active module variables' do
|
|
allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'empty.ini'))
|
|
|
|
framework_datastore = Msf::DataStore.new
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
datastore: framework_datastore
|
|
)
|
|
|
|
module_datastore = Msf::ModuleDataStore.new(framework_datastore)
|
|
module_datastore.merge!(
|
|
{
|
|
'key7' => 'val7',
|
|
'key8' => 'default_val8',
|
|
'key9' => 'val9'
|
|
}
|
|
)
|
|
active_module = instance_double(
|
|
Msf::Module,
|
|
datastore: module_datastore,
|
|
refname: 'active/module/variables'
|
|
)
|
|
|
|
driver = instance_double(
|
|
::Msf::Ui::Console::Driver,
|
|
get_config_core: 'group/name/1',
|
|
get_config: {},
|
|
get_config_group: 'config_group',
|
|
active_module: active_module
|
|
)
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnModule/Datastore%clr
|
|
|
|
The following global/module datastore, and database setup was configured before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[active/module/variables]
|
|
key7=val7
|
|
key8=default_val8
|
|
key9=val9
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.datastore(framework, driver)).to eql(expected_output)
|
|
end
|
|
|
|
it 'preferences the framework datastore values over config stored values' do
|
|
allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'module.ini'))
|
|
|
|
framework_datastore = Msf::DataStore.new
|
|
framework_datastore.merge!(
|
|
{
|
|
'key1' => 'val1',
|
|
'key2' => 'val2',
|
|
'key3' => 'val3'
|
|
}
|
|
)
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
datastore: framework_datastore
|
|
)
|
|
|
|
driver = instance_double(
|
|
::Msf::Ui::Console::Driver,
|
|
get_config_core: 'group/name/1',
|
|
get_config: {
|
|
'key4' => 'val4',
|
|
'key5' => 'val5',
|
|
'key6' => 'val6'
|
|
},
|
|
get_config_group: 'group/name/2',
|
|
active_module: nil
|
|
)
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnModule/Datastore%clr
|
|
|
|
The following global/module datastore, and database setup was configured before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[group/name/1]
|
|
key1=val1
|
|
key2=val2
|
|
key3=val3
|
|
|
|
[group/name/2]
|
|
key4=val4
|
|
key5=val5
|
|
key6=val6
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.datastore(framework, driver)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves and parses Database information' do
|
|
allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'db.ini'))
|
|
|
|
framework_datastore = Msf::DataStore.new
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
datastore: framework_datastore
|
|
)
|
|
|
|
driver = instance_double(
|
|
::Msf::Ui::Console::Driver,
|
|
get_config_core: 'group/name/1',
|
|
get_config: {},
|
|
get_config_group: 'group/name/2',
|
|
active_module: nil
|
|
)
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnModule/Datastore%clr
|
|
|
|
The following global/module datastore, and database setup was configured before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[framework/database/1]
|
|
key10=[Filtered]
|
|
key11=[Filtered]
|
|
|
|
[framework/database/2]
|
|
key12=[Filtered]
|
|
key13=[Filtered]
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.datastore(framework, driver)).to eql(expected_output)
|
|
end
|
|
|
|
it 'log parsing correctly retrieves and parses logs shorter than the log line total' do
|
|
range = 1..30
|
|
logs = ''
|
|
range.each do |i|
|
|
logs += "[00/00/0000 00:00:00] [e(0)] core: Log Line #{i}\n"
|
|
end
|
|
|
|
allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'framework_logs', 'short'))
|
|
|
|
error_log_output = <<~E_LOG
|
|
## %grnFramework Logs%clr
|
|
|
|
The following framework logs were recorded before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 1
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 2
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 3
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 4
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 5
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 6
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 7
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 8
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 9
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 10
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 11
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 12
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 13
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 14
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 15
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 16
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 17
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 18
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 19
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 20
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 21
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 22
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 23
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 24
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 25
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 26
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 27
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 28
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 29
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 30
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
## %grnWeb Service Logs%clr
|
|
|
|
The following web service logs were recorded before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[-] core: Log Line 1
|
|
[-] core: Log Line 2
|
|
[-] core: Log Line 3
|
|
[-] core: Log Line 4
|
|
[-] core: Log Line 5
|
|
[-] core: Log Line 6
|
|
[-] core: Log Line 7
|
|
[-] core: Log Line 8
|
|
[-] core: Log Line 9
|
|
[-] core: Log Line 10
|
|
[-] core: Log Line 11
|
|
[-] core: Log Line 12
|
|
[-] core: Log Line 13
|
|
[-] core: Log Line 14
|
|
[-] core: Log Line 15
|
|
[-] core: Log Line 16
|
|
[-] core: Log Line 17
|
|
[-] core: Log Line 18
|
|
[-] core: Log Line 19
|
|
[-] core: Log Line 20
|
|
[-] core: Log Line 21
|
|
[-] core: Log Line 22
|
|
[-] core: Log Line 23
|
|
[-] core: Log Line 24
|
|
[-] core: Log Line 25
|
|
[-] core: Log Line 26
|
|
[-] core: Log Line 27
|
|
[-] core: Log Line 28
|
|
[-] core: Log Line 29
|
|
[-] core: Log Line 30
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
E_LOG
|
|
|
|
expect(subject.logs).to eql(error_log_output)
|
|
end
|
|
|
|
it 'log parsing correctly retrieves and parses logs equal to the log line total' do
|
|
range = 1..50
|
|
logs = ''
|
|
range.each do |i|
|
|
logs += "[00/00/0000 00:00:00] [e(0)] core: Log Line #{i}\n"
|
|
end
|
|
|
|
allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'framework_logs', 'equal'))
|
|
|
|
error_log_output = <<~E_LOG
|
|
## %grnFramework Logs%clr
|
|
|
|
The following framework logs were recorded before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 1
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 2
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 3
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 4
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 5
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 6
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 7
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 8
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 9
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 10
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 11
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 12
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 13
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 14
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 15
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 16
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 17
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 18
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 19
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 20
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 21
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 22
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 23
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 24
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 25
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 26
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 27
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 28
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 29
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 30
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 31
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 32
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 33
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 34
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 35
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 36
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 37
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 38
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 39
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 40
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 41
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 42
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 43
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 44
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 45
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 46
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 47
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 48
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 49
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 50
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
## %grnWeb Service Logs%clr
|
|
|
|
The following web service logs were recorded before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[-] core: Log Line 1
|
|
[-] core: Log Line 2
|
|
[-] core: Log Line 3
|
|
[-] core: Log Line 4
|
|
[-] core: Log Line 5
|
|
[-] core: Log Line 6
|
|
[-] core: Log Line 7
|
|
[-] core: Log Line 8
|
|
[-] core: Log Line 9
|
|
[-] core: Log Line 10
|
|
[-] core: Log Line 11
|
|
[-] core: Log Line 12
|
|
[-] core: Log Line 13
|
|
[-] core: Log Line 14
|
|
[-] core: Log Line 15
|
|
[-] core: Log Line 16
|
|
[-] core: Log Line 17
|
|
[-] core: Log Line 18
|
|
[-] core: Log Line 19
|
|
[-] core: Log Line 20
|
|
[-] core: Log Line 21
|
|
[-] core: Log Line 22
|
|
[-] core: Log Line 23
|
|
[-] core: Log Line 24
|
|
[-] core: Log Line 25
|
|
[-] core: Log Line 26
|
|
[-] core: Log Line 27
|
|
[-] core: Log Line 28
|
|
[-] core: Log Line 29
|
|
[-] core: Log Line 30
|
|
[-] core: Log Line 31
|
|
[-] core: Log Line 32
|
|
[-] core: Log Line 33
|
|
[-] core: Log Line 34
|
|
[-] core: Log Line 35
|
|
[-] core: Log Line 36
|
|
[-] core: Log Line 37
|
|
[-] core: Log Line 38
|
|
[-] core: Log Line 39
|
|
[-] core: Log Line 40
|
|
[-] core: Log Line 41
|
|
[-] core: Log Line 42
|
|
[-] core: Log Line 43
|
|
[-] core: Log Line 44
|
|
[-] core: Log Line 45
|
|
[-] core: Log Line 46
|
|
[-] core: Log Line 47
|
|
[-] core: Log Line 48
|
|
[-] core: Log Line 49
|
|
[-] core: Log Line 50
|
|
[-] core: Log Line 51
|
|
[-] core: Log Line 52
|
|
[-] core: Log Line 53
|
|
[-] core: Log Line 54
|
|
[-] core: Log Line 55
|
|
[-] core: Log Line 56
|
|
[-] core: Log Line 57
|
|
[-] core: Log Line 58
|
|
[-] core: Log Line 59
|
|
[-] core: Log Line 60
|
|
[-] core: Log Line 61
|
|
[-] core: Log Line 62
|
|
[-] core: Log Line 63
|
|
[-] core: Log Line 64
|
|
[-] core: Log Line 65
|
|
[-] core: Log Line 66
|
|
[-] core: Log Line 67
|
|
[-] core: Log Line 68
|
|
[-] core: Log Line 69
|
|
[-] core: Log Line 70
|
|
[-] core: Log Line 71
|
|
[-] core: Log Line 72
|
|
[-] core: Log Line 73
|
|
[-] core: Log Line 74
|
|
[-] core: Log Line 75
|
|
[-] core: Log Line 76
|
|
[-] core: Log Line 77
|
|
[-] core: Log Line 78
|
|
[-] core: Log Line 79
|
|
[-] core: Log Line 80
|
|
[-] core: Log Line 81
|
|
[-] core: Log Line 82
|
|
[-] core: Log Line 83
|
|
[-] core: Log Line 84
|
|
[-] core: Log Line 85
|
|
[-] core: Log Line 86
|
|
[-] core: Log Line 87
|
|
[-] core: Log Line 88
|
|
[-] core: Log Line 89
|
|
[-] core: Log Line 90
|
|
[-] core: Log Line 91
|
|
[-] core: Log Line 92
|
|
[-] core: Log Line 93
|
|
[-] core: Log Line 94
|
|
[-] core: Log Line 95
|
|
[-] core: Log Line 96
|
|
[-] core: Log Line 97
|
|
[-] core: Log Line 98
|
|
[-] core: Log Line 99
|
|
[-] core: Log Line 100
|
|
[-] core: Log Line 101
|
|
[-] core: Log Line 102
|
|
[-] core: Log Line 103
|
|
[-] core: Log Line 104
|
|
[-] core: Log Line 105
|
|
[-] core: Log Line 106
|
|
[-] core: Log Line 107
|
|
[-] core: Log Line 108
|
|
[-] core: Log Line 109
|
|
[-] core: Log Line 110
|
|
[-] core: Log Line 111
|
|
[-] core: Log Line 112
|
|
[-] core: Log Line 113
|
|
[-] core: Log Line 114
|
|
[-] core: Log Line 115
|
|
[-] core: Log Line 116
|
|
[-] core: Log Line 117
|
|
[-] core: Log Line 118
|
|
[-] core: Log Line 119
|
|
[-] core: Log Line 120
|
|
[-] core: Log Line 121
|
|
[-] core: Log Line 122
|
|
[-] core: Log Line 123
|
|
[-] core: Log Line 124
|
|
[-] core: Log Line 125
|
|
[-] core: Log Line 126
|
|
[-] core: Log Line 127
|
|
[-] core: Log Line 128
|
|
[-] core: Log Line 129
|
|
[-] core: Log Line 130
|
|
[-] core: Log Line 131
|
|
[-] core: Log Line 132
|
|
[-] core: Log Line 133
|
|
[-] core: Log Line 134
|
|
[-] core: Log Line 135
|
|
[-] core: Log Line 136
|
|
[-] core: Log Line 137
|
|
[-] core: Log Line 138
|
|
[-] core: Log Line 139
|
|
[-] core: Log Line 140
|
|
[-] core: Log Line 141
|
|
[-] core: Log Line 142
|
|
[-] core: Log Line 143
|
|
[-] core: Log Line 144
|
|
[-] core: Log Line 145
|
|
[-] core: Log Line 146
|
|
[-] core: Log Line 147
|
|
[-] core: Log Line 148
|
|
[-] core: Log Line 149
|
|
[-] core: Log Line 150
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
E_LOG
|
|
|
|
expect(subject.logs).to eql(error_log_output)
|
|
end
|
|
|
|
it 'log parsing correctly retrieves and parses logs larger than the log line total' do
|
|
range = 51..100
|
|
logs = ''
|
|
range.each do |i|
|
|
logs += "[00/00/0000 00:00:00] [e(0)] core: Log Line #{i}\n"
|
|
end
|
|
|
|
allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'framework_logs', 'long'))
|
|
|
|
error_log_output = <<~E_LOG
|
|
## %grnFramework Logs%clr
|
|
|
|
The following framework logs were recorded before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 51
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 52
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 53
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 54
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 55
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 56
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 57
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 58
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 59
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 60
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 61
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 62
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 63
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 64
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 65
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 66
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 67
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 68
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 69
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 70
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 71
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 72
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 73
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 74
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 75
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 76
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 77
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 78
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 79
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 80
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 81
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 82
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 83
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 84
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 85
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 86
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 87
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 88
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 89
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 90
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 91
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 92
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 93
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 94
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 95
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 96
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 97
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 98
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 99
|
|
[00/00/0000 00:00:00] [e(0)] core: Log Line 100
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
## %grnWeb Service Logs%clr
|
|
|
|
The following web service logs were recorded before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
[-] core: Log Line 151
|
|
[-] core: Log Line 152
|
|
[-] core: Log Line 153
|
|
[-] core: Log Line 154
|
|
[-] core: Log Line 155
|
|
[-] core: Log Line 156
|
|
[-] core: Log Line 157
|
|
[-] core: Log Line 158
|
|
[-] core: Log Line 159
|
|
[-] core: Log Line 160
|
|
[-] core: Log Line 161
|
|
[-] core: Log Line 162
|
|
[-] core: Log Line 163
|
|
[-] core: Log Line 164
|
|
[-] core: Log Line 165
|
|
[-] core: Log Line 166
|
|
[-] core: Log Line 167
|
|
[-] core: Log Line 168
|
|
[-] core: Log Line 169
|
|
[-] core: Log Line 170
|
|
[-] core: Log Line 171
|
|
[-] core: Log Line 172
|
|
[-] core: Log Line 173
|
|
[-] core: Log Line 174
|
|
[-] core: Log Line 175
|
|
[-] core: Log Line 176
|
|
[-] core: Log Line 177
|
|
[-] core: Log Line 178
|
|
[-] core: Log Line 179
|
|
[-] core: Log Line 180
|
|
[-] core: Log Line 181
|
|
[-] core: Log Line 182
|
|
[-] core: Log Line 183
|
|
[-] core: Log Line 184
|
|
[-] core: Log Line 185
|
|
[-] core: Log Line 186
|
|
[-] core: Log Line 187
|
|
[-] core: Log Line 188
|
|
[-] core: Log Line 189
|
|
[-] core: Log Line 190
|
|
[-] core: Log Line 191
|
|
[-] core: Log Line 192
|
|
[-] core: Log Line 193
|
|
[-] core: Log Line 194
|
|
[-] core: Log Line 195
|
|
[-] core: Log Line 196
|
|
[-] core: Log Line 197
|
|
[-] core: Log Line 198
|
|
[-] core: Log Line 199
|
|
[-] core: Log Line 200
|
|
[-] core: Log Line 201
|
|
[-] core: Log Line 202
|
|
[-] core: Log Line 203
|
|
[-] core: Log Line 204
|
|
[-] core: Log Line 205
|
|
[-] core: Log Line 206
|
|
[-] core: Log Line 207
|
|
[-] core: Log Line 208
|
|
[-] core: Log Line 209
|
|
[-] core: Log Line 210
|
|
[-] core: Log Line 211
|
|
[-] core: Log Line 212
|
|
[-] core: Log Line 213
|
|
[-] core: Log Line 214
|
|
[-] core: Log Line 215
|
|
[-] core: Log Line 216
|
|
[-] core: Log Line 217
|
|
[-] core: Log Line 218
|
|
[-] core: Log Line 219
|
|
[-] core: Log Line 220
|
|
[-] core: Log Line 221
|
|
[-] core: Log Line 222
|
|
[-] core: Log Line 223
|
|
[-] core: Log Line 224
|
|
[-] core: Log Line 225
|
|
[-] core: Log Line 226
|
|
[-] core: Log Line 227
|
|
[-] core: Log Line 228
|
|
[-] core: Log Line 229
|
|
[-] core: Log Line 230
|
|
[-] core: Log Line 231
|
|
[-] core: Log Line 232
|
|
[-] core: Log Line 233
|
|
[-] core: Log Line 234
|
|
[-] core: Log Line 235
|
|
[-] core: Log Line 236
|
|
[-] core: Log Line 237
|
|
[-] core: Log Line 238
|
|
[-] core: Log Line 239
|
|
[-] core: Log Line 240
|
|
[-] core: Log Line 241
|
|
[-] core: Log Line 242
|
|
[-] core: Log Line 243
|
|
[-] core: Log Line 244
|
|
[-] core: Log Line 245
|
|
[-] core: Log Line 246
|
|
[-] core: Log Line 247
|
|
[-] core: Log Line 248
|
|
[-] core: Log Line 249
|
|
[-] core: Log Line 250
|
|
[-] core: Log Line 251
|
|
[-] core: Log Line 252
|
|
[-] core: Log Line 253
|
|
[-] core: Log Line 254
|
|
[-] core: Log Line 255
|
|
[-] core: Log Line 256
|
|
[-] core: Log Line 257
|
|
[-] core: Log Line 258
|
|
[-] core: Log Line 259
|
|
[-] core: Log Line 260
|
|
[-] core: Log Line 261
|
|
[-] core: Log Line 262
|
|
[-] core: Log Line 263
|
|
[-] core: Log Line 264
|
|
[-] core: Log Line 265
|
|
[-] core: Log Line 266
|
|
[-] core: Log Line 267
|
|
[-] core: Log Line 268
|
|
[-] core: Log Line 269
|
|
[-] core: Log Line 270
|
|
[-] core: Log Line 271
|
|
[-] core: Log Line 272
|
|
[-] core: Log Line 273
|
|
[-] core: Log Line 274
|
|
[-] core: Log Line 275
|
|
[-] core: Log Line 276
|
|
[-] core: Log Line 277
|
|
[-] core: Log Line 278
|
|
[-] core: Log Line 279
|
|
[-] core: Log Line 280
|
|
[-] core: Log Line 281
|
|
[-] core: Log Line 282
|
|
[-] core: Log Line 283
|
|
[-] core: Log Line 284
|
|
[-] core: Log Line 285
|
|
[-] core: Log Line 286
|
|
[-] core: Log Line 287
|
|
[-] core: Log Line 288
|
|
[-] core: Log Line 289
|
|
[-] core: Log Line 290
|
|
[-] core: Log Line 291
|
|
[-] core: Log Line 292
|
|
[-] core: Log Line 293
|
|
[-] core: Log Line 294
|
|
[-] core: Log Line 295
|
|
[-] core: Log Line 296
|
|
[-] core: Log Line 297
|
|
[-] core: Log Line 298
|
|
[-] core: Log Line 299
|
|
[-] core: Log Line 300
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
E_LOG
|
|
|
|
expect(subject.logs).to eql(error_log_output)
|
|
end
|
|
|
|
it 'log parsing correctly retrieves and parses an empty log file' do
|
|
allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'framework_logs', 'empty'))
|
|
|
|
error_log_output = <<~E_LOG
|
|
## %grnFramework Logs%clr
|
|
|
|
The following framework logs were recorded before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
## %grnWeb Service Logs%clr
|
|
|
|
The following web service logs were recorded before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
E_LOG
|
|
|
|
expect(subject.logs).to eql(error_log_output)
|
|
end
|
|
|
|
it 'log parsing correctly retrieves and returns a missing log file message' do
|
|
allow(::Msf::Config).to receive(:log_directory).and_return('FAKE_PATH')
|
|
|
|
error_log_output = <<~E_LOG
|
|
## %grnFramework Logs%clr
|
|
|
|
The following framework logs were recorded before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
framework.log does not exist.
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
## %grnWeb Service Logs%clr
|
|
|
|
The following web service logs were recorded before the issue occurred:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
msf-ws.log does not exist.
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
E_LOG
|
|
|
|
expect(subject.logs).to eql(error_log_output)
|
|
end
|
|
|
|
it 'correctly retrieves features and outputs them' do
|
|
db = instance_double(
|
|
Msf::DBManager,
|
|
connection_established?: false,
|
|
driver: 'driver'
|
|
)
|
|
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
features: instance_double(Msf::FeatureManager, all: features),
|
|
db: db
|
|
)
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnFramework Configuration%clr
|
|
|
|
The features are configured as follows:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
| name | enabled |
|
|
|-:|-:|
|
|
| filtered_options | false |
|
|
| new_search_capabilities | true |
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.framework_config(framework)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves version information with no connected DB' do
|
|
db = instance_double(
|
|
Msf::DBManager,
|
|
connection_established?: false,
|
|
driver: 'driver'
|
|
)
|
|
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
version: 'VERSION',
|
|
db: db
|
|
)
|
|
|
|
allow(::Msf::Config).to receive(:install_root).and_return('bad/path')
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnVersion/Install%clr
|
|
|
|
The versions and install method of your Metasploit setup:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Framework: VERSION
|
|
Ruby: #{RUBY_DESCRIPTION}
|
|
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
|
|
Install Root: bad/path
|
|
Session Type: driver selected, no connection
|
|
Install Method: Other - Please specify
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.versions(framework)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves version information with DB connected via http' do
|
|
db = double(
|
|
'Metasploit::Framework::DataService::DataProxy',
|
|
name: 'db_name',
|
|
driver: 'http',
|
|
connection_established?: true
|
|
)
|
|
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
version: 'VERSION',
|
|
db: db
|
|
)
|
|
|
|
allow(::Msf::Config).to receive(:install_root).and_return('bad/path')
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnVersion/Install%clr
|
|
|
|
The versions and install method of your Metasploit setup:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Framework: VERSION
|
|
Ruby: #{RUBY_DESCRIPTION}
|
|
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
|
|
Install Root: bad/path
|
|
Session Type: Connected to db_name. Connection type: http.
|
|
Install Method: Other - Please specify
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.versions(framework)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves version information with DB connected via local connection' do
|
|
db = double(
|
|
'Metasploit::Framework::DataService::DataProxy',
|
|
connection_established?: true,
|
|
driver: 'local'
|
|
)
|
|
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
version: 'VERSION',
|
|
db: db
|
|
)
|
|
|
|
connection_pool = instance_double(ActiveRecord::ConnectionAdapters::ConnectionPool)
|
|
connection = double(
|
|
'connection',
|
|
current_database: 'current_db_connection',
|
|
respond_to?: true
|
|
)
|
|
allow(connection_pool).to receive(:with_connection).and_yield(connection)
|
|
|
|
allow(::ApplicationRecord).to receive(:connection_pool).and_return(connection_pool)
|
|
allow(::Msf::Config).to receive(:install_root).and_return('bad/path')
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnVersion/Install%clr
|
|
|
|
The versions and install method of your Metasploit setup:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Framework: VERSION
|
|
Ruby: #{RUBY_DESCRIPTION}
|
|
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
|
|
Install Root: bad/path
|
|
Session Type: Connected to current_db_connection. Connection type: local.
|
|
Install Method: Other - Please specify
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.versions(framework)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves version information with no connected DB and a Kali Install' do
|
|
db = instance_double(
|
|
Msf::DBManager,
|
|
connection_established?: false,
|
|
driver: 'driver'
|
|
)
|
|
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
version: 'VERSION',
|
|
db: db
|
|
)
|
|
|
|
allow(::Msf::Config).to receive(:install_root).and_return(File.join(File::SEPARATOR, 'usr', 'share', 'metasploit-framework'))
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnVersion/Install%clr
|
|
|
|
The versions and install method of your Metasploit setup:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Framework: VERSION
|
|
Ruby: #{RUBY_DESCRIPTION}
|
|
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
|
|
Install Root: #{File.join(File::SEPARATOR, 'usr', 'share', 'metasploit-framework')}
|
|
Session Type: driver selected, no connection
|
|
Install Method: Other - Please specify
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.versions(framework)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves version information with no connected DB and an Omnibus Install' do
|
|
db = instance_double(
|
|
Msf::DBManager,
|
|
connection_established?: false,
|
|
driver: 'driver'
|
|
)
|
|
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
version: 'VERSION',
|
|
db: db
|
|
)
|
|
|
|
allow(::Msf::Config).to receive(:install_root).and_return(File.join(file_fixtures_path, 'debug', 'installs', 'omnibus'))
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnVersion/Install%clr
|
|
|
|
The versions and install method of your Metasploit setup:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Framework: VERSION
|
|
Ruby: #{RUBY_DESCRIPTION}
|
|
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
|
|
Install Root: #{File.join(file_fixtures_path, 'debug', 'installs', 'omnibus')}
|
|
Session Type: driver selected, no connection
|
|
Install Method: Omnibus Installer
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.versions(framework)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves version information with no connected DB and a Git Clone' do
|
|
db = instance_double(
|
|
Msf::DBManager,
|
|
connection_established?: false,
|
|
driver: 'driver'
|
|
)
|
|
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
version: 'VERSION',
|
|
db: db
|
|
)
|
|
|
|
allow(::Msf::Config).to receive(:install_root).and_return(File.join(file_fixtures_path, 'debug', 'installs'))
|
|
allow(File).to receive(:directory?).with(File.join(Msf::Config.install_root, '.git')).and_return(true)
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnVersion/Install%clr
|
|
|
|
The versions and install method of your Metasploit setup:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Framework: VERSION
|
|
Ruby: #{RUBY_DESCRIPTION}
|
|
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
|
|
Install Root: #{File.join(file_fixtures_path, 'debug', 'installs')}
|
|
Session Type: driver selected, no connection
|
|
Install Method: Git Clone
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.versions(framework)).to eql(expected_output)
|
|
end
|
|
|
|
it 'correctly retrieves version information with no connected DB and a Arch Pacman install' do
|
|
db = instance_double(
|
|
Msf::DBManager,
|
|
connection_established?: false,
|
|
driver: 'driver'
|
|
)
|
|
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
version: 'VERSION',
|
|
db: db
|
|
)
|
|
|
|
allow(::Msf::Config).to receive(:install_root).times.and_return(File.join(File::SEPARATOR, 'opt', 'metasploit'))
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnVersion/Install%clr
|
|
|
|
The versions and install method of your Metasploit setup:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Framework: VERSION
|
|
Ruby: #{RUBY_DESCRIPTION}
|
|
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
|
|
Install Root: #{File.join(File::SEPARATOR, 'opt', 'metasploit')}
|
|
Session Type: driver selected, no connection
|
|
Install Method: Other - Please specify
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.versions(framework)).to eql(expected_output)
|
|
end
|
|
|
|
describe '#database_configuration' do
|
|
if ENV['REMOTE_DB']
|
|
before {skip('Tests specifically for local DB connections')}
|
|
end
|
|
let!(:workspace) { FactoryBot.create(:mdm_workspace) }
|
|
let(:db) do
|
|
instance_double(
|
|
Msf::DBManager,
|
|
connection_established?: true,
|
|
name: 'msf',
|
|
driver: 'postgresql',
|
|
active: true,
|
|
workspace: workspace,
|
|
workspaces: [workspace]
|
|
)
|
|
end
|
|
let(:framework) { instance_double(::Msf::Framework, version: 'VERSION', db: db) }
|
|
context 'Empty workspace with DB connected' do
|
|
it 'prints the debug output containing 0 counts' do
|
|
expected_output = <<~OUTPUT
|
|
## %grnDatabase Configuration%clr
|
|
|
|
The database contains the following information:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Session Type: Connected to #{ActiveRecord::Base.connection.current_database}. Connection type: postgresql.
|
|
```
|
|
|
|
| ID | Hosts | Vulnerabilities | Notes | Services |
|
|
|-:|-:|-:|-:|-:|
|
|
| #{workspace.id.to_fs(:delimited)} **(Current)** | 0 | 0 | 0 | 0 |
|
|
| **Total (#{::Mdm::Workspace.count})** | **#{::Mdm::Host.count}** | **#{::Mdm::Vuln.count}** | **#{::Mdm::Note.count}** | **#{::Mdm::Service.count}** |
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.database_configuration(framework)).to eql(expected_output)
|
|
end
|
|
|
|
end
|
|
|
|
context 'Non-empty workspace with DB connected' do
|
|
let!(:workspace) { FactoryBot.create(:mdm_workspace) }
|
|
let!(:host) { FactoryBot.create(:mdm_host, workspace: workspace) }
|
|
let!(:vuln) { FactoryBot.create(:mdm_vuln, host: host) }
|
|
let!(:service) { FactoryBot.create(:mdm_service, host: host) }
|
|
let!(:note) { FactoryBot.create(:mdm_note, workspace: workspace, host: host, service: service, vuln: vuln) }
|
|
|
|
it 'prints the debug output with the correct values' do
|
|
expected_output = <<~OUTPUT
|
|
## %grnDatabase Configuration%clr
|
|
|
|
The database contains the following information:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Session Type: Connected to #{ActiveRecord::Base.connection.current_database}. Connection type: postgresql.
|
|
```
|
|
|
|
| ID | Hosts | Vulnerabilities | Notes | Services |
|
|
|-:|-:|-:|-:|-:|
|
|
| #{workspace.id.to_fs(:delimited)} **(Current)** | 1 | 1 | 1 | 1 |
|
|
| **Total (#{::Mdm::Workspace.count})** | **#{::Mdm::Host.count}** | **#{::Mdm::Vuln.count}** | **#{::Mdm::Note.count}** | **#{::Mdm::Service.count}** |
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.database_configuration(framework)).to eql(expected_output)
|
|
end
|
|
end
|
|
|
|
it 'correctly retrieves session type with DB not connected' do
|
|
db = instance_double(
|
|
Msf::DBManager,
|
|
connection_established?: false,
|
|
driver: 'postgresql',
|
|
active: false
|
|
)
|
|
|
|
framework = instance_double(
|
|
::Msf::Framework,
|
|
db: db
|
|
)
|
|
|
|
expected_output = <<~OUTPUT
|
|
## %grnDatabase Configuration%clr
|
|
|
|
The database contains the following information:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Session Type: postgresql selected, no connection
|
|
```
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.database_configuration(framework)).to eql(expected_output)
|
|
end
|
|
|
|
context 'Multiple workspaces with DB connected' do
|
|
let!(:workspaces) { 5.times.map { FactoryBot.create(:mdm_workspace) } }
|
|
let(:workspace) { workspaces.last }
|
|
before do
|
|
allow(::Mdm::Workspace).to receive(:count).and_return(5)
|
|
allow(::Mdm::Workspace).to receive_message_chain(:order, :take).and_return(workspaces)
|
|
allow(::Mdm::Host).to receive(:count).and_return(0)
|
|
allow(::Mdm::Vuln).to receive(:count).and_return(0)
|
|
allow(::Mdm::Note).to receive(:count).and_return(0)
|
|
allow(::Mdm::Service).to receive(:count).and_return(0)
|
|
end
|
|
it 'outputs multiple empty workspaces' do
|
|
expected_output = <<~OUTPUT
|
|
## %grnDatabase Configuration%clr
|
|
|
|
The database contains the following information:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Session Type: Connected to #{ActiveRecord::Base.connection.current_database}. Connection type: postgresql.
|
|
```
|
|
|
|
| ID | Hosts | Vulnerabilities | Notes | Services |
|
|
|-:|-:|-:|-:|-:|
|
|
| #{workspaces[0].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |
|
|
| #{workspaces[1].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |
|
|
| #{workspaces[2].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |
|
|
| #{workspaces[3].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |
|
|
| #{workspaces[4].id.to_fs(:delimited)} **(Current)** | 0 | 0 | 0 | 0 |
|
|
| **Total (#{::Mdm::Workspace.count})** | **#{::Mdm::Host.count}** | **#{::Mdm::Vuln.count}** | **#{::Mdm::Note.count}** | **#{::Mdm::Service.count}** |
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.database_configuration(framework)).to eql(expected_output)
|
|
end
|
|
end
|
|
|
|
context 'Workspaces with different data with DB connected' do
|
|
let!(:workspaces) do
|
|
5.times.map do |index|
|
|
workspace = FactoryBot.create(:mdm_workspace)
|
|
# Only some of the workspaces should have values to make the output not be the same for every workspace.
|
|
if index.even?
|
|
host = FactoryBot.create(:mdm_host, workspace: workspace)
|
|
vuln = FactoryBot.create(:mdm_vuln, host: host)
|
|
service = FactoryBot.create(:mdm_service, host: host)
|
|
FactoryBot.create(:mdm_note, workspace: workspace, host: host, service: service, vuln: vuln)
|
|
end
|
|
workspace
|
|
end
|
|
end
|
|
let(:workspace) { workspaces.last }
|
|
before do
|
|
allow(::Mdm::Workspace).to receive(:count).and_return(5)
|
|
allow(::Mdm::Workspace).to receive_message_chain(:order, :take).and_return(workspaces)
|
|
allow(::Mdm::Host).to receive(:count).and_return(2)
|
|
allow(::Mdm::Vuln).to receive(:count).and_return(2)
|
|
allow(::Mdm::Note).to receive(:count).and_return(2)
|
|
allow(::Mdm::Service).to receive(:count).and_return(2)
|
|
end
|
|
it 'outputs multiple workspaces with content' do
|
|
expected_output = <<~OUTPUT
|
|
## %grnDatabase Configuration%clr
|
|
|
|
The database contains the following information:
|
|
<details>
|
|
<summary>Collapse</summary>
|
|
|
|
```
|
|
Session Type: Connected to #{ActiveRecord::Base.connection.current_database}. Connection type: postgresql.
|
|
```
|
|
|
|
| ID | Hosts | Vulnerabilities | Notes | Services |
|
|
|-:|-:|-:|-:|-:|
|
|
| #{workspaces[0].id.to_fs(:delimited)} | 1 | 1 | 1 | 1 |
|
|
| #{workspaces[1].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |
|
|
| #{workspaces[2].id.to_fs(:delimited)} | 1 | 1 | 1 | 1 |
|
|
| #{workspaces[3].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |
|
|
| #{workspaces[4].id.to_fs(:delimited)} **(Current)** | 1 | 1 | 1 | 1 |
|
|
| **Total (#{::Mdm::Workspace.count})** | **#{::Mdm::Host.count}** | **#{::Mdm::Vuln.count}** | **#{::Mdm::Note.count}** | **#{::Mdm::Service.count}** |
|
|
|
|
</details>
|
|
|
|
|
|
OUTPUT
|
|
|
|
expect(subject.database_configuration(framework)).to eql(expected_output)
|
|
end
|
|
end
|
|
end
|
|
end
|