Skip to content

Commit

Permalink
New Update
Browse files Browse the repository at this point in the history
Metamask and OpenPhish added, Better UI, fixed bugs
  • Loading branch information
clienthold authored Jan 31, 2025
1 parent a79d62f commit 32b8ca0
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 30 deletions.
51 changes: 40 additions & 11 deletions api.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from modules.yasafebrowsing import ya_check
from modules.tranco import domain_raiting
from modules.netcraft import netcraft_submit
from modules.metamask import metamask_list
from modules.openphish import openphish_list
from config import *
import time

Expand All @@ -30,7 +32,7 @@ def whois(self) -> None:
try:
whois_data = whois.whois(self.domain)
except whois.parser.PywhoisError:
abort(503, "The domain isn't found in WhoIs")
return

if not len(self.domain.split(".")) > 2:
try:
Expand Down Expand Up @@ -75,8 +77,8 @@ def whois(self) -> None:

def urlscan(self) -> None:
self.report_content["UrlScan"] = []

scan = UrlScan(US_API)

try:
scan.submit_url(self.url)
scan.get_results()
Expand Down Expand Up @@ -115,19 +117,23 @@ def safe_browsing(self) -> None:

def virustotal(self) -> None:
self.report_content["VirusTotal"] = []

vt = virustotal_python.Virustotal(VT_API)

try:
if self.is_domain is True:
results = vt.request("urls", data={"url": self.domain}, method="POST")
else:
results = vt.request("urls", data={"url": self.url}, method="POST")

url_id = urlsafe_b64encode(self.url.encode()).decode().strip("=")
for _ in range(40):

for _ in range(15):
try:
results = vt.request(f"urls/{url_id}")

if results.data["attributes"]["last_analysis_stats"]["undetected"] == 0:
raise ValueError()

break
except (virustotal_python.virustotal.VirustotalError, ValueError):
time.sleep(2)
Expand All @@ -136,9 +142,9 @@ def virustotal(self) -> None:
suspicious = results.data["attributes"]["last_analysis_stats"]["suspicious"]
undetected = results.data["attributes"]["last_analysis_stats"]["undetected"]

self.report_content["VirusTotal"].append(f"Malicious: {malicious}|malicious")
self.report_content["VirusTotal"].append(f"Suspicious: {suspicious}|suspicious")
self.report_content["VirusTotal"].append(f"Undetected: {undetected}|clear")
self.report_content["VirusTotal"].append(f"{malicious}|malicious")
self.report_content["VirusTotal"].append(f"{suspicious}|suspicious")
self.report_content["VirusTotal"].append(f"{undetected}|clear")
except Exception:
self.report_content["VirusTotal"].append("Failed")

Expand All @@ -148,22 +154,25 @@ def metadefender(self) -> None:
try:
md = MetaDefender(MD_API)
md.submit_domain(self.domain)

if md.detected > 0:
self.report_content["MetaDefender"].append(f"{md.detected} / {md.allengines}|malicious")
self.report_content["MetaDefender"].append(f"{md.detected}|malicious")
self.report_content["MetaDefender"].append(f"{md.allengines-md.detected}|clear")
else:
self.report_content["MetaDefender"].append(f"{md.detected} / {md.allengines}|clear")
self.report_content["MetaDefender"].append(f"{md.allengines}|clear")
except Exception as e:
self.report_content["MetaDefender"].append("Failed")

def yandex_status(self) -> None:
self.report_content["Yandex Status"] = []

result = ya_check(self.url)

if len(result["info"]) > 0 and "threat" in result["info"][0]:
if result["info"][0]["threat"] == "fraud.phishing":
self.report_content["Yandex Status"].append("Malicious|malicious")
else:
self.report_content["Yandex Status"].append("Not Found")
self.report_content["Yandex Status"].append("Clear|clear")
self.report_content["Yandex Status"].append(f"https://yandex.com/support/search/troubleshooting/delspam.html|reportlink")

def wayback_machine(self) -> None:
Expand Down Expand Up @@ -201,4 +210,24 @@ def netcraft(self) -> None:

self.report_content["Netcraft"].append(f"https://report.netcraft.com/submission/{netcraft_id}|reportlink")
except ValueError:
self.report_content["Netcraft"].append("Already submitted")
self.report_content["Netcraft"].append("Already submitted")

def metamask(self) -> None:
self.report_content["Metamask"] = []

result = metamask_list(self.domain)

