def _explicit_conversions(function_name: str) -> SNMPDetectSpecification: if function_name in MIGRATED_SCAN_FUNCTIONS: return MIGRATED_SCAN_FUNCTIONS[function_name] if function_name == '_is_fsc_or_windows': return any_of( startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.231'), startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.311'), startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.8072'), ) if function_name == 'is_fsc': return all_of( _explicit_conversions('_is_fsc_or_windows'), exists('.1.3.6.1.4.1.231.2.10.2.1.1.0'), ) if function_name == 'is_netapp_filer': return any_of( contains(".1.3.6.1.2.1.1.1.0", "ontap"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.789"), ) if function_name == '_has_table_2': return exists(".1.3.6.1.4.1.9.9.109.1.1.1.1.2.*") if function_name == '_is_cisco': return contains(".1.3.6.1.2.1.1.1.0", "cisco") if function_name == '_is_cisco_nexus': return contains(".1.3.6.1.2.1.1.1.0", "nx-os") raise NotImplementedError(function_name)
def _explicit_conversions(function_name): # type: (str) -> SNMPDetectSpec if function_name == 'has_ifHCInOctets': return exists('.1.3.6.1.2.1.31.1.1.1.6.*') if function_name == '_is_fsc_or_windows': return any_of( startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.231'), startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.311'), startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.8072'), ) if function_name == '_is_ucd': return any_of( contains(".1.3.6.1.2.1.1.1.0", "linux"), contains(".1.3.6.1.2.1.1.1.0", "cmc-tc"), contains(".1.3.6.1.2.1.1.1.0", "hp onboard administrator"), contains(".1.3.6.1.2.1.1.1.0", "barracuda"), contains(".1.3.6.1.2.1.1.1.0", "pfsense"), contains(".1.3.6.1.2.1.1.1.0", "genugate"), contains(".1.3.6.1.2.1.1.1.0", "bomgar"), contains(".1.3.6.1.2.1.1.1.0", "pulse secure"), all_of( equals('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.8072.3.2.10'), contains(".1.3.6.1.2.1.1.1.0", "version"), contains(".1.3.6.1.2.1.1.1.0", "serial"), ), ) if function_name == 'scan_ricoh_printer': return all_of( contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.367.1.1"), exists(".1.3.6.1.4.1.367.3.2.1.2.19.5.1.5.1"), ) if function_name == 'is_fsc': return all_of( _explicit_conversions('_is_fsc_or_windows'), exists('.1.3.6.1.4.1.231.2.10.2.1.1.0'), ) if function_name == 'is_netapp_filer': return any_of( contains(".1.3.6.1.2.1.1.1.0", "ontap"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.789"), ) if function_name == '_has_table_8': return exists(".1.3.6.1.4.1.9.9.109.1.1.1.1.8.*") if function_name == '_is_cisco': return contains(".1.3.6.1.2.1.1.1.0", "cisco") if function_name == '_is_cisco_nexus': return contains(".1.3.6.1.2.1.1.1.0", "nx-os") raise NotImplementedError(function_name)
def _ast_convert_call(call_ast): # type: (ast.Call) -> SNMPDetectSpec if isinstance(call_ast.func, ast.Name): if call_ast.func.id == 'bool': assert _is_oid_function(call_ast.args[0]) return exists(_ast_convert_to_str(call_ast.args[0])) if call_ast.func.id in ( 'has_ifHCInOctets', 'is_fsc', '_is_ucd', '_is_fsc_or_windows', 'scan_ricoh_printer', 'is_netapp_filer', '_has_table_2', '_is_cisco', '_is_cisco_nexus', ): return _explicit_conversions(call_ast.func.id) if call_ast.func.id in ( 'if64_disabled', 'scan_f5_bigip_cluster_status_pre_11_2', 'scan_f5_bigip_cluster_status_11_2_upwards', 'scan_cisco_mem_asa64', ): raise NotImplementedError(call_ast.func.id) if isinstance(call_ast.func, ast.Attribute): assert _is_oid_function(call_ast.func.value) assert len(call_ast.args) == 1 if call_ast.func.attr == 'startswith': return startswith( _ast_convert_to_str(call_ast.func.value), _ast_convert_to_str(call_ast.args[0]), ) if call_ast.func.attr == 'endswith': return endswith( _ast_convert_to_str(call_ast.func.value), _ast_convert_to_str(call_ast.args[0]), ) if isinstance(call_ast.func.value, ast.Name) and call_ast.func.value.id == 're': assert call_ast.func.attr == 'match' raise NotImplementedError("regular expression") if _is_oid_function(call_ast): return exists(_ast_convert_to_str(call_ast)) raise ValueError(ast.dump(call_ast))
def _ast_convert_call(call_ast: ast.Call) -> SNMPDetectSpecification: if isinstance(call_ast.func, ast.Name): if call_ast.func.id == "bool": assert _is_oid_function(call_ast.args[0]) return exists(_ast_convert_to_str(call_ast.args[0])) if call_ast.func.id in ( "is_fsc", "_is_ucd", "_is_fsc_or_windows", "scan_ricoh_printer", "is_netapp_filer", "_has_table_2", "_is_cisco", "_is_cisco_nexus", ): return _explicit_conversions(call_ast.func.id) if call_ast.func.id in ( "scan_f5_bigip_cluster_status_pre_11_2", "scan_f5_bigip_cluster_status_11_2_upwards", "scan_cisco_mem_asa64", ): raise NotImplementedError(call_ast.func.id) if isinstance(call_ast.func, ast.Attribute): assert _is_oid_function(call_ast.func.value) assert len(call_ast.args) == 1 if call_ast.func.attr == "startswith": return startswith( _ast_convert_to_str(call_ast.func.value), _ast_convert_to_str(call_ast.args[0]), ) if call_ast.func.attr == "endswith": return endswith( _ast_convert_to_str(call_ast.func.value), _ast_convert_to_str(call_ast.args[0]), ) if isinstance(call_ast.func.value, ast.Name) and call_ast.func.value.id == "re": assert call_ast.func.attr == "match" raise NotImplementedError("regular expression") if _is_oid_function(call_ast): return exists(_ast_convert_to_str(call_ast)) raise ValueError(ast.dump(call_ast))
def test_exists(testcases): spec = utils.exists(".1.2.3") _validate_detect_spec(spec) assert len(spec) == 1 assert len(spec[0]) == 1 expr = spec[0][0][1] test, result = testcases assert result is bool(re.match(expr, test))
def _ast_convert_compare(comp_ast): # type: (ast.Compare) -> SNMPDetectSpec assert len(comp_ast.ops) == 1 if isinstance(comp_ast.ops[0], ast.In): assert len(comp_ast.comparators) == 1 if _is_oid_function(comp_ast.left): assert isinstance(comp_ast.left, ast.Call) oid_str = _ast_convert_to_str(comp_ast.left) if isinstance(comp_ast.comparators[0], (ast.List, ast.Tuple)): return any_of(*(equals( oid_str, _ast_convert_to_str(v), ) for v in comp_ast.comparators[0].elts)) if isinstance(comp_ast.left, ast.Str): assert _is_oid_function(comp_ast.comparators[0]) return contains( _ast_convert_to_str(comp_ast.comparators[0]), _ast_convert_to_str(comp_ast.left), ) if isinstance(comp_ast.ops[0], ast.Eq): assert isinstance(comp_ast.left, ast.Call) assert len(comp_ast.comparators) == 1 assert isinstance(comp_ast.comparators[0], ast.Str) return equals( _ast_convert_to_str(comp_ast.left), comp_ast.comparators[0].s, ) if isinstance(comp_ast.ops[0], ast.NotEq): assert isinstance(comp_ast.left, ast.Call) assert len(comp_ast.comparators) == 1 assert isinstance(comp_ast.comparators[0], ast.Str) return not_equals( _ast_convert_to_str(comp_ast.left), comp_ast.comparators[0].s, ) if isinstance(comp_ast.ops[0], ast.IsNot): assert _is_none(comp_ast.comparators[0]) if _is_oid_function(comp_ast.left): return exists(_ast_convert_to_str(comp_ast.left)) raise NotImplementedError() # regex, I think if isinstance(comp_ast.ops[0], ast.Is): assert _is_none(comp_ast.comparators[0]) assert _is_oid_function(comp_ast.left) return not_exists(_ast_convert_to_str(comp_ast.left)) if isinstance(comp_ast.ops[0], (ast.GtE, ast.Lt)): raise NotImplementedError() raise ValueError(ast.dump(comp_ast))