Package: dnsmule
DNSMulePackage for rule based dependency scanning and service fingerprinting via DNS.This package provides utilities for writing and evaluating verbose and easy to read rule definitions inYAML-format.
There are two builtin rule formats with more available as plugins.Installationpipinstalldnsmule[full]dnsmule_plugins[full]This will install everything available for DNSMule. You can also choose to install components as necessary.For installing from the repo you can use:pipinstall-e.OverviewThe DNSMule tool is composed in the following way:DNSMuleBackendRulesRulePluginsExamplesCheck out the examples in theexamplesfolder. They should get you up and running quickly.YAML ConfigurationSummaryThe tool configuration is done through one or multiple rule configuration files. The file structure is defined in theschema file. In addition to some builtin rule types, it is possible to create new types by
registering handlers or rules programmatically.Rules support registration per DNS record type and priority for controlling invocation order.version:'0.0.1'rules:-name:o365priority:10type:dns.regexrecord:txtconfig:pattern:'^MS=ms'identification:MICROSOFT::O365-name:sestype:dns.regexrecord:txtconfig:pattern:'^amazonses:'identification:AMAZON::SESExamplefromdnsmule.definitionsimportRecord,Resultfromdnsmule.rulesimportRules,Rulerules:Rules...@rules.add.A[10]defmy_scan(record:Record)->Result:fromdnsmule.loggerimportget_loggerget_logger().info('Address%s',record)returnrecord.tag('MY::SCAN')@rules.register('my.rule')defcreate_my_rule(**arguments)->Rule:...Here theaddis used to directly register a new rule into the ruleset with a given priority. Theregistercall
creates a new handler for rules of typemy.rule. Any futuremy.rulecreations from YAML or code would be routed to
this factory function.See the examples folder for more examples and how to use rules in code.Plugins and BackendsPluginsIt is possible to register plugins using the YAML file:plugins:-name:dnsmule_plugins.CertCheckPluginconfig:callback:falseThese are required to extend thednsmule.plugins.Pluginclass.
Plugins are evaluated and initialized before rules.
Any rules requiring a plugin should list their plugin in this block.
Plugins are only initialized once and if a plugin already exists in the receiving DNSMule instance
it will be ignored.BackendsIt is possible to define a single backend in a YAML file:backend:name:'dnspython.DNSPythonBackend'config:timeout:5.5resolver:8.8.8.8The backend must extend thednsmule.backends.Backendclass.
This declaration is ignored if this is not used inDNSMule.loadorDNSMule(file=file).Editor SupportType Hints and JSON Schema (IntelliJ IDEA, PyCharm, etc.)It is possible to register the schema file as a custom JSON schema in IntelliJ editors.
This will give access to typehints and schema validation inside rule files and is especially nice for dynamic rule
definitions as you get full editor features for python inside the snippets.settings...Languages & Frameworks > Schemas and DTDs > JSON Schema MappingsAdd a new mapping with the schema file and specified file or patternThis is configured in the schema using the custom intellij language injection tag:x-intellij-language-injection:
  language: Python
  prefix: |+0
    code hints go here
    check the schema for more info
  suffix: ''Currently, this supportsdns.regexpattern regex language injection anddns.dynamicrule code language injection.
Type hints and quick documentation are available.Builtin RulesRegex rulesRegex rules can be defined with either onepatternor multiplepatterns.
An example is in the following snippet:rules:
  - name: test
    type: dns.regex
    record: txt
    config:
      pattern: '^.*\.hello_world\.'
      identification: HELLO::WORLD
      flags:
        - UNICODE
        - DOTALL
  - name: generic_verification
    type: dns.regex
    record: txt
    priority: 10
    description: Generic Site Regex Collection
    config:
      patterns:
        - '^(.+)(?:-(?:site|domain))?-verification='
        - '^(.+)(?:site|domain)verification'
        - '^(.+)_verify_'
        - '^(\w+)-code:'
      group: 1The full definition and additional info is available from the schema file, examples, and code.Dynamic RulesDynamic rules are defined as code snippets with one or two methodsAn init method that is invoked once after creationdefinit()->None:add_rule(...)A process function that is invoked once for each recorddefprocess(record:Record)->Result:add_rule(...)returnrecord.result()Both of these functions have access to the following rule creation method:defadd_rule(record_type:Union[str,int,RRType],rule_type:str,name:str,*,priority:int=0,**options,)->None:""":param record_type: Valid DNS record type as text, int, or type:param rule_type:   Valid rule type factory e.g. dns.regex:param name:        Name of the created rule:param priority:    Priority for the created rule, default 0:param options:     Any additional options for the rule factory"""The only globals passed to these methods are:__builtins__RRType, Record, Result, Domain, Tag, ConfigThe Config contains theconfigproperty passed to the rule from YAMLadd_ruleAny additional globals created by the code itselfWhen the code is exec'd the result is inspected for:init function without parametersprocess function with a single parameterSome notes:The init function is invoked exactly once.The process function is invoked exactly once for every single Record.Any rules created from the init method will be invoked for every suitable record.Any rules created from the process method will be invoked for suitable records found after creation.Creating DynamicRules from init or process is considered undefined behaviour and care should be takenThe user should call init manually and include fail-safes for only calling it onceThe add_rule callback might not be available so you need to pass it manually to the ruleOtherExample serverThe repo has aDockerfilefor easily running the tool using an example server in Docker:$./build-image
$./run-serverNoticeThis package is under active development.AdditionalRnD Scripts underscriptsExample server underserverExamples for coding underexamples