Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # coding: utf-8
- # UAtester
- #
- # Chris John Riley
- # blog.c22.cc
- # contact [AT] c22 [DOT] cc
- # 26/09/2010
- # Version: 1.06 BETA
- #
- # Changelog
- # 0.1 --> Initial version
- # 0.2 --> Improved redirect handling
- # 0.3 --> ASCII-ART for the WIN!
- # 0.4 --> Output formatting (Still not happy with this)
- # 0.5 --> Released for limited Alpha testing
- # 0.6 --> Changed handling of default UA strings (no need for -d), added verbose output, single mode -s, handler for URL without HTTP://
- # 0.7 --> Added Android default UA string, altered -h to reflect changes to usage
- # 0.8 --> Expanded on user feedback to avoid confusion of results, added feedback to clarify results, expanded default user agent strings (categorized)
- # 0.81 --> Added TRY to handle ctrl-c quits
- # 0.84 --> Redo response header comparison to cover full return headers, [[35;40m+[0m] Added Headers, [[35;40m-[0m] Removed Headers, [[35;40m![0m] Altered Headers
- # 0.9 --> Added Set-Cookie comparison, Full headers
- # 0.93 --> Added ability to select type of default UAstrings to use -d/--default --> BETA
- # 0.94 --> Bug fixes and code consilidation. Increase Verbose feedback. Correct issues raised in BETA testing
- # 0.95 --> Cookie comparison
- # 0.98 --> Completed Secure and HTTPonly Cookie checks, added new browser UAstrings and Dangerous UA strings -d X
- # --> Added formatting changes to correct line wraps on long UA Strings, URLS, etc...
- # --> Updated positioning and minor tweaks to remove unused debug code
- # 1.00 --> BruCON release... Codename Purple Pimp
- # 1.01 --> Minor display bug-fix (verbose mode only)
- # 1.02 --> Corrected TextWrap configuration to make Python 2.5.x compatible (removed break_on_hyphens)
- # 1.03 --> Altered path to interpreter, corrected --help
- # 1.04 --> Added file output CSV format - Simple output, requires manual sorting to match removed, added headers
- # 1.05 --> Corrected minor display issues with blank UA strings
- # 1.06 --> Minor file handling correction....
- import httplib
- import hashlib
- import urllib
- import urllib2
- import getopt
- import sys
- import re
- import time
- import socket
- import csv
- import string
- import os
- from textwrap import *
- socket.setdefaulttimeout(15)
- rechecktime = 2 # Alter this value to increase of decrease the delay between initial stability checks (default:2)
- rechecks = 3 # Alter this value to decrease the number of stable checks (default/max:3)
- debug = 0
- err = 0
- err_2 = 0
- uafilepresent = False
- csvfilepresent = False
- single = False
- verbose = False
- uafile = False
- csvfile = False
- default = False
- default_options = False
- default_opts = 0
- cookie_names_ref = []
- cookie_names_ua = []
- cookie_full_ref = []
- cookie_full_ua = []
- logo = '''
- _/ _/ _/_/_/_/ _/_/_/_/ _/_/_/_/ _/_/_/_/ _/_/_/_/ _/_/_/_/ _/_/_/_/
- _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/
- _/ _/ _/_/_/_/ _/_/_/ _/ _/_/_/ _/_/_/_/ _/ _/_/_/ _/_/_/_
- _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/
- _/_/_/_/ _/ _/ _/ _/_/_/_/ _/_/_/_/ _/ _/_/_/_/ _/ _/ [\x1B[35;40mv1.06\x1B[0m]
- _/ User-Agent Tester \x1B[35;40m↵\x1B[0m
- _/ AKA: \x1B[35;40mPurple Pimp\x1B[0m ↵
- _/ ChrisJohnRiley \x1B[35;40m↵\x1B[0m
- _/ blog.c22.cc \x1B[35;40m↵\x1B[0m\n'''
- usage = '''
- This tool is designed to automatically check a given URL using a list of standard and non-
- standard User Agent strings provided by the user (1 per line).
- The results of these checks are then reported to the user for further manual analysis where
- required. Gathered data includes Response Codes, resulting URL in the case of a 30x response,
- MD5 and length of response body, and select Server headers.
- Results: When in non-verbose mode, only values that do not match the initial reference connection
- are reported to the user. If no results are shown for a specific useragent then all results match
- the initial reference connection. If you require a full output of all checks regardless of matches
- to the reference, please use the verbose setting.
- Output: [\x1B[35;40m+\x1B[0m] Added Headers, [\x1B[35;40m-\x1B[0m] Removed Headers, [\x1B[35;40m!\x1B[0m] Altered Headers, [ ] No Change
- Usage .:
- -u / --url Complete URL
- -f / --file <Path to User Agent file> / If no file is provided, -d options must be present
- -s / --single provide single user-agent string (may need to be contained within quotes)
- -d / --default Select the UA String type(s) to check. Select 1 or more of the following \x1B[35;40m↵\x1B[0m
- catagories. (\x1B[31;40mM\x1B[0m)obile, (\x1B[31;40mD\x1B[0m)esktop, mis(\x1B[31;40mC\x1B[0m), (\x1B[31;40mT\x1B[0m)ools, (\x1B[31;40mB\x1B[0m)ots, e(\x1B[31;40mX\x1B[0m)treme [\x1B[35;40m!\x1B[0m])
- -o / --output <Path to output file> CSV formated output (FILE WILL BE OVERWRITTEN[\x1B[31;40m!\x1B[0m])
- -v / --verbose results (Displays full headers for each check) >> Recommended
- --debug See debug messages (This isn't the switch you're looking for)\n
- Example .:
- ./UATester.py -u www.example.com -f ./useragentlist.txt -v
- ./UATester.py -u https://www.wordpress.com
- ./UATester.py -u http://www.defaultserver.com -v --debug
- ./UATester.py -u facebook.com -v -d MDBX
- ./UATester.py -u https://www.google.com -s "MySpecialUserAgent"
- ./UATester.py -u blog.c22.cc -d MC -o ./output.csv\n'''
- def main():
- try:
- global err
- global err_2
- global default
- global verbose
- global TextWrapper
- # Setup Text Wrappers to make output uniformed
- REFWRAP = TextWrapper(replace_whitespace=False, width=110, initial_indent=" [ ] ", subsequent_indent=" ")
- TXTWRAP = TextWrapper(replace_whitespace=False, width=110, subsequent_indent=" ")
- PLUSWRAP = TextWrapper(replace_whitespace=False, width=110, initial_indent=" [[35;40m+[0m] ", subsequent_indent=" ")
- MINUSWRAP = TextWrapper(replace_whitespace=False, width=110, initial_indent=" [[35;40m-[0m] ", subsequent_indent=" ")
- UAWRAP = TextWrapper(replace_whitespace=False, width=110, initial_indent="\n\n [>] User-Agent String : ", subsequent_indent=" ")
- if verbose == True: print " [[31;40m*[0m] Running in Verbose mode\n"
- if debug == 1: print " [[31;40m*[0m] Running in Debug mode.... God help you!\n"
- #uastring = 'Nokia7650/1.0 Symbian-QP/6.1 Nokia/2.1' # UAstring used for testing configuration
- uastring = 'Mozilla/5.0' # UAstring used for initial checks
- print " [>] Performing initial request and confirming stability\n",
- print " [>] Using User-Agent string", uastring, '\n'
- if csvfilepresent == True:
- if os.path.exists(csvfile):
- print " [[31;40m![0m] Output file already exists!\n"
- exit()
- try:
- csvoutputfile_handle = open(csvfile, 'w') # Set output CSV file
- csvoutputfile = csv.writer(csvoutputfile_handle, dialect='excel')
- except:
- print"\n [[35;40m![0m] Failed to open/create the output file specified. ", err
- print"\n [!| Thanks for coming.. bye!"
- exit()
- opener = urllib2.build_opener(SmartRedirectHandler())
- req = urllib2.Request(url)
- req.add_header('User-agent', uastring)
- try: resp = opener.open(req)
- except socket.timeout, err:
- print " [[31;40m*[0m] Socket Timeout: ", err
- except socket.error,err_2:
- print " [[31;40m*[0m] Socket Error: ", err
- except urllib2.HTTPError, err:
- print " [[31;40m*[0m] HTTPError: ", err
- except urllib2.URLError, err:
- print " [[31;40m*[0m] URLError: ", err
- except ValueError, err:
- print " [[31;40m*[0m] ValueError: ", err, "\n"
- if err: exit();
- try: ref_resp_statuscode = resp.status
- except AttributeError, err:
- ref_resp_statuscode = resp.code, resp.msg
- print ' [ ] URL (ENTERED):', url
- ref_url = resp.geturl()
- if url != resp.geturl():
- print ' [[35;40m![0m] URL (FINAL):',
- for line in TXTWRAP.wrap(resp.geturl()): print line
- if url != resp.geturl(): print ' [[35;40m![0m] Response Code:', ref_resp_statuscode[0], ref_resp_statuscode[1]
- else: print ' [ ] Response Code:', ref_resp_statuscode[0], ref_resp_statuscode[1]
- ref_headers = resp.info()
- ref_headers_len = len(str(ref_headers).split('\n')) -1
- ref_data = resp.read()
- ref_md5 = hashlib.md5(ref_data)
- if csvfilepresent == True:
- csvform = map(string.strip, ref_headers.headers)
- csvform.insert(0, ref_resp_statuscode)
- csvform.insert(0, resp.geturl())
- csvform.insert(0, uastring)
- csvform.append(ref_md5.hexdigest())
- csvoutputfile.writerow(csvform)
- if debug == 1: print resp.info()
- i = 0
- while i < ref_headers_len:
- for line in REFWRAP.wrap(ref_headers.headers[i]): print line
- i=i+1
- print ' [ ] Data (MD5):', ref_md5.hexdigest(), "\n"
- i = 0
- stable = 1
- while i < rechecks:
- time.sleep(rechecktime) # wait X second and recheck server - See rechecktime variable
- req2 = req
- try:resp_2 = opener.open(req2)
- except socket.timeout, err_2:
- print " [[31;40m*[0m] Socket Timeout: ", err_2
- except socket.error,err_2:
- print " [[31;40m*[0m] Socket Error: ", err_2
- except urllib2.HTTPError, err_2:
- print " [[31;40m*[0m] HTTPError: ", err_2
- except urllib2.URLError, err_2:
- print " [[31;40m*[0m] URLError: ", err_2
- except ValueError, err_2:
- print " [[31;40m*[0m] ValueError: ", err_2, "\n"
- if err_2: print ' [[31;40m*[0m] ERR ', err_2; exit();
- try: ref_resp_2_statuscode = resp.status
- except AttributeError, err:
- ref_resp_2_statuscode = resp.code, resp.msg
- if debug == 1: print "\n [Debug RESP2] :", ref_resp_2_statuscode[0], ref_resp_2_statuscode[1]
- if debug == 1: print "\n [Debug URL] :", resp_2.geturl(); print " [Debug URL] :", resp.geturl();
- if resp_2.geturl() != ref_url:
- print "\n [[35;40m![0m] URL Value doesn't appear stable"
- print ' [[35;40m![0m] URL (FINAL):',
- for line in TXTWRAP.wrap(resp_2.geturl()): print line
- stable = 0
- url_stable = 0
- else:
- print " [\x1B[31;40m"+ str(i+1) +"\x1B[0m] Pass"
- stable_check_headers = resp_2.info()
- stable_check_headers_len = len(str(stable_check_headers).split('\n')) -1
- stable_check_data = resp_2.read()
- stable_check_md5 = hashlib.md5(stable_check_data)
- if debug == 1: print resp_2.info()
- j = 0
- exclude = 0
- while j < stable_check_headers_len:
- if re.search(r'expires|vtag|etag|date|time|set-cookie|x-transaction|X-Cache|Age' , stable_check_headers.headers[j], re.IGNORECASE): # Ignore commonly changing headers
- exclude = 1
- if exclude == 0:
- if debug == 1: print "\n [Debug] :", stable_check_headers.headers[j],; print " [Debug] :", ref_headers.headers[j],;
- if stable_check_headers.headers[j] != ref_headers.headers[j]:
- print ' [[35;40m![0m] Instability Detected'
- stable = 0
- print ' [[35;40m![0m]', ref_headers.headers[j],
- print ' [[35;40m![0m]', stable_check_headers.headers[j],
- if i == 2 and re.search(r'set-cookie' , stable_check_headers.headers[j], re.IGNORECASE): # On last Stable check, gather cookie info for later comparison
- ref_cookie_temp = ref_headers.headers[j].split(':',1)
- ref_cookie_temp_2 = ref_headers.headers[j].split(';')
- ref_cookie_temp = ref_cookie_temp[1].split('=',1)
- if ref_cookie_temp[0] not in cookie_names_ref:
- cookie_names_ref.append(ref_cookie_temp[0])
- cookie_full_ref.append(stable_check_headers.headers[j])
- if stable != 1: break; # If the responses are not stable, break while loop - No point in checking 3 times if once will do
- j=j+1
- i = i+1
- if debug == 1: print 'Cookies', cookie_names_ref
- if stable != 1:
- print "\n [[35;40m![0m] The URL given doesn't appear to give stable responses"
- print " [[35;40m![0m] Results may vary, and should be manually confirmed\n"
- else:
- print "\n [>] URL appears stable. Beginning test"
- #
- # (BUILT-IN) UA STRINGS
- #
- def_uastrings_desktop = [
- # Default Browsers
- "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
- "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0)",
- "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)",
- "Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)",
- "Mozilla/4.0 (compatible;MSIE 5.5; Windows 98)",
- "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)",
- "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100922 Firefox/4.0.1",
- "Mozilla/5.0 (Windows; U; Windows NT 5.2; rv:1.9.2) Gecko/20100101 Firefox/3.6",
- "Mozilla/5.0 (X11; U; SunOS sun4v; en-US; rv:1.8.1.3) Gecko/20070321 Firefox/2.0.0.3",
- "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7",
- "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13",
- "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8",
- "Opera/9.99 (Windows NT 5.1; U; pl) Presto/9.9.9",
- ]
- def_uastrings_bots = [
- # Spidering bots (Goolge, MSN, etc..)
- "Googlebot/2.1 (+http://www.google.com/bot.html)",
- "Googlebot-Image/1.0",
- "Mediapartners-Google",
- "Mozilla/2.0 (compatible; Ask Jeeves)",
- "msnbot-Products/1.0 (+http://search.msn.com/msnbot.htm)",
- "mmcrawler",
- ]
- def_uastrings_crazy = [
- # Crazy WTF stuff (TrackBack is the local Apache uastring)
- "Windows-Media-Player/9.00.00.4503",
- "Mozilla/5.0 (PLAYSTATION 3; 2.00)",
- "TrackBack/1.02",
- "wispr",
- "",
- ]
- def_uastrings_dangerous = [
- # Possible dangerous strings, use at own risk! Not run unless selected through -d X
- "<script>alert('UATester')</script>",
- "'",
- "' or 22=22'--",
- "%0d%0a",
- "../../../../../../etc/passwd",
- "../../../../../boot.ini",
- "VUF0ZXN0ZXIgdGhlIHBydXBsZSBwaW1wIGVkaXRpb24=", # Base64 encoded string "UAtester the pruple pimp edition"
- ]
- def_uastrings_tools = [
- # Commonly used tools. Additions from the Mod_Security ruleset
- "Mozilla/4.75 (Nikto/2.01)",
- "curl/7.7.2 (powerpc-apple-darwin6.0) libcurl 7.7.2 (OpenSSL 0.9.6b)",
- "w3af.sourceforge.net",
- "HTTrack",
- "Wget 1.9cvs-stable",
- "Lynx (textmode)",
- ".nasl",
- "paros",
- "webinspect",
- "brutus",
- "java",
- ]
- def_uastrings_mobile = [
- # Mobile devices
- "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3",
- "Mozilla/5.0 (iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10",
- "Mozilla/5.0 (Linux; U; Android 2.1-update1; en-at; HTC Hero Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17",
- "jBrowser-WAP",
- "Nokia7650/1.0 Symbian-QP/6.1 Nokia/2.1"
- ]
- # NEW CHECK SECTION
- global default
- default = True
- uastrings = [] # Create empty list for UAstrings
- if uafilepresent == True:
- print"\n [>] Reading User-Agents from: ", uafile
- default = False # prevent default strigns from running
- try:
- uastrings_file = open (uafile) # Set uastrings to file contents
- except:
- print"\n [[35;40m![0m] Failed to read the User-Agents from the file specified"
- print"\n [!| Thanks for coming.. bye!"
- exit(1)
- uastrings = uastrings_file.readlines() # Add all file contents into list
- try:
- uastrings_file.close() # Close file
- except:
- print 'Unable to close file handle... sorry'
- exit(1)
- if single == True:
- print"\n [>] Using SINGLE User-Agent String specified in commandline"
- print" [[35;40m![0m] Verbose mode activated for SINGLE mode testing"
- verbose = True
- default = False # prevent default strigns from running
- uastrings.append(single_uastring) # Set uastrings to Single
- if default == True:
- print"\n [>] Using DEFAULT User-Agent Strings"
- if default_options == True:
- if 'M' in default_opts.upper():
- print"\n [>] Using Mobile User-Agent Strings",
- uastrings.extend(def_uastrings_mobile)
- if 'D' in default_opts.upper():
- print"\n [>] Using Desktop User-Agent Strings",
- uastrings.extend(def_uastrings_desktop)
- if 'C' in default_opts.upper():
- print"\n [>] Using Crazy User-Agent Strings",
- uastrings.extend(def_uastrings_crazy)
- if 'T' in default_opts.upper():
- print"\n [>] Using Tool User-Agent Strings",
- uastrings.extend(def_uastrings_tools)
- if 'B' in default_opts.upper():
- print"\n [>] Using Bot User-Agent Strings",
- uastrings.extend(def_uastrings_bots)
- if 'X' in default_opts.upper():
- print"\n [>] Using Dangerous User-Agent Strings\n [>] Contine at your own risk"
- answer = raw_input("\n [>] Press Y to accept >> ")
- if answer.upper() != 'Y':
- print"\n [>] Bam... pimp slap!\n"
- exit();
- else: print"\n [>] 00OOooh Who da' man! Well don't say you didn't ask for it!"
- uastrings.extend(def_uastrings_dangerous)
- else: uastrings.extend(def_uastrings_mobile);uastrings.extend(def_uastrings_desktop);uastrings.extend(def_uastrings_crazy);uastrings.extend(def_uastrings_tools);uastrings.extend(def_uastrings_bots)
- print "\n\n [>] Output: [[35;40m+[0m] Added Headers, [[35;40m-[0m] Removed Headers, [[35;40m![0m] Altered Headers, [ ] No Change"
- header_printed_global = False
- for ualine in uastrings:
- err = 0
- current = ualine
- header_printed = False
- req = urllib2.Request(url)
- req.add_header('User-agent', ualine)
- try: resp2 = opener.open(req)
- except socket.timeout, err:
- print " [[31;40m*[0m] Socket Timeout: ", err
- except socket.error,err_2:
- print " [[31;40m*[0m] Socket Error: ", err
- except urllib2.HTTPError, err:
- print " [[31;40m*[0m] HTTPError: ", err
- except urllib2.URLError, err:
- print " [[31;40m*[0m] URLError: ", err
- except ValueError, err:
- print " [[31;40m*[0m] ValueError: ", err, "\n"
- if err: exit();
- if ualine == "": ualine = "EMPTY USER-AGENT STRING\x1B[31;40m!\x1B[0m" # Set to inform user of empty string
- ua_check_headers = resp2.info()
- ua_check_headers_len = len(str(ua_check_headers).split('\n')) -1
- ua_check_data = resp2.read()
- ua_check_md5 = hashlib.md5(ua_check_data)
- try: statuscode = resp2.status
- except AttributeError, err:
- statuscode = resp2.code, resp2.msg
- if csvfilepresent == True:
- csvform = []
- csvform = map(string.strip, ua_check_headers.headers)
- csvform.insert(0, statuscode)
- csvform.insert(0, resp2.geturl())
- csvform.insert(0, ualine)
- csvform.append(ua_check_md5.hexdigest())
- csvoutputfile.writerow(csvform)
- if debug == 1: print resp2.info()
- if ref_url != resp2.geturl() or verbose == True:
- icon = ' '
- if ref_url != resp2.geturl(): icon = '\x1B[35;40m!\x1B[0m'
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- print ' [' + icon + '] URL (FINAL):',
- for line in TXTWRAP.wrap(resp2.geturl()): print line
- header_printed = True
- header_printed_global = True
- ua_check_statuscode = statuscode
- if ref_resp_statuscode[0] != ua_check_statuscode[0] or verbose == True:
- if header_printed == False:
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- icon = ' '
- if ref_resp_statuscode[0] != ua_check_statuscode[0]: icon = '\x1B[35;40m!\x1B[0m'
- print ' [' + icon + '] Response Code:', ua_check_statuscode[0],ua_check_statuscode[1]; match = True
- header_printed = True
- header_printed_global = True
- j = 0
- exclude = 0
- while j < ua_check_headers_len:
- if verbose == False and re.search(r'expires|vtag|date|time|x-transaction|Set-Cookie|X-Cache|Age' , ua_check_headers.headers[j], re.IGNORECASE): # Ignore commonly changing headers
- exclude = 1
- if exclude == 0:
- ua_check_headers_match = ua_check_headers.headers[j].split(':',1)
- if debug == 1:
- if header_printed == False:
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- header_printed = True
- header_printed_global = True
- k = 0
- while k < ref_headers_len:
- ref_headers_match = ref_headers.headers[k].split(':',1)
- if debug == 1:
- if header_printed == False:
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- header_printed = True
- header_printed_global = True
- if ua_check_headers_match[0] == ref_headers_match[0]:
- header_match = 1
- if ua_check_headers_match[1] == ref_headers_match[1]:
- value_match = 1
- if verbose == True:
- if header_printed == False:
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- header_printed = True
- header_printed_global = True
- for line in REFWRAP.wrap(ua_check_headers.headers[j]): print line
- #print ' [ ]', ua_check_headers.headers[j],
- break;
- else:
- if header_printed == False:
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- header_printed = True
- header_printed_global = True
- if re.search(r'Set-Cookie' , ua_check_headers.headers[j], re.IGNORECASE):
- break;
- else:
- print ' [[35;40m![0m]', ua_check_headers.headers[j],
- break;
- k=k+1
- if k == ref_headers_len and header_match == 0:
- print ' [[35;40m+[0m]', ua_check_headers.headers[j],
- if re.search(r'set-cookie' , ua_check_headers.headers[j], re.IGNORECASE):
- ua_cookie_temp = ua_check_headers.headers[j].split(':',1)
- ua_cookie_temp = ua_cookie_temp[1].split('=',1)
- if ua_cookie_temp[0] not in cookie_names_ua:
- cookie_names_ua.append(ua_cookie_temp[0])
- cookie_full_ua.append(ua_check_headers.headers[j])
- j=j+1
- if j == ua_check_headers_len:
- if debug == 1:print ' ua and ref cookies =', cookie_names_ua, cookie_names_ref
- l = 0
- k = 0
- while l < len(cookie_names_ua):
- cookie_name = str(cookie_names_ua[l])
- try: ref_match = cookie_names_ref.index(cookie_name)
- except: ref_match = False
- if cookie_names_ua[l] not in cookie_names_ref:
- if header_printed == False:
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- header_printed = True
- header_printed_global = True
- for line in PLUSWRAP.wrap(cookie_full_ua[l]): print line
- else:
- httponly = False
- httponly_ref = False
- httponly_ua = False
- secure = False
- secure_ref = False
- secure_ua = False # Reset results for next Cookie
- if re.search(r'httponly', cookie_full_ua[l] , re.IGNORECASE) or re.search(r'httponly', cookie_full_ref[ref_match] , re.IGNORECASE):
- httponly = True # Mark httponly flag found
- if re.search(r'httponly', cookie_full_ref[ref_match] , re.IGNORECASE): httponly_ref = True
- if re.search(r'httponly', cookie_full_ua[l] , re.IGNORECASE): httponly_ua = True
- if re.search(r'secure', cookie_full_ua[l] , re.IGNORECASE) or re.search(r'secure', cookie_full_ref[ref_match] , re.IGNORECASE):
- secure = True # Mark secure flag found
- if re.search(r'secure', cookie_full_ref[ref_match] , re.IGNORECASE): secure_ref = True
- if re.search(r'secure', cookie_full_ua[l] , re.IGNORECASE): secure_ua = True
- if httponly_ref != httponly_ua:
- print ' [[35;40m![0m]', cookie_full_ua[l],
- if httponly_ref == False: print ' [[35;40m+[0m] HTTPonly flag set'
- else: print ' [[35;40m-[0m] HTTPonly flag removed'
- if secure_ref != secure_ua:
- print ' [[35;40m![0m]', cookie_full_ua[l],
- if secure_ref == False: print ' [[35;40m+[0m] Secure flag set'
- else: print ' [[35;40m-[0m] Secure flag removed'
- if httponly == False and secure == False:
- if cookie_names_ua[l] in cookie_names_ref and verbose == True:
- for line in REFWRAP.wrap(cookie_full_ua[l]): print line
- l=l+1
- while k < len(cookie_names_ref):
- if cookie_names_ref[k] not in cookie_names_ua:
- if header_printed == False:
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- header_printed = True
- header_printed_global = True
- for line in MINUSWRAP.wrap(cookie_full_ref[k]): print line
- k=k+1
- exclude = 0
- header_match = 0
- value_match = 0
- j = 0 # Reset counter for missing header check
- exclude = 0
- while j < ref_headers_len:
- ref_headers_match = ref_headers.headers[j].split(':',1)
- k = 0
- while k < ua_check_headers_len:
- ua_check_headers_match = ua_check_headers.headers[k].split(':',1)
- if ref_headers_match[0] == ua_check_headers_match[0]:
- header_match = 1
- break;
- k=k+1
- if k == ua_check_headers_len and header_match != 1:
- if header_printed == False:
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- header_printed = True
- header_printed_global = True
- for line in MINUSWRAP.wrap(ref_headers.headers[j]): print line
- j=j+1
- exclude = 0
- header_match = 0
- value_match = 0
- if ref_md5.hexdigest() != ua_check_md5.hexdigest():
- if header_printed == False:
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- print ' [[35;40m![0m] Data (MD5):', ua_check_md5.hexdigest()
- elif verbose == True:
- if header_printed == False:
- for line in UAWRAP.wrap(ualine): print line
- print '\n'
- header_printed = True
- header_printed_global = True
- print ' [ ] Data (MD5):', ua_check_md5.hexdigest();
- print "\n"
- if header_printed_global == False: print " [>] Checks completed... try enabling VERBOSE mode for more detailed output\n"
- if csvfilepresent == True:
- try:
- csvoutputfile_handle.close() # Close file
- except:
- print 'Unable to close output file handle... sorry', err
- exit(1)
- print " [>] That's all folks... Fo' Shizzle!"
- print "\n"
- except KeyboardInterrupt: print '\n\n [[31;40m*[0m] Error: ctrlc_caught'; print ' [[31;40m*[0m] Thanks for coming... keep on pimpin!\n'; exit()
- class SmartRedirectHandler(urllib2.HTTPRedirectHandler):
- def http_error_301(self, req, fp, code, msg, headers):
- result = urllib2.HTTPRedirectHandler.http_error_301(self, req, fp, code, msg, headers)
- try: result.status = code, msg
- except: result.status = 'No Status Code in Return Header'
- return result
- def http_error_302(self, req, fp, code, msg, headers):
- result = urllib2.HTTPRedirectHandler.http_error_301(self, req, fp, code, msg, headers)
- try: result.status = code, msg
- except: result.status = 'No Status Code in Return Header'
- return result
- def http_error_303(self, req, fp, code, msg, headers):
- result = urllib2.HTTPRedirectHandler.http_error_301(self, req, fp, code, msg, headers)
- try: result.status = code, msg
- except: result.status = 'No Status Code in Return Header'
- return result
- def http_error_307(self, req, fp, code, msg, headers):
- result = urllib2.HTTPRedirectHandler.http_error_301(self, req, fp, code, msg, headers)
- try: result.status = code, msg
- except: result.status = 'No Status Code in Return Header'
- return result
- try:
- opts, args = getopt.getopt(sys.argv[1:], "u:f:s:d:o:vh", ["url=", "file=", "single", "default=", "output=", "verbose", "help", "debug"])
- except getopt.GetoptError:
- print (logo)
- print (usage)
- sys.exit(2)
- if len(sys.argv) < 3:
- print (logo)
- print (usage)
- sys.exit(2)
- for opt, arg in opts:
- if opt in ("-h", "--help"):
- print (logo)
- print (usage)
- sys.exit()
- elif opt in ("-u", "--url"):
- url = arg.lower()
- if url.startswith("http"): url = arg
- else: url = "http://" +arg
- elif opt in ("-f", "--file"):
- uafile = arg
- uafilepresent = True
- elif opt in ("-s", "--single"):
- single_uastring = arg
- single = True
- elif opt in ("-d", "--default"):
- if arg == ' ': arg = 'MDCTB'
- default_opts = arg
- default_options = True
- elif opt in ("-o", "--output"):
- csvfile = arg
- csvfilepresent = True
- elif opt in ("-v", "--verbose"):
- verbose = True
- elif opt in ("--debug"):
- debug = 1
- if __name__== '__main__':
- print (logo)
- main()
Add Comment
Please, Sign In to add comment