> For the complete documentation index, see [llms.txt](https://docs.freelabz.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.freelabz.com/in-depth/concepts/output-types.md).

# Output types

... or how secator unifies all output into common schemas.

`secator` uses the notion of output types to uniformize tasks output. A task can output one or multiple output types.

The currently available output types are [#certificate](#certificate "mention"), [#domain](#domain "mention"), [#exploit](#exploit "mention"), [#ip](#ip "mention"), [#port](#port "mention"), [#record](#record "mention"), [#subdomain](#subdomain "mention"), [#tag](#tag "mention"), [#technology](#technology "mention"), [#url](#url "mention"), [#useraccount](#useraccount "mention"), [#vulnerability](#vulnerability "mention").

{% hint style="info" %}
Feel free to request more output types by [opening an issue](https://github.com/freelabz/secator/issues/new/choose) on the GitHub repo.
{% endhint %}

***

## 📜 Certificate

{% code title="secator/output\_types/certificate.py" %}

```python
@dataclass
class Certificate(OutputType):
    host: str
    fingerprint_sha256: str = field(default='')
    ip: str = field(default='', compare=False)
    raw_value: str = field(default='', compare=False)
    subject_cn: str = field(default='', compare=False)
    subject_an: list[str] = field(default_factory=list, compare=False)
    not_before: datetime = field(default=None, compare=False)
    not_after: datetime = field(default=None, compare=False)
    issuer_dn: str = field(default='', compare=False)
    issuer_cn: str = field(default='', compare=False)
    issuer: str = field(default='', compare=False)
    self_signed: bool = field(default=True, compare=False)
    trusted: bool = field(default=False, compare=False)
    status: str = field(default=CERTIFICATE_STATUS_UNKNOWN, compare=False)
    keysize: int = field(default=None, compare=False)
    serial_number: str = field(default='', compare=False)
    ciphers: list[str] = field(default_factory=list, compare=False)
```

{% endcode %}

***

## 🪪 Domain

{% code title="secator/output\_types/domain.py" %}

```python
@dataclass
class Domain(OutputType):
    domain: str
    alive: bool = False
    creation_date: datetime = field(default=None, compare=False)
    expiration_date: datetime = field(default=None, compare=False)
    updated_date: datetime = field(default=None, compare=False)
    status: list = field(default_factory=list, compare=False)
    registrar: str = field(default='', compare=False)
    registrar_info: dict = field(default_factory=dict, compare=False)
    registrant: str = field(default='', compare=False)
    registrant_info: dict = field(default_factory=dict, compare=False)
    administrative_info: dict = field(default_factory=dict, compare=False)
    technical_info: dict = field(default_factory=dict, compare=False)
    extra_data: dict = field(default_factory=dict, compare=False)
    is_false_positive: bool = field(default=False, compare=False)
    is_acknowledged: bool = field(default=False, compare=False)
    tags: list = field(default_factory=list, compare=False)
```

{% endcode %}

***

## ⍼ Exploit

{% code title="secator/output\_types/exploit.py" %}

```python
@dataclass
class Exploit(OutputType):
    name: str
    provider: str
    id: str
    matched_at: str = ''
    ip: str = ''
    confidence: str = 'low'
    reference: str = field(default='', repr=True, compare=False)
    cves: list = field(default_factory=list, compare=False)
    tags: list = field(default_factory=list, compare=False)
    extra_data: dict = field(default_factory=dict, compare=False)
    is_false_positive: bool = field(default=False, compare=False)
    is_acknowledged: bool = field(default=False, compare=False)
```

{% endcode %}

***

## 💻 Ip

{% code title="secator/output\_types/ip.py" %}

```python
@dataclass
class Ip(OutputType):
    ip: str
    host: str = field(default='', repr=True, compare=False)
    alive: bool = False
    protocol: str = field(default=IpProtocol.IPv4)
    extra_data: dict = field(default_factory=dict, compare=False)
    is_false_positive: bool = field(default=False, compare=False)
    is_acknowledged: bool = field(default=False, compare=False)
    tags: list = field(default_factory=list, compare=False)
```

{% endcode %}

***

## 🔓 Port

{% code title="secator/output\_types/port.py" %}

```python
@dataclass
class Port(OutputType):
    port: int
    ip: str
    state: str = 'UNKNOWN'
    service_name: str = field(default='', compare=False)
    cpes: list = field(default_factory=list, compare=False)
    host: str = field(default='', repr=True, compare=False)
    protocol: str = field(default='tcp', repr=True, compare=False)
    extra_data: dict = field(default_factory=dict, compare=False)
    confidence: str = field(default='low', repr=False, compare=False)
    service_confidence: str = field(default='low', repr=False, compare=False)
    is_false_positive: bool = field(default=False, compare=False)
    is_acknowledged: bool = field(default=False, compare=False)
    tags: list = field(default_factory=list, compare=False)
```

{% endcode %}

***

## 🎤 Record

{% code title="secator/output\_types/record.py" %}

```python
@dataclass
class Record(OutputType):
    name: str
    type: str
    host: str = ''
    extra_data: dict = field(default_factory=dict, compare=False)
    is_false_positive: bool = field(default=False, compare=False)
    is_acknowledged: bool = field(default=False, compare=False)
    tags: list = field(default_factory=list, compare=False)
```

{% endcode %}

***

## 🏰 Subdomain

{% code title="secator/output\_types/subdomain.py" %}

```python
@dataclass
class Subdomain(OutputType):
    host: str
    domain: str
    verified: bool = field(default=False, compare=False)
    sources: List[str] = field(default_factory=list, compare=False)
    extra_data: dict = field(default_factory=dict, compare=False)
    is_false_positive: bool = field(default=False, compare=False)
    is_acknowledged: bool = field(default=False, compare=False)
    tags: list = field(default_factory=list, compare=False)
```

{% endcode %}

***

## 🏷️ Tag

{% code title="secator/output\_types/tag.py" %}

```python
@dataclass
class Tag(OutputType):
    name: str
    value: str
    match: str
    category: str = field(default='general')
    extra_data: dict = field(default_factory=dict, repr=True, compare=False)
    stored_response_path: str = field(default='', compare=False)
    is_false_positive: bool = field(default=False, compare=False)
    is_acknowledged: bool = field(default=False, compare=False)
    tags: list = field(default_factory=list, compare=False)
```

{% endcode %}

***

## 📦 Technology

{% code title="secator/output\_types/technology.py" %}

```python
@dataclass
class Technology(OutputType):
    product: str
    match: str
    version: str = None
    extra_data: dict = field(default_factory=dict, repr=True, compare=False)
    tags: list = field(default_factory=list, compare=False)
```

{% endcode %}

***

## 🔗 Url

{% code title="secator/output\_types/url.py" %}

```python
@dataclass
class Url(OutputType):
    url: str
    host: str = field(default='', compare=False)
    verified: bool = field(default=False, compare=False)
    status_code: int = field(default=0, compare=False)
    title: str = field(default='', compare=False)
    protocol: str = field(default='', compare=False)
    webserver: str = field(default='', compare=False)
    tech: list = field(default_factory=list, compare=False)
    content_type: str = field(default='', compare=False)
    content_length: int = field(default=0, compare=False)
    time: str = field(default='', compare=False)
    method: str = field(default='', compare=False)
    words: int = field(default=0, compare=False)
    lines: int = field(default=0, compare=False)
    screenshot_path: str = field(default='', compare=False)
    stored_response_path: str = field(default='', compare=False)
    confidence: str = field(default='high', compare=False)
    response_headers: dict = field(default_factory=dict, repr=True, compare=False)
    request_headers: dict = field(default_factory=dict, repr=True, compare=False)
    extra_data: dict = field(default_factory=dict, compare=False)
    is_directory: bool = field(default=False, compare=False)
    is_root: bool = field(default=False, compare=False)
    is_redirect: bool = field(default=False, compare=False)
    is_false_positive: bool = field(default=False, compare=False)
    is_acknowledged: bool = field(default=False, compare=False)
    tags: list = field(default_factory=list, compare=False)
```

{% endcode %}

***

## 👤 UserAccount

{% code title="secator/output\_types/user\_account.py" %}

```python
@dataclass
class UserAccount(OutputType):
    username: str
    url: str = ''
    email: str = ''
    site_name: str = ''
    extra_data: dict = field(default_factory=dict, compare=False)
    is_false_positive: bool = field(default=False, compare=False)
    is_acknowledged: bool = field(default=False, compare=False)
    tags: list = field(default_factory=list, compare=False)
```

{% endcode %}

***

## 🚨 Vulnerability

{% code title="secator/output\_types/vulnerability.py" %}

```python
@dataclass
class Vulnerability(OutputType):
    name: str
    id: str = ''
    matched_at: str = ''
    provider: str = field(default='', compare=False)
    ip: str = field(default='', compare=False)
    confidence: str = field(default='low', compare=False)
    severity: str = field(default='unknown', compare=False)
    cvss_score: float = field(default=0.0, compare=False)
    cvss_vec: str = field(default='', compare=False)
    epss_score: float = field(default=0.0, compare=False)
    description: str = field(default='', compare=False)
    remediation: str = field(default='', compare=False)
    impact: str = field(default='', compare=False)
    poc: str = field(default='', compare=False)
    references: List[str] = field(default_factory=list, compare=False)
    reference: str = field(default='', compare=False)
    confidence_nb: int = field(default=0, compare=False)
    severity_nb: int = field(default=0, compare=False)
    extra_data: dict = field(default_factory=dict, compare=False)
    verified: bool = field(default=False, compare=False)
    is_false_positive: bool = field(default=False, compare=False)
    is_acknowledged: bool = field(default=False, compare=False)
    status: str = field(default='', compare=False)
    tags: list = field(default_factory=list, compare=False)
```

{% endcode %}

Notable fields:

* `severity_nb` / `confidence_nb`: numeric severity and confidence, handy for queries (`0` = critical, `1` = high, ...), e.g. `secator q "vulnerability.severity_nb < 2"`.
* `cvss_vec`, `epss_score`: CVSS vector and EPSS score, when the provider returns them.
* `description`, `impact`, `remediation`, `poc`: free-text details and proof-of-concept.
* `status`: triage status of the vulnerability. With the `mongodb` and `sqlite` drivers, it is carried over to the same vulnerability found again in later runs of the workspace, together with `is_false_positive`, `is_acknowledged`, `verified`, `tags` and `poc`.
* `tags`: vulnerabilities whose CVE is in the [CISA Known Exploited Vulnerabilities](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) catalog are tagged `kev` automatically (a bundled copy of the catalog is used when offline), e.g. `secator q "vulnerability.tags ~= 'kev'"`.

***
