Aller au contenu principal

Findings

Les findings sont des éléments d'information rattachés à un projet et à une ressource, comme un domaine, un hôte ou un port. Ils sont créés à l'aide de la trousse de développement logiciel (SDK) de Red Kite.

Les findings prennent différentes formes. Certains créent de nouvelles ressources, d'autres ajoutent simplement des données à des ressources existantes.

Pour produire un finding, la tâche (job) doit créer un objet contenant l'information nécessaire et le sérialiser en JSON.

L'objet du finding doit contenir le champ type. Voici la liste des types par défaut fournis avec les tâches par défaut.

TypeDescription
HostnameFindingCrée un nouveau domaine.
IpFindingCrée un nouvel hôte.
IpRangeFindingCrée une nouvelle plage d'adresses IP.
HostnameIpFindingCrée un nouvel hôte et le rattache à un domaine donné.
PortFindingCrée un nouveau port et le rattache à l'hôte donné.
WebsiteFindingCrée un nouveau site web, avec l'hôte, le domaine et le port appropriés.
CustomFindingRattache des données de finding personnalisées à une entité donnée.
PortServiceFindingRemplit le champ service d'un port.
WebsitePathFindingAjoute un point de terminaison au plan du site d'un site web.
TagFindingAjoute une étiquette à une ressource.
WebsiteScreenshotFindingUne capture d'écran du rendu d'un site web.
AmassDomainReportFindingUn rapport sur les relations d'un domaine.
AmassHostReportFindingUn rapport sur les relations d'un hôte.
RirOrgFindingL'organisation responsable de la gestion d'une adresse IP.

HostnameFinding​

Un HostnameFinding est un nom d'hôte trouvé pour un projet. Ici, « nom d'hôte » désigne un nom de domaine pleinement qualifié, ou FQDN. Un finding de nom d'hôte crée ou met à jour un domaine.

ChampTypeDescription
domainNamestringLe nom de domaine trouvé

Exemple :

{
"type": "HostnameFinding",
"key": "HostnameFinding",
"domainName": "red-kite.io"
}

Avec le SDK Python, vous pouvez émettre ce finding avec le code suivant :

from stalker_job_sdk import DomainFinding, log_finding
hostname = "example.com"
log_finding(
DomainFinding(
"HostnameFinding", hostname, None, "New domain", [], "HostnameFinding"
)
)

Rattacher de l'information à un domaine​

En ajoutant des champs et en utilisant un type de finding personnalisé, vous ajoutez un finding à la ressource de domaine.

from stalker_job_sdk import DomainFinding, log_finding, TextField

hostname = "example.com"
log_finding(
DomainFinding(
"MyCustomHostnameFinding", hostname, None, "Domain info", [
TextField("myfield", "Field Title", "Finding data")
]
)
)

IpFinding​

Un finding d'adresse IP crée un nouvel hôte. Les adresses IP sont au format IPv4.

ChampTypeDescription
ipstringL'adresse IPv4 pour laquelle créer un hôte

Exemple :

{
"type": "IpFinding",
"key": "IpFinding",
"ip": "0.0.0.0"
}

Avec le SDK Python, vous pouvez émettre ce finding avec le code suivant :

from stalker_job_sdk import IpFinding, log_finding
ip = "0.0.0.0"
log_finding(
IpFinding(
"IpFinding", ip, "New ip", [], "IpFinding"
)
)

Rattacher de l'information à un hôte​

En ajoutant des champs et en utilisant un type de finding personnalisé, vous ajoutez un finding à la ressource d'hôte.

from stalker_job_sdk import IpFinding, log_finding, TextField
ip = "0.0.0.0"
mask = 16
log_finding(
IpFinding(
"MyCustomIpFinding", ip, "New Info", [
TextField("myfield", "Field Title", "Finding data")
]
)
)

IpRangeFinding​

Un finding de plage d'adresses IP crée une nouvelle plage IP pour un projet. Les adresses IP sont au format IPv4. Les IpRangeFindings peuvent aussi servir à rattacher de l'information à une ressource de plage IP.