if result is True:
self.report_content["Metamask"].append("Malicious|malicious")
else:
self.report_content["Metamask"].append("Clear|clear")

def openphish(self) -> None:
self.report_content["OpenPhish Feed"] = []

result = openphish_list(self.domain)

if result is True:
self.report_content["OpenPhish Feed"].append("Malicious|malicious")
else:
self.report_content["OpenPhish Feed"].append("Clear|clear")
3 changes: 3 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
SB_API = ""

# VIRUSTOTAL API KEY
# https://www.virustotal.com/gui/user/<USERNAME>/apikey
VT_API = ""

# URLSCAN API KEY
# https://urlscan.io/user/profile/
US_API = ""

# METADEFENDER API KEY
# https://metadefender.opswat.com/account
MD_API = ""
31 changes: 25 additions & 6 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from flask import Flask
from flask import request
from flask import render_template
from flask import abort
from flask import send_file
from api import report_api
from modules.reportgen import create_csv
import threading
import validators
import requests
import io
from ast import literal_eval as make_tuple
from datetime import datetime, timedelta, timezone
import functools
import webbrowser
from config import *

Expand All @@ -18,9 +18,28 @@

app = Flask(__name__)

def timed_cache(**timedelta_kwargs):

def _wrapper(f):
update_delta = timedelta(**timedelta_kwargs)
next_update = datetime.now(timezone.utc) + update_delta
f = functools.lru_cache(None)(f)

@functools.wraps(f)
def _wrapped(*args, **kwargs):
nonlocal next_update
now = datetime.now(timezone.utc)
if now >= next_update:
f.cache_clear()
next_update = now + update_delta
return f(*args, **kwargs)
return _wrapped
return _wrapper

@timed_cache(seconds=300)
def create_report(url: str, is_domain=False) -> tuple:
report = report_api(url, is_domain)
todo = [report.whois, report.urlscan, report.safe_browsing, report.virustotal, report.metadefender, report.yandex_status, report.wayback_machine, report.threatminer, report.netcraft]
todo = [report.whois, report.urlscan, report.safe_browsing, report.virustotal, report.metadefender, report.yandex_status, report.wayback_machine, report.threatminer, report.netcraft, report.metamask, report.openphish]
threads = []

for i in todo:
Expand Down Expand Up @@ -49,7 +68,7 @@ def search():
results = create_report(f"https://{url}/", is_domain=True)
else:
results = create_report(url)

return render_template("search.html", results=results, domain=results[0], information=results[1], records=results[2])
else:
return "Invalid search query"
Expand All @@ -68,5 +87,5 @@ def exportcsv():
return send_file(mem, download_name="report.csv", mimetype="text/csv", as_attachment=True)

if __name__ == "__main__":
webbrowser.open("http://127.0.0.1:9000/", new=2)
app.run(host="127.0.0.1", port=9000)
webbrowser.open("http://localhost:9000/", new=2)
app.run(host="localhost", port=9000)
6 changes: 6 additions & 0 deletions modules/metamask.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import requests

def metamask_list(domain: str) -> bool:
r = requests.get("https://raw.githubusercontent.com/MetaMask/eth-phishing-detect/refs/heads/main/src/config.json")

return domain in r.json()["blacklist"]
1 change: 1 addition & 0 deletions modules/netcraft.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def netcraft_submit(url: str):
}

r = requests.post("https://report.netcraft.com/api/v3/report/urls", json=data)

if r.status_code == 200:
return r.json()["uuid"]
if r.status_code == 400:
Expand Down
6 changes: 6 additions & 0 deletions modules/openphish.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import requests

def openphish_list(domain: str) -> bool:
r = requests.get("https://raw.githubusercontent.com/openphish/public_feed/refs/heads/main/feed.txt")

return domain in r.text
1 change: 1 addition & 0 deletions modules/tranco.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

def domain_raiting(domain: str) -> int:
r = requests.get(f"https://tranco-list.eu/api/ranks/domain/{domain}")

if r.status_code == 200:
if len(r.json()["ranks"]) > 0:
rank = r.json()["ranks"][-1:][0]["rank"]
Expand Down
5 changes: 3 additions & 2 deletions modules/urlscan.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import requests
import json
import time

class DnsError(Exception):
Expand All @@ -15,8 +14,10 @@ def __init__(self, api_key: str):
}

def submit_url(self, url: str):
data = {"url": url, "visibility": "public", "tags": ["Ice Storm"]}
data = {"url": url, "visibility": "public", "tags": ["Ice_Storm ToolKit"]}

