Archived
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1d979640f | ||
|
|
0e6ecf1f16 |
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 99 KiB |
Vendored
BIN
Binary file not shown.
Binary file not shown.
@@ -1,11 +1,49 @@
|
|||||||
version: '3.8'
|
version: '3.8'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
loki:
|
||||||
|
image: grafana/loki:3.0.0
|
||||||
|
container_name: loki
|
||||||
|
ports:
|
||||||
|
- "3100:3100"
|
||||||
|
command: -config.file=/etc/loki/local-config.yaml
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
grafana:
|
||||||
|
image: grafana/grafana:10.4.0
|
||||||
|
container_name: grafana
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- GF_SECURITY_ADMIN_USER=admin
|
||||||
|
- GF_SECURITY_ADMIN_PASSWORD=ocfsecure
|
||||||
|
depends_on:
|
||||||
|
- loki
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
alloy:
|
||||||
|
image: grafana/alloy:latest
|
||||||
|
container_name: alloy
|
||||||
|
volumes:
|
||||||
|
- ./alloy-config.yml:/etc/alloy/config.alloy
|
||||||
|
- ./logs:/var/log/scanner
|
||||||
|
ports:
|
||||||
|
- "12345:12345" # optional web UI/debug
|
||||||
|
command: run /etc/alloy/config.alloy
|
||||||
|
environment:
|
||||||
|
- ALLOY_ENABLE_WEB=true
|
||||||
|
depends_on:
|
||||||
|
- loki
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
apache:
|
apache:
|
||||||
build:
|
build:
|
||||||
context: ./apache
|
context: ./apache
|
||||||
ports:
|
ports:
|
||||||
- "8080:80"
|
- "8080:80"
|
||||||
|
networks:
|
||||||
|
- shared_net
|
||||||
|
- default
|
||||||
volumes:
|
volumes:
|
||||||
- userdata:/home
|
- userdata:/home
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -52,3 +90,7 @@ volumes:
|
|||||||
userdata:
|
userdata:
|
||||||
db_data:
|
db_data:
|
||||||
wp_data:
|
wp_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
shared_net:
|
||||||
|
external: true
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Username: admin
|
||||||
|
Password: wp_graf_pass
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
shared_net:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
loki:
|
||||||
|
image: grafana/loki:3.0.0
|
||||||
|
container_name: loki
|
||||||
|
ports:
|
||||||
|
- "3100:3100"
|
||||||
|
command: -config.file=/etc/loki/local-config.yaml
|
||||||
|
networks:
|
||||||
|
- shared_net
|
||||||
|
|
||||||
|
grafana:
|
||||||
|
image: grafana/grafana:10.4.0
|
||||||
|
container_name: grafana
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- GF_SECURITY_ADMIN_USER=admin
|
||||||
|
- GF_SECURITY_ADMIN_PASSWORD=admin
|
||||||
|
depends_on:
|
||||||
|
- loki
|
||||||
|
networks:
|
||||||
|
- shared_net
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
import json
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
|
|
||||||
|
|
||||||
json_path = "wordfence_vulnerabilities.json"
|
|
||||||
|
|
||||||
def load_cvss_scores(path):
|
|
||||||
"""Load JSON data and extract all CVSS scores into a list"""
|
|
||||||
with open(path, "r", encoding="utf-8") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
scores = []
|
|
||||||
for entry in data:
|
|
||||||
|
|
||||||
if "cvss_score" in entry and isinstance(entry["cvss_score"], (int, float)):
|
|
||||||
scores.append(entry["cvss_score"])
|
|
||||||
return scores
|
|
||||||
|
|
||||||
|
|
||||||
def plot_hist(scores):
|
|
||||||
"""Plot a histogram of CVSS scores"""
|
|
||||||
plt.figure(figsize=(8, 5))
|
|
||||||
plt.hist(scores, bins=10, edgecolor="black", color="skyblue")
|
|
||||||
plt.title("Distribution of CVSS Scores in Vulnerability Data")
|
|
||||||
plt.xlabel("CVSS Score")
|
|
||||||
plt.ylabel("Number of Vulnerabilities")
|
|
||||||
plt.grid(alpha=0.4)
|
|
||||||
plt.savefig("cvss_distribution.png")
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
scores = load_cvss_scores(json_path)
|
|
||||||
print(f"Loaded {len(scores)} CVSS scores.")
|
|
||||||
print("Sample:", scores[:10])
|
|
||||||
|
|
||||||
if scores:
|
|
||||||
plot_hist(scores)
|
|
||||||
else:
|
|
||||||
print("error")
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import json
|
|
||||||
from collections import Counter
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
|
|
||||||
|
|
||||||
path = "wordfence_vulnerabilities.json"
|
|
||||||
|
|
||||||
# Load JSON data
|
|
||||||
with open(path, "r", encoding="utf-8") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
vuln_types = []
|
|
||||||
|
|
||||||
for entry in data:
|
|
||||||
title = entry.get("title")
|
|
||||||
if not isinstance(title, str):
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Split on the first dash (" - ") and take the right-hand side
|
|
||||||
if " - " in title:
|
|
||||||
vuln = title.split(" - ", 1)[1].strip()
|
|
||||||
vuln_types.append(vuln)
|
|
||||||
|
|
||||||
# Count occurrences
|
|
||||||
counts = Counter(vuln_types)
|
|
||||||
top25 = counts.most_common(25)
|
|
||||||
total = sum(counts.values())
|
|
||||||
|
|
||||||
if not vuln_types:
|
|
||||||
print("error")
|
|
||||||
exit()
|
|
||||||
|
|
||||||
# Print table of top 25
|
|
||||||
print("\nTop 25 Vulnerability Types:\n")
|
|
||||||
for name, count in top25:
|
|
||||||
rel = (count / total) * 100
|
|
||||||
print(f"{name:60} {count:5d} ({rel:5.2f}%)")
|
|
||||||
|
|
||||||
# Visualization
|
|
||||||
labels, values = zip(*top25)
|
|
||||||
plt.figure(figsize=(10, 6))
|
|
||||||
plt.barh(labels[::-1], values[::-1], color="cornflowerblue")
|
|
||||||
plt.title("Top 25 Most Common Vulnerability Types")
|
|
||||||
plt.xlabel("Count")
|
|
||||||
plt.ylabel("Vulnerability Type")
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
requests
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
|
|
||||||
# vars
|
|
||||||
JSON_FILE = "wordfence_vulnerabilities.json"
|
|
||||||
BAD_LIST = []
|
|
||||||
|
|
||||||
JSON_OUT = "matches.json"
|
|
||||||
|
|
||||||
|
|
||||||
def load_local(path):
|
|
||||||
with open(path, "r", encoding="utf-8") as f:
|
|
||||||
return json.load(f)
|
|
||||||
|
|
||||||
|
|
||||||
def get_entries(data):
|
|
||||||
# try to find the main list of vulnerabilities
|
|
||||||
if isinstance(data, dict):
|
|
||||||
if "vulnerabilities" in data:
|
|
||||||
return data["vulnerabilities"]
|
|
||||||
for value in data.values():
|
|
||||||
if isinstance(value, list):
|
|
||||||
return value
|
|
||||||
return []
|
|
||||||
elif isinstance(data, list):
|
|
||||||
return data
|
|
||||||
else:
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
if os.path.exists(JSON_FILE):
|
|
||||||
print("Loading ...", JSON_FILE)
|
|
||||||
data = load_local(JSON_FILE)
|
|
||||||
else:
|
|
||||||
print("Error: JSON file not found:", JSON_FILE)
|
|
||||||
return
|
|
||||||
|
|
||||||
entries = get_entries(data)
|
|
||||||
|
|
||||||
bad_set = set(BAD_LIST)
|
|
||||||
hits = []
|
|
||||||
|
|
||||||
for item in entries:
|
|
||||||
if not isinstance(item, dict):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if item.get("type") != "plugin":
|
|
||||||
continue
|
|
||||||
|
|
||||||
slug = (item.get("slug") or "").strip()
|
|
||||||
if not slug:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if slug in bad_set:
|
|
||||||
hit = {
|
|
||||||
"slug": slug,
|
|
||||||
"title": item.get("title"),
|
|
||||||
"cve": item.get("cve"),
|
|
||||||
"severity": item.get("severity"),
|
|
||||||
"cvss_score": item.get("cvss_score"),
|
|
||||||
"cve_link": item.get("cve_link"),
|
|
||||||
"raw": item
|
|
||||||
}
|
|
||||||
hits.append(hit)
|
|
||||||
|
|
||||||
if not hits:
|
|
||||||
print("No matches at all")
|
|
||||||
else:
|
|
||||||
print("Found", len(hits), "matches:")
|
|
||||||
for h in hits:
|
|
||||||
print(
|
|
||||||
"-",
|
|
||||||
h["slug"],
|
|
||||||
"| CVE:", h.get("cve"),
|
|
||||||
"| sev:", h.get("severity"),
|
|
||||||
"| CVSS:", h.get("cvss_score")
|
|
||||||
)
|
|
||||||
print(" link:", h.get("cve_link"))
|
|
||||||
|
|
||||||
# save
|
|
||||||
with open(JSON_OUT, "w", encoding="utf-8") as f:
|
|
||||||
json.dump(hits, f, ensure_ascii=False, indent=2)
|
|
||||||
print("Saved to", JSON_OUT)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
get_CVE.py **MUST** be ran before cve_scanner_new1 can be ran since it runs using a list that is fetched daily.
|
|
||||||
CVE_scanner.py runs on a static list called wordfence_vulnerabilities.json that is stored in the same directory, which is an old list of major vulnerabilities.
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
|
|
||||||
JSON_FILE = "wordfence_CVE.json"
|
|
||||||
JSON_OUT = "malware.json"
|
|
||||||
BAD_PLUGINS = []
|
|
||||||
|
|
||||||
|
|
||||||
def load_file(path):
|
|
||||||
with open(path, "r", encoding="utf-8") as f:
|
|
||||||
return json.load(f)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
if not os.path.exists(JSON_FILE):
|
|
||||||
print("json file not found:", JSON_FILE)
|
|
||||||
return
|
|
||||||
|
|
||||||
data = load_file(JSON_FILE)
|
|
||||||
|
|
||||||
bad_set = set()
|
|
||||||
for n in BAD_PLUGINS:
|
|
||||||
if isinstance(n, str):
|
|
||||||
n = n.strip()
|
|
||||||
if n:
|
|
||||||
bad_set.add(n)
|
|
||||||
|
|
||||||
hits = []
|
|
||||||
|
|
||||||
for key, item in data.items():
|
|
||||||
if not isinstance(item, dict):
|
|
||||||
continue
|
|
||||||
|
|
||||||
software_list = item.get("software") or []
|
|
||||||
for s in software_list:
|
|
||||||
if not isinstance(s, dict):
|
|
||||||
continue
|
|
||||||
if s.get("type") != "plugin":
|
|
||||||
continue
|
|
||||||
|
|
||||||
name = (s.get("name") or "").strip()
|
|
||||||
if name not in bad_set:
|
|
||||||
continue
|
|
||||||
|
|
||||||
affected = s.get("affected_versions") or {}
|
|
||||||
if not affected:
|
|
||||||
continue
|
|
||||||
|
|
||||||
refs = item.get("references") or []
|
|
||||||
ref = refs[0] if refs else None
|
|
||||||
|
|
||||||
hit = {
|
|
||||||
"id": item.get("id"),
|
|
||||||
"title": item.get("title"),
|
|
||||||
"name": name,
|
|
||||||
"slug": s.get("slug"),
|
|
||||||
"affected_versions": list(affected.keys()),
|
|
||||||
"link": ref,
|
|
||||||
"raw": item
|
|
||||||
}
|
|
||||||
hits.append(hit)
|
|
||||||
|
|
||||||
if not hits:
|
|
||||||
print("no matches found")
|
|
||||||
else:
|
|
||||||
print("found", len(hits), "matches")
|
|
||||||
for h in hits:
|
|
||||||
print("-", h["name"], "|", ", ".join(h["affected_versions"]))
|
|
||||||
|
|
||||||
with open(JSON_OUT, "w", encoding="utf-8") as f:
|
|
||||||
json.dump(hits, f, ensure_ascii=False, indent=2)
|
|
||||||
print("saved json to", JSON_OUT)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import requests
|
|
||||||
import os
|
|
||||||
|
|
||||||
URL = "https://www.wordfence.com/api/intelligence/v2/vulnerabilities/scanner"
|
|
||||||
OUT_FILE = "wordfence_CVE.json"
|
|
||||||
|
|
||||||
def main():
|
|
||||||
print("API request.....")
|
|
||||||
r = requests.get(URL, timeout=60)
|
|
||||||
r.raise_for_status()
|
|
||||||
|
|
||||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
out_path = os.path.join(script_dir, OUT_FILE)
|
|
||||||
|
|
||||||
with open(out_path, "w", encoding="utf-8") as f:
|
|
||||||
f.write(r.text)
|
|
||||||
|
|
||||||
print("File Saved!")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
-1165623
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
-520306
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user