Extract hostnames and domains from DDoSia MISP object

DDoSia

DDoSia is a distributed denial-of-service (DDoS) attack tool reportedly employed by pro-Russian hacktivist groups. The tool coordinates large networks of compromised devices to flood targeted websites or services with excessive traffic, overwhelming their capacity and rendering them inaccessible to legitimate users. It has been used to disrupt government, financial, and media platforms, aiming to create instability and hinder critical infrastructure.

The DDoSia configuration, basically the instructions for the attack tool, have been shared via the MISP platform as MISP objects (ddos-config object).

Extract hostnames and domains

I created a small tool to

  • Search for the events with the DDoSia config file;
  • Extract the unique hostnames and domains;
  • Print the summary, and optionally send it to Mattermost.

The script requires the pymisp and tldextract Python libraries.

Sample output

1Parsed 9 events and found 65 unique hostnames for 49 domains - (2024-10-08)
2Hostnames
3 1535.omr.gov.ua
4 authentication.antwerpen.be
5 cabinet.teplo.od.ua
6 cci.sumy.ua
7 citizen.omr.gov.ua
8 dsns.gov.ua
9 gouvernement.cfwb.be
10 itd.rada.gov.ua
11 kassa.bus.com.ua
12 komfinbank.rada.gov.ua
13 komit.rada.gov.ua
14 komnbor.rada.gov.ua
15 kompek.rada.gov.ua




Script

You can find the script on GitHub at https://github.com/cudeso/tools/blob/master/ddosia-extract/parse_ddosia.py. Make sure you

  • Set the misp_url and misp_key. Point it to your MISP server;
  • Set the date_filter to limit the results;
  • Choose if you want to send results to Mattermost with send_mattermost (and set mattermost_hook)

1import urllib3
2import sys
3import json
4import requests
5import tldextract
6from datetime import datetime
7 
8from pymisp import *
9 
10# Get events from MISP with the DDoSia configuration object.
11# Extract unique hostnames and domains
12# Optionally send to Mattermost
13#
14# Koen Van Impe - 2024
15 
16# Credentials
17misp_url = "MISP"
18misp_key = "KEY"
19misp_verifycert = True
20mattermost_hook = ""
21teams_hook = ""
22ddosia_file_output = "/var/www/MISP/app/webroot/misp-export/ddosia.txt"
23 
24# Output
25target_hostnames = []
26target_domains = []
27 
28# Send to Mattermost?
29send_mattermost = False
30 
31# Send to Teams
32send_teams = False
33 
34# Write to file
35write_to_ddosia_file_output = False
36 
37# MISP organisation "witha.name"
38query_org = "ae763844-03bf-4588-af75-932d5ed2df8c"
39 
40# Published?
41published = True
42 
43# Limit for recent events
44date_filter = "1d"
45 
46# Create PyMISP object and test connectivity
47misp = PyMISP(misp_url, misp_key, misp_verifycert)
48print(f"Extract hostnames from {misp_url}")
49 
50# Search for events
51events = misp.search("events", pythonify=True, org=query_org, published=published, date=date_filter)
52 
53# Process events
54if len(events) > 0:
55    print("Parsing {} events".format(len(events)))
56    for event in events:
57        print(" Event {} ({})".format(event.info, event.uuid))
58        for object in event.objects:
59            if object.name == "ddos-config":
60                for attribute in object.Attribute:
61                    if attribute.type == "hostname":
62                        check_value = attribute.value.lower().strip()
63                        if check_value not in target_hostnames:
64                            target_hostnames.append(check_value)
65                            print(f"  Found {check_value}")
66 
67                        extracted = tldextract.extract(check_value)
68                        domain = '.'.join([extracted.domain, extracted.suffix])
69                        if domain not in target_domains:
70                            target_domains.append(domain)
71 
72    if len(target_hostnames) > 0:
73        target_hostnames.sort()
74        target_domains.sort()
75         
76        title = "DDoSia config: Parsed {} MISP events and found {} unique hostnames for {} domains - ({}, last {})".format(len(events), len(target_hostnames), len(target_domains), datetime.now().date(), date_filter)
77        summary = "Hostnames\n------------\n"
78        summary_md = "# Hostnames\n"
79 
80        for t in target_hostnames:
81            summary += "\n{}".format(t)
82            summary_md += "\n- {}".format(t)
83 
84        summary += "\n\nDomains\n----------\n"
85        summary_md += "\n\n# Domains\n"
86        for t in target_domains:
87            summary += "\n{}".format(t)
88            summary_md += "\n- {}".format(t)
89        summary_md += "\n"
90         
91        if send_mattermost:
92            summary_md = title + summary_md + "\n"
93            message = {"username": "witha.name-reporters", "text": summary_md}
94            r = requests.post(mattermost_hook, data=json.dumps(message))
95            print(r, r.status_code, r.text)
96                         
97        if send_teams:
98            message = {
99                    "type": "message",
100                    "attachments": [
101                        {
102                            "contentType": "application/vnd.microsoft.teams.card.o365connector",
103                            "content": {
104                                "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
105                                "type": "MessageCard",
106                                "context": "https://schema.org/extensions",
107                                "title": title,
108                                "version": "1.0",
109                                "sections": [
110                                    {
111                                        "text": summary_md
112                                    }
113                                ]
114                            }
115                        }
116                    ]
117                }
118            r = requests.post(teams_hook, json=message)
119             
120        if write_to_ddosia_file_output:
121            summary = title + "\n\n" + summary + "\n"
122            with open(ddosia_file_output, 'w') as file:
123                file.write(summary)
124 
125else:
126    print("No events found.")

One thought on “Extract hostnames and domains from DDoSia MISP object

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.