r = requests.post("https://urlscan.io/api/v1/scan/", headers=self.headers, json=data)

if r.status_code == 200:
self.api_results = r.json()["api"]
elif r.status_code == 400:
Expand Down
15 changes: 13 additions & 2 deletions static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ main.search {
flex-wrap: wrap;
gap: 25px;
margin-top: 20px;
width: 98%;
height: 98%;
}

.block {
Expand Down Expand Up @@ -171,6 +169,19 @@ main.search {
overflow: hidden;
}

.inline {
display: flex;
justify-content: space-around;
gap: 0.4rem;
}

.inline > h2 {
width: 100%;
padding: 0.5rem;
text-align: center;
border-radius: 15px;
}

.abuse-btn {
padding: 10px;
text-align: center;
Expand Down
28 changes: 19 additions & 9 deletions templates/search.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>REPORT / ICE STORM</title>
<title>Report / ICE STORM</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

Expand All @@ -23,33 +23,43 @@ <h1 class="projectname">ICE STORM</h1>
<div id="information" class="block">
{% for info in information %}
{% if "|reportmail" in info %}
<a class="abuse-btn" href="mailto:{{ info.replace("|reportmail", "") }}?subject=Phishing site: {{ domain.replace(".", "[.]") }}&amp;body=To whom it may concern,%0A%0AThe following website recently came to my attention: hxxps://{{ domain.replace(".", "[.]") }}%0A%0ADespite what it is pretending, this is a phishing site and not the official website.%0A%0AYou are providing services to the people operating the Website while it is very obviously being used for fraud.%0AI'm writing to request that you take it down as soon as possible%0A%0AYours faithfully." target="_blank"><h2>report | {{ info.replace("|reportmail", "") }}</h2></a>
<a class="abuse-btn" href="mailto:{{ info.replace("|reportmail", "") }}?subject=Phishing site: {{ domain.replace(".", "[.]") }}&amp;body=To whom it may concern,%0A%0AThe following website recently came to my attention: hxxps://{{ domain.replace(".", "[.]") }}%0A%0ADespite what it is pretending, this is a phishing site and not the official website.%0A%0AYou are providing services to the people operating the Website while it is very obviously being used for fraud.%0AI'm writing to request that you take it down as soon as possible%0A%0AYours faithfully." target="_blank"><h2>report | {{ info.replace("|reportmail", "") }}</h2></a>
{% elif "|img" in info %}
<img src="{{ info.replace("|img", "") }}">
<img src="{{ info.replace("|img", "") }}">
{% else %}
<h2>{{ info }}</h2>
<h2>{{ info }}</h2>
{% endif %}
{% endfor %}
</div>
<div class="results">
{% for record in records %}
<div class="block">
<h2 class="title">{{ record }}</h2>
{% if record in ["VirusTotal", "MetaDefender"] %}
<div class="inline">
{% endif %}
{% for i in records[record] %}
{% if "|clear" in i %}
<h2 class="clear">{{ i.replace("|clear", "") }}</h2>
<h2 class="clear">{{ i.replace("|clear", "") }}</h2>
{% elif "|suspicious" in i %}
<h2 class="suspicious">{{ i.replace("|suspicious", "") }}</h2>
<h2 class="suspicious">{{ i.replace("|suspicious", "") }}</h2>
{% elif "|malicious" in i %}
<h2 class="malicious">{{ i.replace("|malicious", "") }}</h2>
<h2 class="malicious">{{ i.replace("|malicious", "") }}</h2>
{% elif "|reportlink" in i %}
<a class="abuse-btn" href="{{ i.replace("|reportlink", "") }}" target="_blank"><h2>report</h2></a>
<a class="abuse-btn" href="{{ i.replace("|reportlink", "") }}" target="_blank"><h2>report</h2></a>
{% else %}
<h2>{{ i }}</h2>
<h2>{{ i }}</h2>
{% endif %}
{% endfor %}
{% if record in ["VirusTotal", "MetaDefender"] %}
</div>
{% endif %}
</div>
{% endfor %}
<div class="block">
<h2 class="title">ICANN Compliance</h2>
<a class="abuse-btn" href="https://icann-nsp.my.site.com/compliance/s/abuse-domain" target="_blank"><h2>report</h2></a>
</div>
</div>
</main>
</body>
Expand Down

0 comments on commit 32b8ca0

Please sign in to comment.