|
| 1 | +# Instructions on Adding New Renders |
| 2 | +## General |
| 3 | +The translation engine of Uncoder IO is conceptually composed of renders, parsers, and mapping files for each supported language. |
| 4 | +- A render is a component that generates the target query/rule from a source language (Sigma, Roota). |
| 5 | +- A parser is a component that parses the source rule into objects that consequently are used to generate the destination query/rule by the render. |
| 6 | +- A mapping file is a dictionary that maps the source fields to target fields as well as source log sources to target log sources. |
| 7 | + |
| 8 | +Uncoder IO supports the following parsers: |
| 9 | +- Roota |
| 10 | +- Sigma |
| 11 | +- IOCs |
| 12 | + |
| 13 | +We encourage you to contribute renders that enable translating from Roota, Sigma, and IOCs into your SIEM, EDR/XDR, or Data Lake. |
| 14 | + |
| 15 | +You can find the list of supported target platforms in the [platforms](https://github.com/UncoderIO/Uncoder_IO/tree/main/translator/app/translator/platforms) directory. |
| 16 | + |
| 17 | +## How to Add a New Render |
| 18 | + |
| 19 | +All code related to translation has to be in the directory with the corresponding platform name in `translator/app/translator/platforms`. |
| 20 | + |
| 21 | +- `translator/app/translator/platforms/<platform_name>/renders` – a directory that contains platform renders for different content types (such as rules and queries translated from a source language or queries generated based on parsed IOCs). |
| 22 | +- `const.py` – a Python file that contains metainformation about the platform. |
| 23 | +- `escape_manager.py` – a Python file that contains classes describing the rules of escaping special characters. |
| 24 | +- `mapping.py` – a Python file that contains classes that describe working with mappings. |
| 25 | + |
| 26 | +To add a new render: |
| 27 | + |
| 28 | +1. Create a directory with the platform name in `app/translator/platforms/`. |
| 29 | +2. Describe the metainformation about the platform in the `const.py` file. |
| 30 | +3. Create a class that processes mappings in the `mapping.py` file. |
| 31 | +4. Create a class that processes special characters in the `escaping_manager.py` file. |
| 32 | +5. Create the `renders` directory in `translator/app/translator/platforms/<platform_name>/`. |
| 33 | +6. Create a file with the name that matches the name of the platform. |
| 34 | +7. The render is composed of two classes: |
| 35 | + a. `BaseQueryRender` – the class that describes the general mechanism of rendering a query from the tokens parsed from the input query. |
| 36 | + b. `BaseQueryFieldValue` – the class that describes the mechanism of creating the `Field-Value` component of the query. |
| 37 | + |
| 38 | + |
| 39 | +## Render Classes |
| 40 | +These classes should be described in the `translator/app/translator/platforms/<platform_name>/renders/<platform_name>.py` file. |
| 41 | + |
| 42 | +### BaseQueryRender Class |
| 43 | + |
| 44 | +The class has the following attributes: |
| 45 | +- `mappings` – a class responsinble for working with mapping of fields and tables/indexes |
| 46 | +- `details` – the metainformation about the platform (described in the `const.py` file) |
| 47 | +- `is_strict_mapping` – a boolean flag that defines if the render's mapping is strict. When set to `True`, the render returns an error if a field has no mapping |
| 48 | +- `platform_functions` – a class responsible for parsing and rendering functions |
| 49 | +- `or_token/and_token/not_token` – corresponding platform operators that should be used when generating the target query |
| 50 | +- `field_value_map` – a class that creates `Field-Value` |
| 51 | +- `query_pattern` – the template of the source query |
| 52 | +- `comment_symbol` – escaping character (metainformation provided for a better context is passed to the output together with the query so it should be commented). If this character allows commenting multiple lines, set the flag `is_multi_line_comment == True` |
| 53 | + |
| 54 | +The class has the following methods: |
| 55 | +- The entry point into the process of query rendering is the `generate` method. Query generation process is started for all mappings that match the input query: |
| 56 | + - `generate_prefix` method – a table or an index is generated (depending on the mapping) |
| 57 | + - `generate_query` method – the query's body is generated. The `generate_query` method goes through each token parsed from the source query, and using the `BaseQueryFieldValue` class transforms the `FieldValue` token into a string value that conforms to the rules and standards of the target platform |
| 58 | + - `finalize_query` method – the output query is generated based on `query_pattern` with the metainformation added |
| 59 | +- The process ends with the `finalize` method validating the translation output and joining the queries that are identical (that is they match multiple log sources) |
| 60 | + |
| 61 | + |
| 62 | +### BaseQueryFieldValue Class |
| 63 | + |
| 64 | +The class has the following attributes: |
| 65 | +- `details` – the metainformation about the platform (described in the `const.py` file) |
| 66 | +- `escape_manager`– a class responsible for processing and escaping special characters |
| 67 | + |
| 68 | +The class has the following methods: |
| 69 | +- `__init__` creates a dictionary (map) named `field_value` where a processing method is connected that depends on the operator that was between the field and its value |
| 70 | + |
| 71 | +## Mapping Classes |
| 72 | +These classes should be described in the `translator/app/translator/platforms/<platform_name>/mapping.py` file. |
| 73 | + |
| 74 | +To describe mappings, you need two classes: |
| 75 | +- A class that inherits the `BasePlatformMappings` class – responsible for choosing mapping |
| 76 | +- A class that inherits the `LogSourceSignature` class – describes the mapping structure. |
| 77 | +It's also important to invoke and initialize a class created by inheritance from `BasePlatformMappings` because later it should be connected to the render. |
| 78 | + |
| 79 | +### LogSourceSignature |
| 80 | +A class that describes the mapping structure. |
| 81 | + |
| 82 | +The `__init__` method describes tabels/indexes that can be applied for a log source. Also there's an important but optional field `_default_source`, a dictionary that contains the table/index values that can be used for a certain log source at the time of rendering. |
| 83 | + |
| 84 | +The `is_suitable` method is required. It's used to determine the mapping. |
| 85 | + |
| 86 | +### BasePlatformMappings |
| 87 | +This class has one required attribute – the name of the directory from which mappings should be taken (all mappings are in `translator/app/translator/mappings/<platform_name>`). Only the directory name should be indicated. |
| 88 | + |
| 89 | +This class contains two required methods: |
| 90 | +- `prepare_log_source_signature` – a method that transforms mappings obtained from the YAML file into objects |
| 91 | +- `get_suitable_source_mappings` – a method that contains the conditions for checking for a suitable mapping depending on fields and tables/indexes. |
| 92 | + |
| 93 | +## Escape Manager Class |
| 94 | +This class inherits the basic class `EscapeManager`. It contains a required attribute `escape_map`. Depending on the `Value` type (the values searched for in the field) you need to define special characters to be escaped. `Value` types are defined in `translator/app/translator/core/custom_types/values.py`. |
| 95 | + |
| 96 | +## const.py |
| 97 | +The file where the metainformation about the platform and the rule templates (if any) are stored. |
| 98 | + |
| 99 | +## Metainformation |
| 100 | +`siem_type` – unique platform identifier |
| 101 | +`group_name` – platform name to be displayed in the platform selection dropdown in the UI |
| 102 | +`platform_name` – the name of the content type to be displayed on the tab (as well as in the sub-menu of the platform) |
| 103 | +`group_id` – the unique identifier of all content types for a platform |
0 commit comments