th1enq commited on
Commit
22dafaa
·
verified ·
1 Parent(s): 07693f5

Upload URLFeatureExtraction.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. URLFeatureExtraction.py +382 -0
URLFeatureExtraction.py ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # importing required packages for this section
4
+ from urllib.parse import urlparse,urlencode
5
+ import ipaddress
6
+ import re
7
+
8
+ """#### **3.1.1. Domain of the URL**
9
+ Here, we are just extracting the domain present in the URL. This feature doesn't have much significance in the training. May even be dropped while training the model.
10
+ """
11
+ '''
12
+ # 1.Domain of the URL (Domain)
13
+ def getDomain(url):
14
+ domain = urlparse(url).netloc
15
+ if re.match(r"^www.",domain):
16
+ domain = domain.replace("www.","")
17
+ return domain'''
18
+
19
+ """#### **3.1.2. IP Address in the URL**
20
+
21
+ Checks for the presence of IP address in the URL. URLs may have IP address instead of domain name. If an IP address is used as an alternative of the domain name in the URL, we can be sure that someone is trying to steal personal information with this URL.
22
+
23
+ If the domain part of URL has IP address, the value assigned to this feature is 1 (phishing) or else 0 (legitimate).
24
+ """
25
+
26
+ # 2.Checks for IP address in URL (Have_IP)
27
+ def havingIP(url):
28
+ try:
29
+ ipaddress.ip_address(url)
30
+ ip = 1
31
+ except:
32
+ ip = 0
33
+ return ip
34
+
35
+ """#### **3.1.3. "@" Symbol in URL**
36
+
37
+ Checks for the presence of '@' symbol in the URL. Using “@” symbol in the URL leads the browser to ignore everything preceding the “@” symbol and the real address often follows the “@” symbol.
38
+
39
+ If the URL has '@' symbol, the value assigned to this feature is 1 (phishing) or else 0 (legitimate).
40
+ """
41
+
42
+ # 3.Checks the presence of @ in URL (Have_At)
43
+ def haveAtSign(url):
44
+ if "@" in url:
45
+ at = 1
46
+ else:
47
+ at = 0
48
+ return at
49
+
50
+ """#### **3.1.4. Length of URL**
51
+
52
+ Computes the length of the URL. Phishers can use long URL to hide the doubtful part in the address bar. In this project, if the length of the URL is greater than or equal 54 characters then the URL classified as phishing otherwise legitimate.
53
+
54
+ If the length of URL >= 54 , the value assigned to this feature is 1 (phishing) or else 0 (legitimate).
55
+ """
56
+
57
+ # 4.Finding the length of URL and categorizing (URL_Length)
58
+ def getLength(url):
59
+ if len(url) < 54:
60
+ length = 0
61
+ else:
62
+ length = 1
63
+ return length
64
+
65
+ """#### **3.1.5. Depth of URL**
66
+
67
+ Computes the depth of the URL. This feature calculates the number of sub pages in the given url based on the '/'.
68
+
69
+ The value of feature is a numerical based on the URL.
70
+ """
71
+
72
+ # 5.Gives number of '/' in URL (URL_Depth)
73
+ def getDepth(url):
74
+ s = urlparse(url).path.split('/')
75
+ depth = 0
76
+ for j in range(len(s)):
77
+ if len(s[j]) != 0:
78
+ depth = depth+1
79
+ return depth
80
+
81
+ """#### **3.1.6. Redirection "//" in URL**
82
+
83
+ Checks the presence of "//" in the URL. The existence of “//” within the URL path means that the user will be redirected to another website. The location of the “//” in URL is computed. We find that if the URL starts with “HTTP”, that means the “//” should appear in the sixth position. However, if the URL employs “HTTPS” then the “//” should appear in seventh position.
84
+
85
+ If the "//" is anywhere in the URL apart from after the protocal, thee value assigned to this feature is 1 (phishing) or else 0 (legitimate).
86
+ """
87
+
88
+ # 6.Checking for redirection '//' in the url (Redirection)
89
+ def redirection(url):
90
+ pos = url.rfind('//')
91
+ if pos > 6:
92
+ if pos > 7:
93
+ return 1
94
+ else:
95
+ return 0
96
+ else:
97
+ return 0
98
+
99
+ """#### **3.1.7. "http/https" in Domain name**
100
+
101
+ Checks for the presence of "http/https" in the domain part of the URL. The phishers may add the “HTTPS” token to the domain part of a URL in order to trick users.
102
+
103
+ If the URL has "http/https" in the domain part, the value assigned to this feature is 1 (phishing) or else 0 (legitimate).
104
+ """
105
+
106
+ # 7.Existence of “HTTPS” Token in the Domain Part of the URL (https_Domain)
107
+ def httpDomain(url):
108
+ domain = urlparse(url).netloc
109
+ if 'https' in domain:
110
+ return 1
111
+ else:
112
+ return 0
113
+
114
+ """#### **3.1.8. Using URL Shortening Services “TinyURL”**
115
+
116
+ URL shortening is a method on the “World Wide Web” in which a URL may be made considerably smaller in length and still lead to the required webpage. This is accomplished by means of an “HTTP Redirect” on a domain name that is short, which links to the webpage that has a long URL.
117
+
118
+ If the URL is using Shortening Services, the value assigned to this feature is 1 (phishing) or else 0 (legitimate).
119
+ """
120
+
121
+ #listing shortening services
122
+ shortening_services = r"bit\.ly|goo\.gl|shorte\.st|go2l\.ink|x\.co|ow\.ly|t\.co|tinyurl|tr\.im|is\.gd|cli\.gs|" \
123
+ r"yfrog\.com|migre\.me|ff\.im|tiny\.cc|url4\.eu|twit\.ac|su\.pr|twurl\.nl|snipurl\.com|" \
124
+ r"short\.to|BudURL\.com|ping\.fm|post\.ly|Just\.as|bkite\.com|snipr\.com|fic\.kr|loopt\.us|" \
125
+ r"doiop\.com|short\.ie|kl\.am|wp\.me|rubyurl\.com|om\.ly|to\.ly|bit\.do|t\.co|lnkd\.in|db\.tt|" \
126
+ r"qr\.ae|adf\.ly|goo\.gl|bitly\.com|cur\.lv|tinyurl\.com|ow\.ly|bit\.ly|ity\.im|q\.gs|is\.gd|" \
127
+ r"po\.st|bc\.vc|twitthis\.com|u\.to|j\.mp|buzurl\.com|cutt\.us|u\.bb|yourls\.org|x\.co|" \
128
+ r"prettylinkpro\.com|scrnch\.me|filoops\.info|vzturl\.com|qr\.net|1url\.com|tweez\.me|v\.gd|" \
129
+ r"tr\.im|link\.zip\.net"
130
+
131
+ # 8. Checking for Shortening Services in URL (Tiny_URL)
132
+ def tinyURL(url):
133
+ match=re.search(shortening_services,url)
134
+ if match:
135
+ return 1
136
+ else:
137
+ return 0
138
+
139
+ """#### **3.1.9. Prefix or Suffix "-" in Domain**
140
+
141
+ Checking the presence of '-' in the domain part of URL. The dash symbol is rarely used in legitimate URLs. Phishers tend to add prefixes or suffixes separated by (-) to the domain name so that users feel that they are dealing with a legitimate webpage.
142
+
143
+ If the URL has '-' symbol in the domain part of the URL, the value assigned to this feature is 1 (phishing) or else 0 (legitimate).
144
+ """
145
+
146
+ # 9.Checking for Prefix or Suffix Separated by (-) in the Domain (Prefix/Suffix)
147
+ def prefixSuffix(url):
148
+ if '-' in urlparse(url).netloc:
149
+ return 1 # phishing
150
+ else:
151
+ return 0 # legitimate
152
+
153
+ """### **3.2. Domain Based Features:**
154
+
155
+ Many features can be extracted that come under this category. Out of them, below mentioned were considered for this project.
156
+
157
+ * DNS Record
158
+ * Website Traffic
159
+ * Age of Domain
160
+ * End Period of Domain
161
+
162
+ Each of these features are explained and the coded below:
163
+ """
164
+
165
+ #!pip install python-whois
166
+
167
+ # importing required packages for this section
168
+ import re
169
+ from bs4 import BeautifulSoup
170
+ #import whois
171
+ import urllib
172
+ import urllib.request
173
+ from datetime import datetime
174
+
175
+ """#### **3.2.1. DNS Record**
176
+
177
+ For phishing websites, either the claimed identity is not recognized by the WHOIS database or no records founded for the hostname.
178
+ If the DNS record is empty or not found then, the value assigned to this feature is 1 (phishing) or else 0 (legitimate).
179
+ """
180
+
181
+ # 11.DNS Record availability (DNS_Record)
182
+ # obtained in the featureExtraction function itself
183
+
184
+ """#### **3.2.2. Web Traffic**
185
+
186
+ This feature measures the popularity of the website by determining the number of visitors and the number of pages they visit. However, since phishing websites live for a short period of time, they may not be recognized by the Alexa database (Alexa the Web Information Company., 1996). By reviewing our dataset, we find that in worst scenarios, legitimate websites ranked among the top 100,000. Furthermore, if the domain has no traffic or is not recognized by the Alexa database, it is classified as “Phishing”.
187
+
188
+ If the rank of the domain < 100000, the vlaue of this feature is 1 (phishing) else 0 (legitimate).
189
+ """
190
+
191
+ # 12.Web traffic (Web_Traffic)
192
+ def web_traffic(url):
193
+ try:
194
+ #Filling the whitespaces in the URL if any
195
+ url = urllib.parse.quote(url)
196
+ rank = BeautifulSoup(urllib.request.urlopen("http://data.alexa.com/data?cli=10&dat=s&url=" + url).read(), "xml").find(
197
+ "REACH")['RANK']
198
+ rank = int(rank)
199
+ except TypeError:
200
+ return 1
201
+ if rank <100000:
202
+ return 1
203
+ else:
204
+ return 0
205
+
206
+ """#### **3.2.3. Age of Domain**
207
+
208
+ This feature can be extracted from WHOIS database. Most phishing websites live for a short period of time. The minimum age of the legitimate domain is considered to be 12 months for this project. Age here is nothing but different between creation and expiration time.
209
+
210
+ If age of domain > 12 months, the vlaue of this feature is 1 (phishing) else 0 (legitimate).
211
+ """
212
+
213
+ # 13.Survival time of domain: The difference between termination time and creation time (Domain_Age)
214
+ def domainAge(domain_name):
215
+ creation_date = domain_name.creation_date
216
+ expiration_date = domain_name.expiration_date
217
+ if (isinstance(creation_date,str) or isinstance(expiration_date,str)):
218
+ try:
219
+ creation_date = datetime.strptime(creation_date,'%Y-%m-%d')
220
+ expiration_date = datetime.strptime(expiration_date,"%Y-%m-%d")
221
+ except:
222
+ return 1
223
+ if ((expiration_date is None) or (creation_date is None)):
224
+ return 1
225
+ elif ((type(expiration_date) is list) or (type(creation_date) is list)):
226
+ return 1
227
+ else:
228
+ ageofdomain = abs((expiration_date - creation_date).days)
229
+ if ((ageofdomain/30) < 6):
230
+ age = 1
231
+ else:
232
+ age = 0
233
+ return age
234
+
235
+ """#### **3.2.4. End Period of Domain**
236
+
237
+ This feature can be extracted from WHOIS database. For this feature, the remaining domain time is calculated by finding the different between expiration time & current time. The end period considered for the legitimate domain is 6 months or less for this project.
238
+
239
+ If end period of domain > 6 months, the vlaue of this feature is 1 (phishing) else 0 (legitimate).
240
+ """
241
+
242
+ # 14.End time of domain: The difference between termination time and current time (Domain_End)
243
+ def domainEnd(domain_name):
244
+ expiration_date = domain_name.expiration_date
245
+ if isinstance(expiration_date,str):
246
+ try:
247
+ expiration_date = datetime.strptime(expiration_date,"%Y-%m-%d")
248
+ except:
249
+ return 1
250
+ if (expiration_date is None):
251
+ return 1
252
+ elif (type(expiration_date) is list):
253
+ return 1
254
+ else:
255
+ today = datetime.now()
256
+ end = abs((expiration_date - today).days)
257
+ if ((end/30) < 6):
258
+ end = 0
259
+ else:
260
+ end = 1
261
+ return end
262
+
263
+ """## **3.3. HTML and JavaScript based Features**
264
+
265
+ Many features can be extracted that come under this category. Out of them, below mentioned were considered for this project.
266
+
267
+ * IFrame Redirection
268
+ * Status Bar Customization
269
+ * Disabling Right Click
270
+ * Website Forwarding
271
+
272
+ Each of these features are explained and the coded below:
273
+ """
274
+
275
+ # importing required packages for this section
276
+ import requests
277
+
278
+ """### **3.3.1. IFrame Redirection**
279
+
280
+ IFrame is an HTML tag used to display an additional webpage into one that is currently shown. Phishers can make use of the “iframe” tag and make it invisible i.e. without frame borders. In this regard, phishers make use of the “frameBorder” attribute which causes the browser to render a visual delineation.
281
+
282
+ If the iframe is empty or repsonse is not found then, the value assigned to this feature is 1 (phishing) or else 0 (legitimate).
283
+ """
284
+
285
+ # 15. IFrame Redirection (iFrame)
286
+ def iframe(response):
287
+ if response == "":
288
+ return 1
289
+ else:
290
+ if re.findall(r"[<iframe>|<frameBorder>]", response.text):
291
+ return 0
292
+ else:
293
+ return 1
294
+
295
+ """### **3.3.2. Status Bar Customization**
296
+
297
+ Phishers may use JavaScript to show a fake URL in the status bar to users. To extract this feature, we must dig-out the webpage source code, particularly the “onMouseOver” event, and check if it makes any changes on the status bar
298
+
299
+ If the response is empty or onmouseover is found then, the value assigned to this feature is 1 (phishing) or else 0 (legitimate).
300
+ """
301
+
302
+ # 16.Checks the effect of mouse over on status bar (Mouse_Over)
303
+ def mouseOver(response):
304
+ if response == "" :
305
+ return 1
306
+ else:
307
+ if re.findall("<script>.+onmouseover.+</script>", response.text):
308
+ return 1
309
+ else:
310
+ return 0
311
+
312
+ """### **3.3.3. Disabling Right Click**
313
+
314
+ Phishers use JavaScript to disable the right-click function, so that users cannot view and save the webpage source code. This feature is treated exactly as “Using onMouseOver to hide the Link”. Nonetheless, for this feature, we will search for event “event.button==2” in the webpage source code and check if the right click is disabled.
315
+
316
+ If the response is empty or onmouseover is not found then, the value assigned to this feature is 1 (phishing) or else 0 (legitimate).
317
+ """
318
+
319
+ # 17.Checks the status of the right click attribute (Right_Click)
320
+ def rightClick(response):
321
+ if response == "":
322
+ return 1
323
+ else:
324
+ if re.findall(r"event.button ?== ?2", response.text):
325
+ return 0
326
+ else:
327
+ return 1
328
+
329
+ """### **3.3.4. Website Forwarding**
330
+ The fine line that distinguishes phishing websites from legitimate ones is how many times a website has been redirected. In our dataset, we find that legitimate websites have been redirected one time max. On the other hand, phishing websites containing this feature have been redirected at least 4 times.
331
+ """
332
+
333
+ # 18.Checks the number of forwardings (Web_Forwards)
334
+ def forwarding(response):
335
+ if response == "":
336
+ return 1
337
+ else:
338
+ if len(response.history) <= 2:
339
+ return 0
340
+ else:
341
+ return 1
342
+
343
+ """## **4. Computing URL Features**
344
+
345
+ Create a list and a function that calls the other functions and stores all the features of the URL in the list. We will extract the features of each URL and append to this list.
346
+ """
347
+
348
+ #Function to extract features
349
+ def featureExtraction(url):
350
+
351
+ features = []
352
+ #Address bar based features (10)
353
+ #features.append(getDomain(url))
354
+ features.append(havingIP(url))
355
+ features.append(haveAtSign(url))
356
+ features.append(getLength(url))
357
+ features.append(getDepth(url))
358
+ features.append(redirection(url))
359
+ features.append(httpDomain(url))
360
+ features.append(tinyURL(url))
361
+ features.append(prefixSuffix(url))
362
+
363
+ # #Domain based features (4)
364
+ # dns = 0
365
+ # try:
366
+ # domain_name = whois.whois(urlparse(url).netloc)
367
+ # except:
368
+ # dns = 1
369
+
370
+ # features.append(dns)
371
+ # features.append(web_traffic(url))
372
+ # features.append(1 if dns == 1 else domainAge(domain_name))
373
+ # features.append(1 if dns == 1 else domainEnd(domain_name))
374
+
375
+
376
+
377
+ return features
378
+
379
+ #converting the list to dataframe
380
+ feature_names = ['Domain', 'Have_IP', 'Have_At', 'URL_Length', 'URL_Depth','Redirection',
381
+ 'https_Domain', 'TinyURL', 'Prefix/Suffix', 'Label']
382
+