quantum-drive commited on
Commit
700e294
·
verified ·
1 Parent(s): 4cab62a

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +171 -0
app.py ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import joblib
3
+ import pandas as pd
4
+ import numpy as np
5
+ import re
6
+ import string
7
+ import socket
8
+ import ssl
9
+ import whois
10
+ import dns.resolver
11
+ from urllib.parse import urlparse
12
+ from datetime import datetime
13
+ from sklearn.preprocessing import LabelEncoder
14
+ from sklearn.linear_model import LogisticRegression
15
+
16
+ # Load correct models
17
+ phishing_model = joblib.load("phishing_stack.pkl")
18
+ malware_model = joblib.load("new_malware_stack.pkl")
19
+
20
+
21
+ # Feature extraction for both phishing and malware
22
+ def extract_features(url):
23
+ extracted = tldextract.extract(url)
24
+ domain = f"{extracted.domain}.{extracted.suffix}"
25
+ hostname = extracted.domain
26
+ scheme = "https" if url.startswith("https") else "http"
27
+
28
+ try:
29
+ ip_address = socket.gethostbyname(domain)
30
+ has_ip = 1
31
+ except:
32
+ ip_address = ''
33
+ has_ip = 0
34
+
35
+ features = {
36
+ "url_length": len(url),
37
+ "hostname_length": len(hostname),
38
+ "num_dots": url.count("."),
39
+ "num_hyphens": url.count("-"),
40
+ "num_digits": sum(char.isdigit() for char in url),
41
+ "num_special_chars": len(re.findall(r"[!@#$%^&*()_+=\[\]{};':\"\\|,.<>\/?]", url)),
42
+ "has_ip_address": has_ip,
43
+ "has_https": scheme == "https",
44
+ "has_suspicious_words": int(bool(re.search(r"(login|verify|bank|account|update|secure)", url, re.IGNORECASE))),
45
+ "is_shortened": int(bool(re.search(r"(bit\.ly|goo\.gl|tinyurl\.com|t\.co|ow\.ly)", url))),
46
+ "tld": extracted.suffix
47
+ }
48
+
49
+ # Additional features for malware
50
+ try:
51
+ whois_info = whois.whois(domain)
52
+ features["domain_age_days"] = (
53
+ (whois_info.expiration_date - whois_info.creation_date).days
54
+ if whois_info.expiration_date and whois_info.creation_date
55
+ else -1
56
+ )
57
+ features["domain_expiry_days"] = (
58
+ (whois_info.expiration_date - whois_info.updated_date).days
59
+ if whois_info.expiration_date and whois_info.updated_date
60
+ else -1
61
+ )
62
+ except:
63
+ features["domain_age_days"] = -1
64
+ features["domain_expiry_days"] = -1
65
+
66
+ try:
67
+ response = requests.get(url, timeout=5)
68
+ features["dns_ttl"] = response.elapsed.microseconds // 1000
69
+ except:
70
+ features["dns_ttl"] = -1
71
+
72
+ try:
73
+ ctx = ssl.create_default_context()
74
+ with ctx.wrap_socket(socket.socket(), server_hostname=domain) as s:
75
+ s.settimeout(5)
76
+ s.connect((domain, 443))
77
+ cert = s.getpeercert()
78
+ features["ssl_issuer"] = cert.get("issuer", [("N/A", "")])[0][0]
79
+ features["ssl_valid"] = True
80
+ except:
81
+ features["ssl_issuer"] = "Unknown"
82
+ features["ssl_valid"] = False
83
+
84
+ features["has_suspicious_keyword"] = features["has_suspicious_words"]
85
+ features["is_https"] = features["has_https"]
86
+
87
+ return features
88
+
89
+
90
+ def classify_url(url):
91
+ features = extract_features(url)
92
+
93
+ phishing_input = [
94
+ features["url_length"],
95
+ features["hostname_length"],
96
+ features["num_dots"],
97
+ features["num_hyphens"],
98
+ features["num_digits"],
99
+ features["num_special_chars"],
100
+ features["has_ip_address"],
101
+ features["has_https"],
102
+ features["has_suspicious_words"],
103
+ features["is_shortened"],
104
+ features["tld"]
105
+ ]
106
+
107
+ malware_input = [
108
+ features["url_length"],
109
+ features["hostname_length"],
110
+ features["num_dots"],
111
+ features["num_hyphens"],
112
+ features["num_digits"],
113
+ features["num_special_chars"],
114
+ features["has_suspicious_keyword"],
115
+ features["has_ip_address"],
116
+ features["is_https"],
117
+ features["is_shortened"],
118
+ features["tld"],
119
+ features["domain_age_days"],
120
+ features["domain_expiry_days"],
121
+ features["dns_ttl"],
122
+ features["ssl_issuer"],
123
+ features["ssl_valid"]
124
+ ]
125
+
126
+ phishing_pred = phishing_model.predict([phishing_input])[0]
127
+ phishing_proba = phishing_model.predict_proba([phishing_input])[0].max()
128
+
129
+ malware_pred = malware_model.predict([malware_input])[0]
130
+ malware_proba = malware_model.predict_proba([malware_input])[0].max()
131
+
132
+ final_result = (
133
+ "Phishing" if phishing_pred == "Phishing" else
134
+ "Malware" if malware_pred == "malicious" else
135
+ "Benign"
136
+ )
137
+
138
+ return {
139
+ "url": url,
140
+ "final_result": final_result,
141
+ "phishing": {
142
+ "prediction": phishing_pred,
143
+ "confidence": phishing_proba,
144
+ "features": dict(zip([
145
+ "url_length", "hostname_length", "num_dots", "num_hyphens", "num_digits",
146
+ "num_special_chars", "has_ip_address", "has_https", "has_suspicious_words",
147
+ "is_shortened", "tld"
148
+ ], phishing_input))
149
+ },
150
+ "malware": {
151
+ "prediction": malware_pred,
152
+ "confidence": malware_proba,
153
+ "features": dict(zip([
154
+ "url_length", "hostname_length", "num_dots", "num_hyphens", "num_digits",
155
+ "num_special_chars", "has_suspicious_keyword", "has_ip_address", "is_https",
156
+ "is_shortened", "tld", "domain_age_days", "domain_expiry_days", "dns_ttl",
157
+ "ssl_issuer", "ssl_valid"
158
+ ], malware_input))
159
+ }
160
+ }
161
+
162
+
163
+ with gr.Blocks() as demo:
164
+ gr.Markdown("## 🔐 URL Threat Detection - Phishing & Malware")
165
+ with gr.Row():
166
+ url_input = gr.Textbox(label="Enter URL", placeholder="https://example.com", lines=1)
167
+ output = gr.JSON(label="Prediction Results")
168
+ submit_btn = gr.Button("Check URL")
169
+ submit_btn.click(fn=classify_url, inputs=[url_input], outputs=[output])
170
+
171
+ demo.launch()