-
Notifications
You must be signed in to change notification settings - Fork 55
/
Copy pathpdf_annot_urls.py
127 lines (114 loc) · 5.21 KB
/
pdf_annot_urls.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# Copyright (C) 2024 Wassime BATTA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
from urllib.parse import parse_qs, urlparse
from lib.cuckoo.common.abstracts import Signature
from lib.cuckoo.common.constants import CUCKOO_ROOT
def extract_domains(url):
domains = set()
try:
parsed_url = urlparse(url)
if parsed_url.netloc:
domains.add(parsed_url.netloc)
query_params = parse_qs(parsed_url.query)
for param_values in query_params.values():
for value in param_values:
param_url = urlparse(value)
if param_url.netloc:
domains.add(param_url.netloc)
except Exception as e:
print("extract_domains, %s", str(e))
return domains
class PDF_Annot_URLs_Checker(Signature):
name = "pdf_annot_urls_checker"
description = "The PDF contains a Link Annotation"
severity = 2 # Default severity
categories = ["static"]
authors = ["Wassime BATTA"]
minimum = "0.5"
enaled = False
filter_analysistypes = set(["file", "static"])
malicious_tlds_files = (
"custom/data/malicioustlds.txt",
"data/malicioustlds.txt",
)
def __init__(self, *args, **kwargs):
super(PDF_Annot_URLs_Checker, self).__init__(*args, **kwargs)
self.malicious_tlds = self.load_malicious_tlds()
def load_malicious_tlds(self):
malicious_tlds = set()
malicious_tlds_file = False
for malicious_tlds_file in self.malicious_tlds_files:
path = os.path.join(CUCKOO_ROOT, malicious_tlds_file)
if os.path.exists(path):
malicious_tlds_file = path
break
if not malicious_tlds_file:
with open(malicious_tlds_file, "r") as f:
for line in f:
line = line.strip()
if line.startswith("."):
malicious_tlds.add(line)
return malicious_tlds
def run(self):
found_malicious_extension = False
found_malicious_domain = False
found_domain_only = False
found_blacklist_ip = False
suspect = False
if "PDF" in self.results.get("target", {}).get("file", {}).get("type"):
for entry in self.results.get("target").get("file", {}).get("pdf", {}).get("Annot_URLs", []):
entry_lower = entry.lower()
self.data.append({"url": entry})
if entry_lower.endswith(
(".exe", ".zip", ".rar", ".bat", ".cmd", ".js", ".jse", ".vbs", ".vbe", ".ps1", ".psm1", ".sh")
) and not entry_lower.startswith("mailto:"):
found_malicious_extension = True
if entry_lower.startswith(("http://", "https://")):
domain_start = entry_lower.find("//") + 2
domain_end = entry_lower.find("/", domain_start)
if domain_end == -1:
domain = entry_lower[domain_start:]
else:
domain = entry_lower[domain_start:domain_end]
for malicious_tld in self.malicious_tlds:
if domain.endswith(malicious_tld):
found_malicious_domain = True
break
else:
# If no malicious TLDs detected, set found_domain_only to True
targets = extract_domains(entry_lower)
for target in targets:
blacklisted_server, server = self.check_dnsbbl(target)
if blacklisted_server:
found_blacklist_ip = True
self.data.append(
{
"blacklisted": f"The domain or IP address {target} is blacklisted on the following server: {server} "
}
)
# break # Stop checking once blacklisted IP is found
# print ( blacklisted_server)
# else:
# print(f"The domain or IP address {target} is not blacklisted.")
if found_malicious_domain or found_malicious_extension or found_blacklist_ip:
self.severity = 6
self.description = "The PDF contains a Malicious Link Annotation"
suspect = True
elif found_domain_only:
self.severity = 2
self.description = "The PDF contains a Link Annotation"
suspect = True
return suspect