Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add project discovery Nuclei boefje #518

Merged
merged 12 commits into from
Mar 30, 2023
Empty file.
15 changes: 15 additions & 0 deletions boefjes/boefjes/plugins/kat_nuclei/boefje.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"id": "nuclei",
"name": "Nuclei-scan",
"description": "Nuclei is used to send requests across targets based on a template, providing fast scanning.",
"consumes": [
"Hostname",
"HostnameHTTPURL"
],
"produces": [
"Finding",
"CVEFindinsgType"
],
"environment_keys": [],
"scan_level": 3
}
Binary file added boefjes/boefjes/plugins/kat_nuclei/cover.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions boefjes/boefjes/plugins/kat_nuclei/description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Nuclei - Project discovery

Nuclei is used to send requests across targets based on a template, leading to zero false positives
and providing fast scanning on a large number of hosts. Nuclei offers scanning for a variety of protocols,
including TCP, DNS, HTTP, SSL, File, Whois, Websocket, Headless etc. With powerful and flexible templating,
Nuclei can be used to model all kinds of security checks.

Integrated in this Boefje are only the CVE templates for performance reasons.

[More information about Nucelei](https://github.com/projectdiscovery/nuclei)

### Input OOIs

Nuclei expects a Hostname object of a website as input. The scan will then use the [CVE directory](https://github.com/projectdiscovery/nuclei-templates/tree/main/cves)
to scan for known CVE's

this is handled by the following parameter in the "main.py" file

```
"-t", "/root/nuclei-templates/cves/"
```

### Output OOIs

Nuclei outputs the following OOIs:

|OOI type|Description|
|---|---|
|CveFindingType|Returns CVE's found on the target hostnames|
|Finding|Finding|
31 changes: 31 additions & 0 deletions boefjes/boefjes/plugins/kat_nuclei/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import Tuple, Union, List
import docker
from boefjes.job_models import BoefjeMeta


NUCLEI_IMAGE = "projectdiscovery/nuclei:latest"


def verify_hostname_meta(input):
# if the input object is HostnameHTTPURL then the hostname is located in netloc
if "netloc" in input and "name" in input["netloc"]:
netloc_name = input["netloc"]["name"]
port = input.get("port")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also return a None, which makes the formatted string look like <hostname>:None. It can be avoided by giving a default port, e.g. port = input.get("port", 80)

But since the port property is required and therefore guaranteed to exist, you can simply access that element directly: port = input["port"]

Suggested change
port = input.get("port")
port = input["port"]

Copy link
Contributor Author

@RiieCco RiieCco Mar 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ammar92 Woeps i am not sure what i just did exactly haha, sorry about that!

return f"{netloc_name}:{port}"
else:
# otherwise the Hostname input object is used
return input["name"]


def run(boefje_meta: BoefjeMeta) -> List[Tuple[set, Union[bytes, str]]]:
client = docker.from_env()

# Checks if the url is of object HostnameHTTPURL or Hostname
url = verify_hostname_meta(boefje_meta.arguments["input"])
output = client.containers.run(
NUCLEI_IMAGE,
["-t", "/root/nuclei-templates/cves/", "-u", url, "-json"],
remove=True,
)

return [(set(), output)]
31 changes: 31 additions & 0 deletions boefjes/boefjes/plugins/kat_nuclei/normalize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import json
from typing import Union, Iterator

from octopoes.models import OOI, Reference
from octopoes.models.ooi.findings import Finding, CVEFindingType

from boefjes.job_models import NormalizerMeta


def run(normalizer_meta: NormalizerMeta, raw: Union[bytes, str]) -> Iterator[OOI]:
url_reference = Reference.from_str(normalizer_meta.raw_data.boefje_meta.input_ooi)
if raw:
for line in raw.splitlines():
# Extract and parse values
data = json.loads(line)
id_ = data["info"]["classification"]["cve-id"][0]
description = data["info"]["description"]
curl_command = data["curl-command"]

# Create instances of CVEFindingType and Finding classes
cve_finding_type = CVEFindingType(id=id_)
yield cve_finding_type

finding = Finding(
finding_type=cve_finding_type.reference,
ooi=url_reference,
proof=curl_command,
description=description,
reproduce=None, # Set this attribute if you have a reproduce value
)
yield finding
10 changes: 10 additions & 0 deletions boefjes/boefjes/plugins/kat_nuclei/normalizer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"id": "kat_nuclei_normalize",
"consumes": [
"nuclei"
],
"produces": [
"Findings",
"CVEFindingType"
]
}
Empty file.