diff --git a/CHANGELOG.md b/CHANGELOG.md index 29fb3dc1..a9fad897 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 solution method to solution of vt object. [#131](https://github.com/greenbone/ospd-openvas/pull/131) - Add typing to daemon.py, nvticache.py and db.py. [#161](https://github.com/greenbone/ospd-openvas/pull/161)[#162](https://github.com/greenbone/ospd-openvas/pull/162)[#163](https://github.com/greenbone/ospd-openvas/pull/163) +- Add support for alive test settings. [#182](https://github.com/greenbone/ospd-openvas/pull/182) ### Changed - Less strict checks for the nvti cache version diff --git a/Pipfile.lock b/Pipfile.lock index 07db0eff..742c453f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -142,22 +142,22 @@ "ospd": { "editable": true, "git": "https://github.com/greenbone/ospd.git", - "ref": "ea4bdef3ba9a961032f150f3c4481c9db6bee6fd" + "ref": "f710afcef24df83379245e0b6969239fe5438756" }, "packaging": { "hashes": [ - "sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47", - "sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108" + "sha256:aec3fdbb8bc9e4bb65f0634b9f551ced63983a529d6a8931817d52fdd0816ddb", + "sha256:fe1d8331dfa7cc0a883b49d75fc76380b2ab2734b220fbb87d774e4fd4b851f8" ], "index": "pypi", - "version": "==19.2" + "version": "==20.0" }, "paramiko": { "hashes": [ - "sha256:ee034658ca12be4eafb62609e192d68f89c83626f5ac4fcb29cedd4e3e7e3c51", - "sha256:fba9c46340e3d690ad5a9d0dbf06677cd91425de3afa7e9c0c187298ee4ddd0d" + "sha256:920492895db8013f6cc0179293147f830b8c7b21fdfc839b6bad760c27459d9f", + "sha256:9c980875fa4d2cb751604664e9a2d0f69096643f5be4db1b99599fe114a97b2f" ], - "version": "==2.7.0" + "version": "==2.7.1" }, "psutil": { "hashes": [ @@ -210,10 +210,10 @@ }, "pyparsing": { "hashes": [ - "sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f", - "sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a" + "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f", + "sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec" ], - "version": "==2.4.5" + "version": "==2.4.6" }, "redis": { "hashes": [ @@ -225,10 +225,10 @@ }, "six": { "hashes": [ - "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", - "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" + "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", + "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" ], - "version": "==1.13.0" + "version": "==1.14.0" } }, "develop": { @@ -341,9 +341,10 @@ }, "pathspec": { "hashes": [ - "sha256:e285ccc8b0785beadd4c18e5708b12bb8fcf529a1e61215b3feff1d1e559ea5c" + "sha256:163b0632d4e31cef212976cf57b43d9fd6b0bac6e67c26015d611a647d5e7424", + "sha256:562aa70af2e0d434367d9790ad37aed893de47f1693e4201fd1d3dca15d19b96" ], - "version": "==0.6.0" + "version": "==0.7.0" }, "pylint": { "hashes": [ @@ -355,28 +356,36 @@ }, "regex": { "hashes": [ - "sha256:15454b37c5a278f46f7aa2d9339bda450c300617ca2fca6558d05d870245edc7", - "sha256:1ad40708c255943a227e778b022c6497c129ad614bb7a2a2f916e12e8a359ee7", - "sha256:5e00f65cc507d13ab4dfa92c1232d004fa202c1d43a32a13940ab8a5afe2fb96", - "sha256:604dc563a02a74d70ae1f55208ddc9bfb6d9f470f6d1a5054c4bd5ae58744ab1", - "sha256:720e34a539a76a1fedcebe4397290604cc2bdf6f81eca44adb9fb2ea071c0c69", - "sha256:7caf47e4a9ac6ef08cabd3442cc4ca3386db141fb3c8b2a7e202d0470028e910", - "sha256:7faf534c1841c09d8fefa60ccde7b9903c9b528853ecf41628689793290ca143", - "sha256:b4e0406d822aa4993ac45072a584d57aa4931cf8288b5455bbf30c1d59dbad59", - "sha256:c31eaf28c6fe75ea329add0022efeed249e37861c19681960f99bbc7db981fb2", - "sha256:c7393597191fc2043c744db021643549061e12abe0b3ff5c429d806de7b93b66", - "sha256:d2b302f8cdd82c8f48e9de749d1d17f85ce9a0f082880b9a4859f66b07037dc6", - "sha256:e3d8dd0ec0ea280cf89026b0898971f5750a7bd92cb62c51af5a52abd020054a", - "sha256:ec032cbfed59bd5a4b8eab943c310acfaaa81394e14f44454ad5c9eba4f24a74" - ], - "version": "==2019.11.1" + "sha256:07b39bf943d3d2fe63d46281d8504f8df0ff3fe4c57e13d1656737950e53e525", + "sha256:0932941cdfb3afcbc26cc3bcf7c3f3d73d5a9b9c56955d432dbf8bbc147d4c5b", + "sha256:0e182d2f097ea8549a249040922fa2b92ae28be4be4895933e369a525ba36576", + "sha256:10671601ee06cf4dc1bc0b4805309040bb34c9af423c12c379c83d7895622bb5", + "sha256:23e2c2c0ff50f44877f64780b815b8fd2e003cda9ce817a7fd00dea5600c84a0", + "sha256:26ff99c980f53b3191d8931b199b29d6787c059f2e029b2b0c694343b1708c35", + "sha256:27429b8d74ba683484a06b260b7bb00f312e7c757792628ea251afdbf1434003", + "sha256:3e77409b678b21a056415da3a56abfd7c3ad03da71f3051bbcdb68cf44d3c34d", + "sha256:4e8f02d3d72ca94efc8396f8036c0d3bcc812aefc28ec70f35bb888c74a25161", + "sha256:4eae742636aec40cf7ab98171ab9400393360b97e8f9da67b1867a9ee0889b26", + "sha256:6a6ae17bf8f2d82d1e8858a47757ce389b880083c4ff2498dba17c56e6c103b9", + "sha256:6a6ba91b94427cd49cd27764679024b14a96874e0dc638ae6bdd4b1a3ce97be1", + "sha256:7bcd322935377abcc79bfe5b63c44abd0b29387f267791d566bbb566edfdd146", + "sha256:98b8ed7bb2155e2cbb8b76f627b2fd12cf4b22ab6e14873e8641f266e0fb6d8f", + "sha256:bd25bb7980917e4e70ccccd7e3b5740614f1c408a642c245019cff9d7d1b6149", + "sha256:d0f424328f9822b0323b3b6f2e4b9c90960b24743d220763c7f07071e0778351", + "sha256:d58e4606da2a41659c84baeb3cfa2e4c87a74cec89a1e7c56bee4b956f9d7461", + "sha256:e3cd21cc2840ca67de0bbe4071f79f031c81418deb544ceda93ad75ca1ee9f7b", + "sha256:e6c02171d62ed6972ca8631f6f34fa3281d51db8b326ee397b9c83093a6b7242", + "sha256:e7c7661f7276507bce416eaae22040fd91ca471b5b33c13f8ff21137ed6f248c", + "sha256:ecc6de77df3ef68fee966bb8cb4e067e84d4d1f397d0ef6fce46913663540d77" + ], + "version": "==2020.1.8" }, "six": { "hashes": [ - "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", - "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" + "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", + "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" ], - "version": "==1.13.0" + "version": "==1.14.0" }, "toml": { "hashes": [ @@ -387,29 +396,30 @@ }, "typed-ast": { "hashes": [ - "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", - "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", - "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", - "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", - "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", - "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", - "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", - "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", - "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", - "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", - "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", - "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", - "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", - "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", - "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", - "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", - "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", - "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", - "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", - "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" + "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", + "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", + "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", + "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", + "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", + "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", + "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", + "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", + "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", + "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", + "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", + "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", + "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", + "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", + "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", + "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", + "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", + "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", + "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", + "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", + "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" ], "markers": "implementation_name == 'cpython' and python_version < '3.8'", - "version": "==1.4.0" + "version": "==1.4.1" }, "wrapt": { "hashes": [ diff --git a/ospd_openvas/daemon.py b/ospd_openvas/daemon.py index 146e90ac..321930da 100644 --- a/ospd_openvas/daemon.py +++ b/ospd_openvas/daemon.py @@ -28,6 +28,7 @@ import binascii import copy +from enum import IntEnum from typing import Optional, Dict, List, Tuple from datetime import datetime from base64 import b64decode @@ -229,6 +230,17 @@ OID_SMB_AUTH = "1.3.6.1.4.1.25623.1.0.90023" OID_ESXI_AUTH = "1.3.6.1.4.1.25623.1.0.105058" OID_SNMP_AUTH = "1.3.6.1.4.1.25623.1.0.105076" +OID_PING_HOST = "1.3.6.1.4.1.25623.1.0.100315" + + +class AliveTest(IntEnum): + """ Alive Tests. """ + + ALIVE_TEST_TCP_ACK_SERVICE = 1 + ALIVE_TEST_ICMP = 2 + ALIVE_TEST_ARP = 4 + ALIVE_TEST_CONSIDER_ALIVE = 8 + ALIVE_TEST_TCP_SYN_SERVICE = 16 def _from_bool_to_str(value: int) -> str: @@ -1195,10 +1207,10 @@ def check_param_type(vt_param_value: str, param_type: str) -> Optional[int]: return 1 - def process_vts(self, vts: List) -> Tuple[list, list]: + def process_vts(self, vts: List) -> Tuple[list, dict]: """ Add single VTs and their parameters. """ vts_list = [] - vts_params = [] + vts_params = {} vtgroups = vts.pop('vt_groups') if vtgroups: @@ -1238,13 +1250,12 @@ def process_vts(self, vts: List) -> Tuple[list, list]: continue if type_aux == 'checkbox': vt_param_value = _from_bool_to_str(int(vt_param_value)) - param = [ + vts_params[ "{0}:{1}:{2}:{3}".format( vtid, vt_param_id, param_type, param_name - ), - str(vt_param_value), - ] - vts_params.append(param) + ) + ] = str(vt_param_value) + return vts_list, vts_params @staticmethod @@ -1362,6 +1373,110 @@ def build_credentials_as_prefs(credentials: Dict) -> List[str]: return cred_prefs_list + @staticmethod + def build_alive_test_opt_as_prefs(target_options: Dict) -> List[str]: + """ Parse the target options dictionary. + @param credentials: Dictionary with the target options. + + @return A list with the target options in string format to be + added to the redis KB. + """ + target_opt_prefs_list = [] + if target_options and target_options.get('alive_test'): + try: + alive_test = int(target_options.get('alive_test')) + except ValueError: + logger.debug( + 'Alive test settings not applied. ' + 'Invalid alive test value %s', + target_options.get('alive_test'), + ) + return target_opt_prefs_list + + if alive_test < 1 or alive_test > 31: + return target_opt_prefs_list + + if ( + alive_test & AliveTest.ALIVE_TEST_TCP_ACK_SERVICE + or alive_test & AliveTest.ALIVE_TEST_TCP_SYN_SERVICE + ): + value = "yes" + else: + value = "no" + target_opt_prefs_list.append( + OID_PING_HOST + + ':1:checkbox:' + + 'Do a TCP ping|||' + + '{0}'.format(value) + ) + + if ( + alive_test & AliveTest.ALIVE_TEST_TCP_SYN_SERVICE + and alive_test & AliveTest.ALIVE_TEST_TCP_ACK_SERVICE + ): + value = "yes" + else: + value = "no" + target_opt_prefs_list.append( + OID_PING_HOST + + ':2:checkbox:' + + 'TCP ping tries also TCP-SYN ping|||' + + '{0}'.format(value) + ) + + if (alive_test & AliveTest.ALIVE_TEST_TCP_SYN_SERVICE) and not ( + alive_test & AliveTest.ALIVE_TEST_TCP_ACK_SERVICE + ): + value = "yes" + else: + value = "no" + target_opt_prefs_list.append( + OID_PING_HOST + + ':7:checkbox:' + + 'TCP ping tries only TCP-SYN ping|||' + + '{0}'.format(value) + ) + + if alive_test & AliveTest.ALIVE_TEST_ICMP: + value = "yes" + else: + value = "no" + target_opt_prefs_list.append( + OID_PING_HOST + + ':3:checkbox:' + + 'Do an ICMP ping|||' + + '{0}'.format(value) + ) + + if alive_test & AliveTest.ALIVE_TEST_ARP: + value = "yes" + else: + value = "no" + target_opt_prefs_list.append( + OID_PING_HOST + + ':4:checkbox:' + + 'Use ARP|||' + + '{0}'.format(value) + ) + + if alive_test & AliveTest.ALIVE_TEST_CONSIDER_ALIVE: + value = "no" + else: + value = "yes" + target_opt_prefs_list.append( + OID_PING_HOST + + ':5:checkbox:' + + 'Mark unrechable Hosts as dead (not scanning)|||' + + '{0}'.format(value) + ) + + # Also select a method, otherwise Ping Host logs a warning. + if alive_test == AliveTest.ALIVE_TEST_CONSIDER_ALIVE: + target_opt_prefs_list.append( + OID_PING_HOST + ':1:checkbox:' + 'Do a TCP ping|||yes' + ) + return target_opt_prefs_list + def exec_scan(self, scan_id: str, target: str): """ Starts the OpenVAS scanner for scan_id scan. """ if self.pending_feed: @@ -1484,9 +1599,19 @@ def exec_scan(self, scan_id: str, target: str): self.openvas_db.add_single_item( 'internal/%s/scanprefs' % openvas_scan_id, [plugin_list] ) + # Set alive test option. Overwrite the scan config settings. + target_options = self.get_scan_target_options(scan_id, target) + if target_options: + alive_test_opt = self.build_alive_test_opt_as_prefs( + target_options + ) + for elem in alive_test_opt: + key, val = elem.split("|||", 2) + nvts_params[key] = val + # Add nvts parameters - for elem in nvts_params: - item = '%s|||%s' % (elem[0], elem[1]) + for key, val in nvts_params.items(): + item = '%s|||%s' % (key, val) self.openvas_db.add_single_item( 'internal/%s/scanprefs' % openvas_scan_id, [item] ) diff --git a/tests/test_daemon.py b/tests/test_daemon.py index e4301832..17c06bad 100644 --- a/tests/test_daemon.py +++ b/tests/test_daemon.py @@ -575,6 +575,40 @@ def test_build_credentials_ssh_up(self, mock_nvti, mock_db): ret = w.build_credentials_as_prefs(cred_dict) self.assertEqual(ret, cred_out) + def test_build_alive_test_opt_empty(self, mock_nvti, mock_db): + w = DummyDaemon(mock_nvti, mock_db) + target_options_dict = {'alive_test': '0'} + + self.maxDiff = None + ret = w.build_alive_test_opt_as_prefs(target_options_dict) + self.assertEqual(ret, []) + + def test_build_alive_test_opt(self, mock_nvti, mock_db): + w = DummyDaemon(mock_nvti, mock_db) + alive_test_out = [ + "1.3.6.1.4.1.25623.1.0.100315:1:checkbox:Do a TCP ping|||no", + "1.3.6.1.4.1.25623.1.0.100315:2:checkbox:TCP ping tries also TCP-SYN ping|||no", + "1.3.6.1.4.1.25623.1.0.100315:7:checkbox:TCP ping tries only TCP-SYN ping|||no", + "1.3.6.1.4.1.25623.1.0.100315:3:checkbox:Do an ICMP ping|||yes", + "1.3.6.1.4.1.25623.1.0.100315:4:checkbox:Use ARP|||no", + "1.3.6.1.4.1.25623.1.0.100315:5:checkbox:Mark unrechable Hosts as dead (not scanning)|||yes", + ] + target_options_dict = {'alive_test': '2'} + + self.maxDiff = None + ret = w.build_alive_test_opt_as_prefs(target_options_dict) + self.assertEqual(ret, alive_test_out) + + def test_build_alive_test_opt_fail_1(self, mock_nvti, mock_db): + w = DummyDaemon(mock_nvti, mock_db) + target_options_dict = {'alive_test': 'a'} + + self.maxDiff = None + logging.Logger.debug = Mock() + ret = w.build_alive_test_opt_as_prefs(target_options_dict) + if hasattr(Mock, 'assert_called_once'): + logging.Logger.debug.assert_called_once() + def test_process_vts(self, mock_nvti, mock_db): vts = { '1.3.6.1.4.1.25623.1.0.100061': {'1': 'new value'}, @@ -582,12 +616,7 @@ def test_process_vts(self, mock_nvti, mock_db): } vt_out = ( ['1.3.6.1.4.1.25623.1.0.100061'], - [ - [ - '1.3.6.1.4.1.25623.1.0.100061:1:entry:Data length :', - 'new value', - ] - ], + {'1.3.6.1.4.1.25623.1.0.100061:1:entry:Data length :': 'new value'}, ) w = DummyDaemon(mock_nvti, mock_db)