ChampTypeDescription
ipstringL'adresse IPv4 pour laquelle créer un hôte
masknumberUn entier entre 0 et 32, inclusivement. Il représente un masque de réseau en notation courte, comme /24.

Exemple :

{
"type": "IpRangeFinding",
"key": "IpRangeFinding",
"ip": "0.0.0.0",
"mask": 16
}

Avec le SDK Python, vous pouvez émettre ce finding avec le code suivant :

from stalker_job_sdk import IpRangeFinding, log_finding
ip = "0.0.0.0"
mask = 16
log_finding(
IpRangeFinding(
'IpRangeFinding', ip, mask, None, [], "IpRangeFinding"
)
)

Rattacher de l'information à une plage d'adresses IP​

En ajoutant des champs et en utilisant un type de finding personnalisé, vous ajoutez un finding à la ressource de plage IP.

from stalker_job_sdk import IpRangeFinding, log_finding, TextField
ip = "0.0.0.0"
mask = 16
log_finding(
IpRangeFinding(
'IpRangeFinding', ip, mask, "Finding title", [
TextField("myfield", "Field Title", "Finding data")
]
)
)

HostnameIpFinding​

Le HostnameIpFinding est généralement le résultat de la résolution d'un nom d'hôte en adresse IP. Le nom d'hôte, domainName, doit se résoudre vers l'adresse IP et doit déjà être connu de Red Kite comme domaine valide. Le finding crée ou met à jour un hôte et le rattache au domaine existant donné.

ChampDescription
domainNameLe domaine auquel rattacher le nouvel hôte
ipL'adresse IPv4

Exemple :

{
"type": "HostnameIpFinding",
"key": "HostnameIpFinding",
"domainName": "red-kite.io",
"ip": "0.0.0.0"
}

Avec le SDK Python, vous pouvez émettre ce finding avec le code suivant :

from stalker_job_sdk import DomainFinding, log_finding
hostname = "example.com"
ip = "0.0.0.0"
log_finding(
DomainFinding(
"HostnameIpFinding", hostname, ip, "New ip", [], "HostnameIpFinding"
)
)

PortFinding​

Le PortFinding est généralement le résultat d'une tâche d'analyse de ports. Il signale qu'un port ouvert, tcp ou udp, a été trouvé sur l'hôte précisé par la valeur ip. L'ip doit déjà être connue de Red Kite comme hôte valide. Un finding de port crée ou met à jour un port et le rattache à l'hôte donné.

ChampDescription
protocolLe protocole, soit 'tcp', soit 'udp'
ipL'adresse IP
portLe numéro de port

Exemple :

{
"type": "PortFinding",
"key": "PortFinding",
"protocol": "tcp",
"ip": "1.2.3.4",
"port": 80
}

Avec le SDK Python, vous pouvez émettre ce finding avec le code suivant :

from stalker_job_sdk import PortFinding, log_finding, TextField
port = 80
ip = "1.2.3.4"
log_finding(
PortFinding(
"PortFinding",
ip,
port,
"tcp",
"New port",
[TextField("protocol", "This is a TCP port", "tcp")],
"PortFinding",
)
)

Rattacher de l'information à un port​

En ajoutant des champs et en utilisant un type de finding personnalisé, vous ajoutez un finding à la ressource de port.

from stalker_job_sdk import PortFinding, log_finding, TextField
port = 80
ip = "1.2.3.4"
log_finding(
PortFinding(
"MyCustomPortFinding",
ip,
port,
"tcp",
"New port data",
[
TextField("protocol", "This is a TCP port", "tcp"),
TextField("myfield", "Field Title", "Finding data")
],
)
)

WebsiteFinding​

Le WebsiteFinding crée une ressource de site web. Un site web est défini par 4 caractéristiques : une adresse IP, un nom de domaine, un numéro de port et un chemin. Seuls l'adresse IP et le port sont obligatoires. Le domaine peut être vide et le chemin vaut / par défaut.

Pour créer un site web, le finding doit faire référence à un port existant d'un projet. Pour faire aussi référence à un domaine, ce domaine doit déjà être connu de Red Kite.

