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

248 check for xss eg using httpsgithubcomhahwuldalfox #1251

Merged
merged 51 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
2604e3e
Dalfox draft version
michalkrzem Aug 13, 2024
7580149
Dalfox module with multiple links and output as json.
michalkrzem Aug 23, 2024
1518934
Dalfox module with reports and new outputs
michalkrzem Aug 27, 2024
0c15d63
Reporter added
michalkrzem Aug 27, 2024
e54047b
stash
michalkrzem Sep 3, 2024
76ea96e
First tests added
michalkrzem Sep 3, 2024
fa59b72
Dalfox for all vuln_types.
michalkrzem Sep 4, 2024
b6383de
delete help_sql_error from git
michalkrzem Sep 4, 2024
058d23b
delete .readhedocs from git
michalkrzem Sep 4, 2024
a26c0c9
Links with extensions. Two tests by two links.
michalkrzem Sep 4, 2024
b5b9e72
Static extensions added
michalkrzem Sep 5, 2024
cfc3cd3
New parameter into xss.php added.
michalkrzem Sep 5, 2024
d948d07
Duplicates and tests added.
michalkrzem Sep 5, 2024
430bc30
Reports and translations added.
michalkrzem Sep 5, 2024
e5faa82
Correct test run command for whole project.
michalkrzem Sep 5, 2024
85bed57
artemis/modules/data/dalfox/ directory added
michalkrzem Sep 5, 2024
eaee72e
Merge branch 'main' into 248-check-for-xss-eg-using-httpsgithubcomhah…
michalkrzem Sep 6, 2024
b4f92cc
Test - fix
michalkrzem Sep 6, 2024
be3dc4b
Merge branch '248-check-for-xss-eg-using-httpsgithubcomhahwuldalfox' …
michalkrzem Sep 6, 2024
b422bbe
Readthedocs - fix. (I don't know why I deleted them before)
michalkrzem Sep 6, 2024
769bf84
After review.
michalkrzem Sep 6, 2024
1403903
Translations fixed
michalkrzem Sep 6, 2024
8767195
Sorted kartons
michalkrzem Sep 12, 2024
fc4442e
Reporting translations and priority
michalkrzem Sep 12, 2024
056df61
cat deleted
michalkrzem Sep 12, 2024
dd4c9b2
Username and password in the same form
michalkrzem Sep 12, 2024
be15e7f
Descriptions of the vulnerability variable, along with the configurat…
michalkrzem Sep 12, 2024
372a14c
Text fix
kazet Sep 17, 2024
85218b3
.
kazet Sep 17, 2024
49f5f4b
.
kazet Sep 17, 2024
3add515
.
kazet Sep 17, 2024
c470edb
.
kazet Sep 17, 2024
506930e
.
kazet Sep 17, 2024
4ccbb97
.
kazet Sep 17, 2024
1f07a85
.
kazet Sep 17, 2024
a1081d7
.
kazet Sep 17, 2024
80c8d58
.
kazet Sep 17, 2024
6c07a6a
.
kazet Sep 17, 2024
7c0bdf5
.
kazet Sep 17, 2024
73e0f36
.
kazet Sep 17, 2024
78a2229
.
kazet Oct 15, 2024
d41a38f
.
kazet Oct 15, 2024
f4852f0
mege
kazet Oct 15, 2024
a7f75ef
.
kazet Oct 15, 2024
217aef2
.
kazet Oct 15, 2024
929b831
.
kazet Oct 15, 2024
584be88
mege
kazet Oct 15, 2024
d61210d
.
kazet Oct 15, 2024
403c5e4
.
kazet Oct 15, 2024
4be016d
.
kazet Oct 15, 2024
ac6b114
.
kazet Oct 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions artemis/modules/dalfox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!/usr/bin/env python3
import json
import os
import subprocess
import tempfile
import urllib
from typing import Any, Dict, List, Tuple
from urllib.parse import unquote

from karton.core import Task

from artemis.binds import Service, TaskStatus, TaskType
from artemis.config import Config
from artemis.module_base import ArtemisBase
from artemis.task_utils import get_target_url


class DalFox(ArtemisBase):
"""
Running the Dalfox tool to scan for XSS vulnerabilities."""

identity = "dalfox"
filters = [
{"type": TaskType.SERVICE.value, "service": Service.HTTP.value},
]
dalfox_vulnerability_types = {"V": "Verify", "R": "Reflected", "G": "Grep"}

def __init__(self, *args: Any, **kwargs: Any):
super().__init__(*args, **kwargs)

@staticmethod
def _strip_query_string(url: str) -> str:
url_parsed = urllib.parse.urlparse(url)
return urllib.parse.urlunparse(url_parsed._replace(query="", fragment=""))

def prepare_output(self, vulnerabilities: List[Dict[str, Any]]) -> Tuple[List[str], List[Dict[str, Any]]]:
message: List[Any] = []
result: List[Any] = []

for vulnerability in (vuln for vuln in vulnerabilities if vuln != {}):
# Vulnerability - data concerning a single XSS vulnerability from the list found by the Dalfox module.
# In the loop instruction, I remove duplicates and the empty result that Dalfox generates at the last
# position of the results.
flag = any(
kazet marked this conversation as resolved.
Show resolved Hide resolved
(
(vulnerability.get("param") in result_single_data.values())
and (vulnerability.get("type") in result_single_data.values())
and (vulnerability["data"].split("?")[0] == result_single_data["url"].split("?")[0])
)
for result_single_data in result
)

if not flag:
data = {
"param": vulnerability.get("param"),
"evidence": unquote(vulnerability["evidence"]),
"type": vulnerability.get("type"),
"url": unquote(vulnerability["data"]),
"type_name": self.dalfox_vulnerability_types.get(vulnerability["type"]),
}
result.append(data)
message.append(
f"On {unquote(vulnerability['data'])} we identified an XSS vulnerability ("
f"type: {self.dalfox_vulnerability_types.get(vulnerability['type'])}) in "
f"the parameter: {vulnerability.get('param')}. "
)

result.sort(key=lambda x: x["param"])
return message, result

def scan(self, links_file_path: str, targets: List[str]) -> List[Dict[str, Any]]:
vulnerabilities = []

if Config.Miscellaneous.CUSTOM_USER_AGENT:
additional_configuration = ["--user-agent", Config.Miscellaneous.CUSTOM_USER_AGENT]
else:
additional_configuration = []

if Config.Limits.REQUESTS_PER_SECOND:
milliseconds_per_request = int((1 / Config.Limits.REQUESTS_PER_SECOND) * 1000.0)
else:
milliseconds_per_request = 0

try:
command = [
"dalfox",
"--debug",
"--delay",
f"{milliseconds_per_request}",
"file",
links_file_path,
"--method",
"GET",
"--worker",
"1",
"--format",
"json",
] + additional_configuration
self.log.info(f"Running command: {' '.join(command)}")

result = subprocess.run(
command,
capture_output=True,
text=True,
)
vulnerabilities = json.loads(result.stdout)
except subprocess.CalledProcessError as e:
self.log.error(f"Error when running DalFox: {e}")

return vulnerabilities

def run(self, current_task: Task) -> None:
url = get_target_url(current_task)
self.log.info(url)

# TODO: until we don't increase the speed, let's keep only the homepage for dalfox check
links = [url]

_, path_to_file_with_links = tempfile.mkstemp()
with open(path_to_file_with_links, "w") as file:
file.write("\n".join(links))

vulnerabilities = self.scan(links_file_path=path_to_file_with_links, targets=links)
message, result = self.prepare_output(vulnerabilities)
os.unlink(path_to_file_with_links)

if message:
status = TaskStatus.INTERESTING
status_reason = ", ".join(message)
else:
status = TaskStatus.OK
status_reason = None

self.db.save_task_result(task=current_task, status=status, status_reason=status_reason, data={"result": result})


if __name__ == "__main__":
DalFox().loop()
Empty file.
57 changes: 57 additions & 0 deletions artemis/reporting/modules/dalfox/reporter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import os
from typing import Any, Dict, List

from artemis.reporting.base.language import Language
from artemis.reporting.base.report import Report
from artemis.reporting.base.report_type import ReportType
from artemis.reporting.base.reporter import Reporter
from artemis.reporting.base.templating import ReportEmailTemplateFragment
from artemis.reporting.utils import get_top_level_target


class DalFoxReporter(Reporter):
"""
Running a report with data generated using the Dalfox tool, which scans URLs for XSS vulnerabilities.
"""

XSS = ReportType("xss")

@staticmethod
def get_alerts(all_reports: List[Report]) -> List[str]:
result = []

for report in all_reports:
if report.report_type == DalFoxReporter.XSS:
result.append(
f"As Dalfox is a new module, verify whether the problem on {report.target} is indeed a true positive."
)
return result

@staticmethod
def create_reports(task_result: Dict[str, Any], language: Language) -> List[Report]:
if task_result["headers"]["receiver"] != "dalfox":
return []

if not task_result["status"] == "INTERESTING":
return []

if not isinstance(task_result["result"], dict):
return []

return [
Report(
top_level_target=get_top_level_target(task_result),
target=f"{task_result['payload']['host']}",
report_type=DalFoxReporter.XSS,
additional_data=task_result["result"],
timestamp=task_result["created_at"],
)
]

@staticmethod
def get_email_template_fragments() -> List[ReportEmailTemplateFragment]:
return [
ReportEmailTemplateFragment.from_file(
os.path.join(os.path.dirname(__file__), "template_xss.jinja2"), priority=7
)
]
30 changes: 30 additions & 0 deletions artemis/reporting/modules/dalfox/template_xss.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{% if "xss" in data.contains_type %}
<li>
{% trans trimmed %}We identified that the following URLs contain XSS vulnerabilities:{% endtrans %}

<ul>
{% for report in data.reports %}
{% if report.report_type == "xss" %}
{% for message in report.additional_data.result %}
<li>
{{ message.url }}: {% trans trimmed %}we identified an XSS vulnerability in:{% endtrans %}
<b>{{ message.param }}</b>
({% trans trimmed %}example:{% endtrans %} {{ message.evidence }}).
</p>
</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
</ul>

{% trans trimmed %}
A Cross-Site Scripting vulnerability allows an attacker to craft a link that, when clicked by an administrator,
performs any action with their permissions (such as modifying content).
{% endtrans %}
{% trans trimmed %}
The above examples are automatically generated - contact us if they aren't sufficient for
you to reproduce the vulnerability.
{% endtrans %}
</li>
{% endif %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#: artemis/reporting/modules/dalfox/template_xss.jinja2:3
msgid "We identified that the following URLs contain XSS vulnerabilities:"
msgstr ""

#: artemis/reporting/modules/dalfox/template_xss.jinja2:10
msgid "we identified an XSS vulnerability in:"
msgstr ""

#: artemis/reporting/modules/dalfox/template_xss.jinja2:12
msgid "example:"
msgstr ""

#: artemis/reporting/modules/dalfox/template_xss.jinja2:21
msgid ""
"A Cross-Site Scripting vulnerability allows an attacker to craft a link "
"that, when clicked by an administrator, performs any action with their "
"permissions (such as modifying content)."
msgstr ""

#: artemis/reporting/modules/dalfox/template_xss.jinja2:25
msgid ""
"The above examples are automatically generated - contact us if they "
"aren't sufficient for you to reproduce the vulnerability."
msgstr ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#: artemis/reporting/modules/dalfox/template_xss.jinja2:3
msgid "We identified that the following URLs contain XSS vulnerabilities:"
msgstr "Wykryliśmy, że następujące adresy zawierają podatności XSS:"

#: artemis/reporting/modules/dalfox/template_xss.jinja2:10
msgid "we identified an XSS vulnerability in:"
msgstr "zidentyfikowaliśmy podatność w:"

#: artemis/reporting/modules/dalfox/template_xss.jinja2:12
msgid "example:"
msgstr "przykład:"

#: artemis/reporting/modules/dalfox/template_xss.jinja2:21
msgid ""
"A Cross-Site Scripting vulnerability allows an attacker to craft a link "
"that, when clicked by an administrator, performs any action with their "
"permissions (such as modifying content)."
msgstr ""
"Podatność Cross-Site Scripting umożliwia atakującemu spreparowanie linku,"
" który po kliknięciu przez administratora wykona dowolną akcję z jego "
"uprawnieniami (taką jak np. modyfikacja treści)."

#: artemis/reporting/modules/dalfox/template_xss.jinja2:25
msgid ""
"The above examples are automatically generated - contact us if they "
"aren't sufficient for you to reproduce the vulnerability."
msgstr ""
"Powyższe przykłady są generowane automatycznie - prosimy o kontakt, jeśli"
" nie są wystarczające, aby odtworzyć podatność po Państwa stronie."
1 change: 1 addition & 0 deletions artemis/reporting/severity.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Severity(str, Enum):
ReportType("misconfigured_email"): Severity.MEDIUM,
ReportType("old_drupal"): Severity.MEDIUM,
ReportType("old_joomla"): Severity.MEDIUM,
ReportType("xss"): Severity.HIGH,
# This doesn't mean that a version is insecure, as WordPress maintains a separate list
# of insecure versions. This just means "turn on the automatic updates"
ReportType("old_wordpress"): Severity.LOW,
Expand Down
8 changes: 8 additions & 0 deletions docker-compose.test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@ services:
volumes:
- ./test/reporting/data/bruteable_files/htpasswd/:/var/www/html/

test_apache-with-xss:
build:
dockerfile: test/images/php-xss/Dockerfile
command: systemctl start apache2.service
volumes:
- ./test/data/dalfox/:/var/www/html/


test-apache-with-sql-injection-postgres:
build:
dockerfile: test/images/php-postgres/Dockerfile
Expand Down
25 changes: 18 additions & 7 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ services:
restart: always
volumes: ["./docker/karton.ini:/etc/karton/karton.ini", "${DOCKER_COMPOSE_ADDITIONAL_SHARED_DIRECTORY:-./shared}:/shared/"]

karton-dalfox:
<<: *artemis-build-or-image
command: "python3 -m artemis.modules.dalfox"
depends_on: [karton-system, karton-logger]
env_file: .env
restart: always
volumes:
- "./docker/karton.ini:/etc/karton/karton.ini"
- "${DOCKER_COMPOSE_ADDITIONAL_SHARED_DIRECTORY:-./shared}:/shared/"

karton-dashboard:
depends_on: [karton-system, karton-logger]
env_file: .env
Expand Down Expand Up @@ -281,6 +291,14 @@ services:
restart: always
volumes: ["./docker/karton.ini:/etc/karton/karton.ini", "${DOCKER_COMPOSE_ADDITIONAL_SHARED_DIRECTORY:-./shared}:/shared/"]

karton-sql_injection_detector:
<<: *artemis-build-or-image
command: "python3 -m artemis.modules.sql_injection_detector"
depends_on: [karton-system, karton-logger]
env_file: .env
restart: always
volumes: ["./docker/karton.ini:/etc/karton/karton.ini", "${DOCKER_COMPOSE_ADDITIONAL_SHARED_DIRECTORY:-./shared}:/shared/"]

karton-ssh_bruter:
<<: *artemis-build-or-image
command: "python3 -m artemis.modules.ssh_bruter"
Expand Down Expand Up @@ -341,13 +359,6 @@ services:
restart: always
volumes: ["./docker/karton.ini:/etc/karton/karton.ini", "${DOCKER_COMPOSE_ADDITIONAL_SHARED_DIRECTORY:-./shared}:/shared/"]

karton-sql_injection_detector:
<<: *artemis-build-or-image
command: "python3 -m artemis.modules.sql_injection_detector"
depends_on: [karton-system, karton-logger]
env_file: .env
restart: always
volumes: ["./docker/karton.ini:/etc/karton/karton.ini", "${DOCKER_COMPOSE_ADDITIONAL_SHARED_DIRECTORY:-./shared}:/shared/"]


volumes:
Expand Down
6 changes: 5 additions & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
FROM python:3.12-alpine3.20

COPY --from=golang:1.23-alpine /usr/local/go/ /usr/local/go/
ENV PATH="/usr/local/go/bin:$PATH"

COPY docker/wait-for-it.sh /wait-for-it.sh
COPY requirements.txt requirements.txt
COPY docker/go.sum docker/go.mod /go/
Expand All @@ -8,13 +11,14 @@ ARG ADDITIONAL_REQUIREMENTS
# remove some apk packages.
# Whois here is important - if we wouldn't install it, we would default to busybox whois,
# having different output making https://pypi.org/project/whoisdomain/ regexes fail.
RUN apk add --no-cache --virtual .build-deps go gcc git libc-dev make libffi-dev libpcap-dev postgresql-dev && \
RUN apk add --no-cache --virtual .build-deps gcc git libc-dev make libffi-dev libpcap-dev postgresql-dev && \
apk add --no-cache bash libpcap libpq git subversion whois && \
cd /go && \
GOBIN=/usr/local/bin/ go install -modfile go.mod github.com/projectdiscovery/naabu/v2/cmd/naabu && \
GOBIN=/usr/local/bin/ go install -modfile go.mod github.com/praetorian-inc/fingerprintx/cmd/fingerprintx && \
GOBIN=/usr/local/bin/ go install -modfile go.mod github.com/lc/gau/v2/cmd/gau && \
GOBIN=/usr/local/bin/ go install -modfile go.mod github.com/projectdiscovery/subfinder/v2/cmd/subfinder && \
GOBIN=/usr/local/bin/ go install -modfile go.mod github.com/hahwul/dalfox/v2 && \
GOBIN=/usr/local/bin/ go install -modfile go.mod github.com/projectdiscovery/nuclei/v3/cmd/nuclei && \
cd / && \
git clone https://github.com/rfc-st/humble.git --branch master /humble && \
Expand Down
Loading