diff --git a/CHANGELOG.md b/CHANGELOG.md
index 42dbcac3..a938913b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
- Add target option for supplying dedicated port list for alive detection (Boreas only) via OSP. [#323](https://github.com/greenbone/ospd/pull/323)
+- Add target option for supplying alive test methods via separate elements. [#329](https://github.com/greenbone/ospd/pull/329)
### Removed
- Remove python3.5 support and deprecated methods. [#316](https://github.com/greenbone/ospd/pull/316)
diff --git a/doc/OSP.xml b/doc/OSP.xml
index d334639d..d9b80fb7 100644
--- a/doc/OSP.xml
+++ b/doc/OSP.xml
@@ -179,8 +179,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
credentials
exclude_hosts
finished_hosts
- alive_test
alive_test_ports
+
+ alive_test
+ alive_test_methods
+
reverse_lookup_unify
reverse_lookup_only
@@ -196,45 +199,89 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
credentials
- One or many credentials containing the credential for the given hosts.
+ One or many credentials containing the credential for the given hosts
credential
exclude_hosts
- One or many hosts to exclude. The list is comma-separated. Each entry can be a IP address, a CIDR notation, a hostname, a IP range. IPs can be v4 or v6. Each wrapper must handle the exclude hosts.
+ One or many hosts to exclude. The list is comma-separated. Each entry can be a IP address, a CIDR notation, a hostname, a IP range. IPs can be v4 or v6. Each wrapper must handle the exclude hosts
string
finished_hosts
- One or many finished hosts to exclude when the client resumes a task. The list is comma-separated. Each entry can be an IP address, a CIDR notation, a hostname, a IP range. IPs can be v4 or v6. The listed hosts will be set as finished before starting the scan. Each wrapper must handle the finished hosts.
+ One or many finished hosts to exclude when the client resumes a task. The list is comma-separated. Each entry can be an IP address, a CIDR notation, a hostname, a IP range. IPs can be v4 or v6. The listed hosts will be set as finished before starting the scan. Each wrapper must handle the finished hosts
string
alive_test
- Alive test type to be performed against the target.
- string
+ Alive test type to be performed against the target
+ integer
+
+
+ alive_test_methods
+ Alive test methods to be performed against the target
+
+ icmp
+
+
+ icmp
+ ICMP ping
+ boolean
+
+
+ tcp_syn
+
+
+ tcp_syn
+ TCP-SYN ping
+ boolean
+
+
+ tcp_ack
+
+
+ tcp_ack
+ TCP-ACK ping
+ boolean
+
+
+ arp
+
+
+ arp
+ ARP ping
+ boolean
+
+
+ consider_alive
+
+
+ consider_alive
+ Consider the target to be alive
+ boolean
+
alive_test_ports
- Dedicated port list for alive detection. Used for TCP-SYN and TCP-ACK ping when Boreas (scanner preference test_alive_hosts_only) is enabled. If no port list is provided ports 80, 137, 587, 3128, 8081 are used as defaults.
+ Dedicated port list for alive detection. Used for TCP-SYN and TCP-ACK ping when Boreas (scanner preference test_alive_hosts_only) is enabled. If no port list is provided ports 80, 137, 587, 3128, 8081 are used as defaults
string
reverse_lookup_only
- Only scan IP addresses that can be resolved into a DNS name.
+ Only scan IP addresses that can be resolved into a DNS name
string
reverse_lookup_unify
- If multiple IP addresses resolve to the same DNS name the DNS name will only get scanned once.
+ If multiple IP addresses resolve to the same DNS name the DNS name will only get scanned once
string
- Target without credentials.
+ Target without credentials
example.org
@@ -247,7 +294,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- Target with two credentials.
+ Target with two credentials
192.168.1.0/24
@@ -1486,6 +1533,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21.4
+
+ START_SCAN
+ Add support for supplying alive test methods via separate elements.
+ Target element received new optional target option alive_test_methods with subelements imcp, tcp_ack, tcp_syn, arp and consider_alive.
+
+ 21.4
+
+
GET_VTS
Returned object extended with solution method
diff --git a/ospd/protocol.py b/ospd/protocol.py
index bcfb5a0e..d5056fdc 100644
--- a/ospd/protocol.py
+++ b/ospd/protocol.py
@@ -146,6 +146,39 @@ def process_credentials_elements(cred_tree: Element) -> Dict:
return credentials
+ @staticmethod
+ def process_alive_test_methods(
+ alive_test_tree: Element, options: Dict
+ ) -> None:
+ """Receive an XML object with the alive test methods to run
+ a scan with. Methods are added to the options Dict.
+
+ @param
+
+ boolean(1 or 0)
+ boolean(1 or 0)
+ boolean(1 or 0)
+ boolean(1 or 0)
+ boolean(1 or 0)
+
+ """
+ for child in alive_test_tree:
+ if child.tag == 'icmp':
+ if child.text is not None:
+ options['icmp'] = child.text
+ if child.tag == 'tcp_ack':
+ if child.text is not None:
+ options['tcp_ack'] = child.text
+ if child.tag == 'tcp_syn':
+ if child.text is not None:
+ options['tcp_syn'] = child.text
+ if child.tag == 'arp':
+ if child.text is not None:
+ options['arp'] = child.text
+ if child.tag == 'consider_alive':
+ if child.text is not None:
+ options['consider_alive'] = child.text
+
@classmethod
def process_target_element(cls, scanner_target: Element) -> Dict:
"""Receive an XML object with the target, ports and credentials to run
@@ -222,6 +255,9 @@ def process_target_element(cls, scanner_target: Element) -> Dict:
ports = child.text
if child.tag == 'credentials':
credentials = cls.process_credentials_elements(child)
+ if child.tag == 'alive_test_methods':
+ options['alive_test_methods'] = '1'
+ cls.process_alive_test_methods(child, options)
if child.tag == 'alive_test':
options['alive_test'] = child.text
if child.tag == 'alive_test_ports':
diff --git a/tests/test_scan_and_result.py b/tests/test_scan_and_result.py
index 9ab57c71..fdeed807 100644
--- a/tests/test_scan_and_result.py
+++ b/tests/test_scan_and_result.py
@@ -238,7 +238,8 @@ def test_get_vts_filter_negative(self):
)
fs = FakeStream()
self.daemon.handle_command(
- '', fs,
+ '',
+ fs,
)
response = fs.get_response()
@@ -741,7 +742,8 @@ def test_get_scan_results_clean(self):
fs = FakeStream()
self.daemon.handle_command(
- '' % scan_id, fs,
+ '' % scan_id,
+ fs,
)
res_len = len(
@@ -771,7 +773,8 @@ def test_get_scan_results_restore(self):
fs = FakeStream(return_value=False)
self.daemon.handle_command(
- '' % scan_id, fs,
+ '' % scan_id,
+ fs,
)
res_len = len(
@@ -893,6 +896,82 @@ def test_scan_get_target_options(self):
target_options = self.daemon.get_scan_target_options(scan_id)
self.assertEqual(target_options, {'alive_test': '0'})
+ def test_scan_get_target_options_alive_test_methods(self):
+ fs = FakeStream()
+ self.daemon.handle_command(
+ ''
+ ''
+ ''
+ ''
+ '192.168.0.1'
+ '22'
+ ''
+ '1'
+ '1'
+ '1'
+ '1'
+ '1'
+ ''
+ ''
+ ''
+ '',
+ fs,
+ )
+ self.daemon.start_queued_scans()
+
+ response = fs.get_response()
+
+ scan_id = response.findtext('id')
+ time.sleep(1)
+ target_options = self.daemon.get_scan_target_options(scan_id)
+ self.assertEqual(
+ target_options,
+ {
+ 'alive_test_methods': '1',
+ 'icmp': '1',
+ 'tcp_syn': '1',
+ 'tcp_ack': '1',
+ 'arp': '1',
+ 'consider_alive': '1',
+ },
+ )
+
+ def test_scan_get_target_options_alive_test_methods_dont_add_empty_or_missing( # pylint: disable=line-too-long
+ self,
+ ):
+ fs = FakeStream()
+ self.daemon.handle_command(
+ ''
+ ''
+ ''
+ ''
+ '192.168.0.1'
+ '22'
+ ''
+ '1'
+ ''
+ ''
+ ''
+ ''
+ ''
+ '',
+ fs,
+ )
+ self.daemon.start_queued_scans()
+
+ response = fs.get_response()
+
+ scan_id = response.findtext('id')
+ time.sleep(1)
+ target_options = self.daemon.get_scan_target_options(scan_id)
+ self.assertEqual(
+ target_options,
+ {
+ 'alive_test_methods': '1',
+ 'icmp': '1',
+ },
+ )
+
def test_progress(self):
fs = FakeStream()
@@ -1087,7 +1166,8 @@ def test_get_scan_progress_xml(self):
fs = FakeStream()
self.daemon.handle_command(
- '' % scan_id, fs,
+ '' % scan_id,
+ fs,
)
response = fs.get_response()
@@ -1164,7 +1244,8 @@ def test_scan_exists(self, mock_create_process, _mock_os):
)
self.daemon.handle_command(
- cmd, fs,
+ cmd,
+ fs,
)
self.daemon.start_queued_scans()