Il signale qu'un port ouvert exécutant un service http(s), tcp ou udp, a été trouvé sur l'hôte précisé par la valeur ip. L'ip doit déjà être connue de Red Kite comme hôte valide. Un finding de port crée ou met à jour un port et le rattache à l'hôte donné.

Émettre un PortServiceFinding avec un serviceName http ou https crée un WebsiteFinding pour chaque domaine lié à l'hôte, plus un avec un domaine vide. En savoir plus sur PortServiceFinding et les sites web

ChampDescription
ipL'adresse IP
portLe numéro de port
domainNameLe domaine sur lequel le site web est hébergé; peut être vide
pathLe chemin du dossier, / par défaut
sslVrai si le site web est protégé par chiffrement

Exemple :

{
"type": "WebsiteFinding",
"key": "WebsiteFinding",
"ip": "1.2.3.4",
"port": 80,
"domainName": "example.com",
"path": "/",
"ssl": false
}

Avec le SDK Python, vous pouvez émettre ce finding avec le code suivant :

from stalker_job_sdk import WebsiteFinding, log_finding
port = 80
ip = "1.2.3.4"
domain = "example.com"
path = "/"
ssl = False

log_finding(
WebsiteFinding(
"WebsiteFinding",
ip,
port,
domain,
path,
ssl,
"New website",
[],
"WebsiteFinding",
)
)

Rattacher de l'information à un site web​

En ajoutant des champs et en utilisant un type de finding personnalisé, vous ajoutez un finding à la ressource de site web.

from stalker_job_sdk import WebsiteFinding, log_finding, TextField
port = 80
ip = "1.2.3.4"
domain = "example.com"
path = "/"
ssl = False

log_finding(
WebsiteFinding(
"MyCustomWebsiteFinding",
ip,
port,
domain,
path,
ssl,
"New website data",
[
TextField("myfield", "Field Title", "Finding data")
],
)
)

CustomFinding​

Les findings personnalisés rattachent de l'information sous forme de champs à une ressource. Il existe des findings personnalisés pour chaque type de ressource. Lorsque vous ne précisez pas le type de finding que vous journalisez, vous créez un finding personnalisé pour le type de ressource associé.

Classe de finding du SDKRessources
HostnameFindingDomaines
IpFindingHôtes
IpRangeFindingPlages IP
PortFindingPorts
WebsiteFindingSites web

Voici un exemple de finding personnalisé pour un port avec le SDK Python. Dans cet exemple, le port affichera l'information personnalisée This port runs an HTTP server, avec un champ texte rattaché :

from stalker_job_sdk import PortFinding, log_finding, TextField
port = 80
ip = "0.0.0.0"
log_finding(
PortFinding(
"PortFunFact", ip, port, "tcp", "This is a fun fact about a port", [
TextField('myfieldkey', 'My field title', 'My field data')
]
)
)

Remarquez que la clé PortFunFact peut être n'importe quoi, que l'information est fournie au moyen de TextField, et que le type de finding n'est pas fourni afin d'utiliser la valeur par défaut.

À titre de comparaison, voici comment créer un port avec la classe PortFinding, qui n'est pas utilisée ici comme finding personnalisé. Vous verrez que la clé est PortFinding, qu'aucun champ n'est fourni et que le type est également PortFinding :

from stalker_job_sdk import PortFinding, log_finding
port = 80
ip = "0.0.0.0"
log_finding(
PortFinding(
"PortFinding", ip, port, "tcp", None, None, "PortFinding"
)
)

Champs dynamiques​

Les champs dynamiques donnent de la flexibilité aux tâches pour produire des données complexes. Voici la liste des champs dynamiques pris en charge.

ChampDescription
TextUne étiquette avec du texte
ImageUne image

Chaque champ comprend au minimum une key, un type et des data. Le type est généralement rempli automatiquement par le SDK. La key s'utilise comme un nom de variable, et data doit contenir les valeurs intéressantes extraites par la tâche.

Le champ key peut servir à injecter le contenu de data comme entrée d'une nouvelle tâche dans un abonnement sur événement.

Champ texte​

Créer un TextField avec le SDK Python :

