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

Report that the domain will soon expire #495 #544

Merged
merged 23 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6c92a3b
Check that the domain will soon expire, (#495)
anna1492 Sep 22, 2023
eb1182d
Report that the domain will soon expire - reporter, scanner-changes (…
anna1492 Sep 26, 2023
82af5b9
Report that the domain will soon expire - translation, (#495)
anna1492 Oct 2, 2023
3128538
Report that the domain will soon expire - translation - update, (#495)
anna1492 Oct 2, 2023
074d4cd
Report that the domain will soon expire - tests, (#495)
anna1492 Oct 3, 2023
cc85f34
Report that the domain will soon expire - changes, improvements (#495)
anna1492 Oct 4, 2023
1639719
Report that the domain will soon expire - translation - update (#495)
anna1492 Oct 4, 2023
8bc1abf
Report that the domain will soon expire - changes (#495)
anna1492 Oct 10, 2023
5c0093c
Report that the domain will soon expire - additional changes (#495)
anna1492 Oct 11, 2023
a1ca9fc
Merge branch 'main' into domain-expiration-scanner
kazet Oct 11, 2023
a1eb893
Supporting domains in normal forms
kazet Oct 11, 2023
3062654
lint
kazet Oct 11, 2023
6804fd9
lint
kazet Oct 11, 2023
64155d0
Report that the domain will soon expire - config - change (#495)
anna1492 Oct 12, 2023
22ef702
Merge branch 'domain-expiration-scanner' of github.com:CERT-Polska/Ar…
anna1492 Oct 13, 2023
46180b1
Report that the domain will soon expire - whois limit (#495)
anna1492 Oct 17, 2023
6e429b2
Report that the domain will soon expire - log message - change (#495)
anna1492 Oct 18, 2023
93aa8d3
Report that the domain will soon expire - change (#495)
anna1492 Oct 18, 2023
c74c922
Merge branch 'main' into domain-expiration-scanner
anna1492 Oct 18, 2023
6e942a8
Report that the domain will soon expire - rate limit, refactoring (#495)
anna1492 Oct 19, 2023
fbc2a1c
Report that the domain will soon expire - rate limit - change, refact…
anna1492 Oct 23, 2023
6d3f81c
Report that the domain will soon expire - fix (#495)
anna1492 Oct 23, 2023
ce5f5b3
Report that the domain will soon expire - additional type hints (#495)
anna1492 Oct 24, 2023
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
5 changes: 5 additions & 0 deletions artemis/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,11 @@ class WordPressBruter:
"www123, when testing www.projectname.example.com.",
] = get_config("WORDPRESS_BRUTER_STRIPPED_PREFIXES", default="www", cast=decouple.Csv(str))

class DomainExpirationScanner:
DOMAIN_EXPIRATION_ALERT_IN_DAYS: Annotated[
kazet marked this conversation as resolved.
Show resolved Hide resolved
int, "The scanner warns if the domain's expiration date falls within this time frame from now."
] = get_config("DOMAIN_EXPIRATION_ALERT_IN_DAYS", default=5, cast=int)
kazet marked this conversation as resolved.
Show resolved Hide resolved

@staticmethod
def verify_each_variable_is_annotated() -> None:
def verify_class(cls: type) -> None:
Expand Down
52 changes: 52 additions & 0 deletions artemis/modules/domain_expiration_scanner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
import datetime
from typing import Any, Dict

from karton.core import Task
from whois import query # type: ignore

from artemis.binds import TaskStatus, TaskType
from artemis.config import Config
from artemis.domains import is_main_domain
from artemis.module_base import ArtemisBase


class DomainExpirationScanner(ArtemisBase):
"""
Alerts if domain expiration date is coming.
"""

identity = "domain_expiration_scanner"
filters = [{"type": TaskType.DOMAIN.value}]

def run(self, current_task: Task) -> None:
domain = current_task.get_payload(TaskType.DOMAIN)
if is_main_domain(domain):
now = datetime.datetime.now()
result: Dict[str, Any] = {}
domain_data = query(domain)
kazet marked this conversation as resolved.
Show resolved Hide resolved
expiry_date = domain_data.expiration_date
days_to_expire = None
if expiry_date:
days_to_expire = (expiry_date - now).days
result["expiry_date"] = expiry_date
if (
days_to_expire
and days_to_expire <= Config.Modules.DomainExpirationScanner.DOMAIN_EXPIRATION_ALERT_IN_DAYS
):
result["close_expiry_date"] = True
result["days_to_expire"] = days_to_expire
status = TaskStatus.INTERESTING
kazet marked this conversation as resolved.
Show resolved Hide resolved
status_reason = (
f"Scanned domain will expire in {days_to_expire} days."
if days_to_expire != 1
else f"Scanned domain will expire in {days_to_expire} day."
)
else:
status = TaskStatus.OK
kazet marked this conversation as resolved.
Show resolved Hide resolved
status_reason = None
self.db.save_task_result(task=current_task, status=status, status_reason=status_reason, data=result)


if __name__ == "__main__":
DomainExpirationScanner().loop()
45 changes: 45 additions & 0 deletions artemis/reporting/modules/domain_expiration_scanner/reporter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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 DomainExpirationScannerReporter(Reporter):
CLOSE_DOMAIN_EXPIRATION_DATE = ReportType("close_domain_expiration_date")

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

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

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

additional_data = task_result["result"]

return [
Report(
top_level_target=get_top_level_target(task_result),
target=f"http://{task_result['payload']['domain']}",
kazet marked this conversation as resolved.
Show resolved Hide resolved
report_type=DomainExpirationScannerReporter.CLOSE_DOMAIN_EXPIRATION_DATE,
additional_data=additional_data["days_to_expire"],
kazet marked this conversation as resolved.
Show resolved Hide resolved
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_close_domain_expiration_scanner.jinja2"),
priority=5,
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{% if "close_domain_expiration_date" in data.contains_type %}
<li>{% trans %}The following addresses will soon expire: {% endtrans %}
kazet marked this conversation as resolved.
Show resolved Hide resolved
<ul>
{% for report in data.reports %}
{% if report.report_type == "close_domain_expiration_date" %}
<li>
<p> {{ report.target }} - {{ report.additional_data }} {% trans %}days{% endtrans %}</p>
kazet marked this conversation as resolved.
Show resolved Hide resolved
</li>
{% endif %}
{% endfor %}
</ul>
</li>
{% endif %}
1 change: 1 addition & 0 deletions artemis/reporting/severity.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Severity(str, Enum):
ReportType("directory_index"): Severity.MEDIUM,
ReportType("open_port_remote_desktop"): Severity.MEDIUM,
ReportType("exposed_bash_history"): Severity.MEDIUM,
ReportType("close_domain_expiry_date"): Severity.MEDIUM,
ReportType("certificate_authority_invalid"): Severity.LOW,
ReportType("expired_ssl_certificate"): Severity.LOW,
ReportType("almost_expired_ssl_certificate"): Severity.LOW,
Expand Down
10 changes: 10 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,16 @@ services:
restart: always
volumes: ["./docker/karton.ini:/etc/karton/karton.ini"]

karton-domain_expiration_scanner:
build:
context: .
dockerfile: docker/Dockerfile
command: "python3 -m artemis.modules.domain_expiration_scanner"
depends_on: [ karton-logger ]
env_file: .env
restart: always
volumes: [ "./docker/karton.ini:/etc/karton/karton.ini" ]

volumes:
data-mongodb:
data-redis:
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM python:3.11-alpine3.18
COPY docker/wait-for-it.sh /wait-for-it.sh

ARG ADDITIONAL_REQUIREMENTS
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 go gcc git libc-dev make libffi-dev libpcap-dev postgresql-dev whois && \
apk add --no-cache bash libpcap libpq git subversion
RUN GOBIN=/usr/local/bin/ go install github.com/projectdiscovery/naabu/v2/cmd/[email protected] && \
GOBIN=/usr/local/bin/ go install github.com/praetorian-inc/fingerprintx/cmd/[email protected] && \
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ typing-extensions==4.8.0
urllib3==1.26.16
uvicorn==0.23.2
validators==0.22.0
whois==0.9.27