key = 'topthreekeywords'
label = 'Top 3 keywords found in web page'
data = 'Potato, celery, transformers'
field = TextField(key, label, data)

Le résultat est un JSON semblable à celui-ci :

{
"key": "topthreekeywords",
"type": "text",
"label": "Top 3 keywords found in web page",
"data": "Potato, celery, transformers"
}

Champ image​

Créer un ImageField avec le SDK Python :

key = 'myImageField'
image_data = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII'
field = ImageField(key, image_data)

Le résultat est un JSON semblable à celui-ci :

{
"key": "myImageField",
"type": "image",
"data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}

PortServiceFinding​

Un PortServiceFinding est un type de CustomFinding qui remplit le champ service d'un port dans la base de données avec la valeur du champ texte serviceName. Cette valeur s'affiche ensuite dans l'interface, sous le champ Service.

ChampDescription
protocolLe protocole, soit 'tcp', soit 'udp'
ipL'adresse IP
portLe numéro de port
fieldsUne liste de champs. Doit inclure serviceName.

Avec le SDK Python, vous pouvez émettre ce finding avec le code suivant.

from stalker_job_sdk import PortFinding, log_finding, TextField

ip = '0.0.0.0'
port = 22
protocol = 'tcp'
service_name = 'ssh'

fields = [
TextField("serviceName", "Service name", service_name)
]

log_finding(
PortFinding(
"PortServiceFinding", ip, port, protocol, f"Found service {service_name}", fields
)
)

À la réception de ce finding, le backend définit le champ service du port TCP 22 de l'adresse IP 0.0.0.0 à ssh.

PortServiceFinding et les sites web​

Lorsqu'un PortServiceFinding est publié avec le nom de service http ou https, la plateforme comprend qu'un site web se trouve sur ce port.

La plateforme crée et publie donc plusieurs WebsiteFinding : un pour chaque nom de domaine lié à l'hôte, et un pour l'adresse IP seule.

Ces findings de site web permettent d'examiner plus en profondeur le port http(s) avec les différents noms de domaine, au cas où le port prendrait en charge plusieurs hôtes virtuels.

Par exemple, imaginez un hôte avec l'adresse IP 1.2.3.4. Cet hôte est lié aux domaines example.com et dev.example.com.

Puis, avec le code suivant, qui publie les résultats pour un port https :

from stalker_job_sdk import PortFinding, log_finding, TextField

ip = '1.2.3.4'
port = 443
protocol = 'tcp'
service_name = 'https'

fields = [
TextField("serviceName", "Service name", service_name)
]

log_finding(
PortFinding(
"PortServiceFinding", ip, port, protocol, f"Found service {service_name}", fields
)
)

Les trois sites web suivants seraient créés :

domainehôteportchemin
S. O.1.2.3.4443/
example.com1.2.3.4443/
dev.example.com1.2.3.4443/

Ainsi, un site web à dev.example.com, qui peut être différent de celui à example.com, sera trouvé. Il en va de même pour le site web accessible directement par l'adresse IP.

WebsitePathFinding​

Un WebsitePathFinding est un type de CustomFinding qui remplit le champ paths d'un site web dans la base de données avec la valeur du champ texte endpoint. Cette valeur s'affiche ensuite dans l'interface comme plan du site web.

ChampDescription
domainNameLe domaine du site web
ipL'adresse IP du site web
portLe numéro de port du site web
pathLe chemin du site web
fieldsUne liste de champs. Doit inclure endpoint.

Avec le SDK Python, vous pouvez émettre ce finding avec le code suivant.

from stalker_job_sdk import WebsiteFinding, log_finding, TextField

ip = '1.2.3.4'
domain = 'example.com'
port = 443
path = '/'
ssl = True
endpoint = '/example/endpoint.html'

fields = [
TextField("endpoint", "Endpoint", endpoint)
]

log_finding(
WebsiteFinding(
"WebsitePathFinding", ip, port, domain, path, ssl, f"Website path", fields
)
)

À la réception de ce finding, le backend ajoute la donnée endpoint aux chemins du site web concerné.

WebsiteScreenshotFinding​

Un WebsiteScreenshotFinding est un type de CustomFinding qui doit contenir un ImageField nommé image. Cette image est considérée comme la page d'accueil du site web et s'affiche dans les différentes vues du site web.

ChampDescription
domainNameLe domaine du site web
ipL'adresse IP du site web
portLe numéro de port du site web
pathLe chemin du site web
fieldsUne liste de champs. Doit inclure image.

Avec le SDK Python, vous pouvez émettre ce finding avec le code suivant.

from stalker_job_sdk import WebsiteFinding, log_finding, ImageField, TextField
from base64 import b64encode

ip = '1.2.3.4'
domain = 'example.com'
port = 443
path = '/'
ssl = True
data = b64encode(image_bytes).decode('utf-8')
image_data =
endpoint = '/example/endpoint.html'

fields = [
TextField("endpoint", "Endpoint", endpoint),
ImageField("image", f"data:image/png;base64,{data}")
]

log_finding(
WebsiteFinding(
"WebsiteScreenshotFinding", ip, port, domain or '', path, ssl, "Website screenshot", fields
)
)

TagFinding​

Un TagFinding est un finding qui ajoute une étiquette existante à une ressource existante. La ressource et l'étiquette doivent déjà exister.

ChampDescription
tagLe nom de l'étiquette
ip(facultatif) L'adresse IP de la ressource.
port(facultatif) Le numéro de port de la ressource.
protocol(facultatif) Le protocole du port de la ressource.
domainName(facultatif) Le domaine de la ressource.
path(facultatif) Le chemin de la ressource.

Avec le SDK Python, vous pouvez émettre ce finding pour un site web avec le code suivant.

from stalker_job_sdk import log_finding, TagFinding

ip = '1.2.3.4'
domain = 'example.com'
port = 443
path = '/'
protocol='tcp'

log_finding(
TagFinding(
"Login", ip=ip, port=port, domainName=domain, path=path, protocol=protocol
)
)

À la réception de ce finding, le backend ajoute l'étiquette à la ressource trouvée. La ressource est identifiée à l'aide des valeurs fournies. Les combinaisons valides sont :

Combinaison valideType de ressource
domainDomaine
ipHôte
ip, port, protocolPort
(domain), ip, port, protocol, pathSite web

AmassDomainReportFinding​

Rattache un rapport sur les relations d'un domaine à une ressource de domaine.

Voici un exemple d'émission avec le SDK Python.

from stalker_job_sdk import log_finding, DomainFinding, TextField

domain = "example.com"
content = "report content"
fields = [TextField("report", "Report", content)]
title = "Domain Relationship Report"

log_finding(
DomainFinding(
"AmassDomainReportFinding", domain, None, title, fields
)
)
ChampDescription
domainNameLe nom de domaine
fieldsUne liste de champs.

Tous les champs ont la clé report et contiennent du texte qui renseigne les utilisateurs sur les relations de la ressource.

AmassHostReportFinding​

Rattache un rapport sur les relations d'un hôte à une ressource d'hôte.

Voici un exemple d'émission avec le SDK Python.

from stalker_job_sdk import log_finding, IpFinding, TextField

ip = "1.1.1.1"
content = "report content"
fields = [TextField("report", "Report", content)]
title = "Host Relationship Report"

log_finding(
IpFinding(
"AmassHostReportFinding", ip, title, fields
)
)
ChampDescription
ipL'adresse IP de l'hôte
fieldsUne liste de champs.

Tous les champs ont la clé report et contiennent du texte qui renseigne les utilisateurs sur les relations de la ressource.

RirOrgFinding​

L'organisation responsable de la gestion d'une adresse IP, déterminée à partir de l'ASN.

Voici un exemple d'émission avec le SDK Python.

from stalker_job_sdk import log_finding, IpFinding, TextField

fields = [TextField("name", "Name", org_info)]
ip = "1.1.1.1"
title = "Regional Internet registry organization"

log_finding(
IpFinding(
"RirOrgFinding", ip, title, fields
)
)
ChampDescription
ipL'adresse IP de l'hôte
fieldsUne liste de champs.

Tous les champs ont la clé name et contiennent le nom de l'organisation responsable de la gestion de l'adresse IP.