Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- #------------------------------------------------------
- # BY: UNDEADSEC from BRAZIL :)
- # YouTube: https://www.youtube.com/c/UndeadSec
- # Github: https://github.com/UndeadSec/EvilURL
- #------------------------------------------------------
- from platform import python_version
- from sys import exit, argv
- from argparse import ArgumentParser
- from nmap import PortScanner
- from whois import whois
- version = python_version().startswith('2', 0, len(python_version()))
- if version:
- print('Are you using python version {}\n'
- 'Please, use version 3.X of python'.format(python_version()))
- exit(1)
- from os import system
- RED, WHITE, GREEN, END, YELLOW = '\033[91m', '\33[97m', '\033[1;32m', '\033[0m', '\33[93m'
- unicodes = [{'\u0430':'Cyrillic Small Letter A'},
- {'\u03F2':'Greek Lunate Sigma Symbol'},
- {'\u0435':'Cyrillic Small Letter Ie'},
- {'\u043E':'Cyrillic Small Letter O'},
- {'\u0440':'Cyrillic Small Letter Er'},
- {'\u0455':'Cyrillic Small Letter Dze'},
- {'\u0501':'Cyrillic Small Letter Komi De'},
- {'\u051B':'Cyrillic Small Letter Qa'},
- {'\u051D':'Cyrillic Small Letter We'}]
- def message(output=False):
- system('clear')
- printParser('''{0}
- {0}88888888888 88 88{1} 88 88 88888888ba 88
- {0}88 "" 88{1} 88 88 88 "8b 88
- {0}88 88{1} 88 88 88 ,8P 88
- {0}88aaaaa 8b d8 88 88{1} 88 88 88aaaaaa8P' 88
- {0}88""""" `8b d8' 88 88{1} 88 88 88""""88' 88 v3.0
- {0}88 `8b d8' 88 88{1} 88 88 88 `8b 88
- {0}88 `8b,d8' 88 88{1} Y8a. .a8P 88 `8b 88
- {0}88888888888 "8" 88 88{1} `"Y8888Y"' 88 `8b 88888888 {1}
- [ by UNDEAD{0}SEC{1} - Alisson Moretto @UndeadSec ]\n'''.format(RED, END), output)
- def cleanTxt(txt):
- for i in (RED, WHITE, GREEN, END, YELLOW):
- txt = txt.replace(i, '')
- return txt
- def cleanFile(output):
- arq = open(output, 'w')
- arq.write('')
- arq.close()
- def checkAval(domain):
- try:
- return whois(domain).registrar
- except:
- return None
- def printParser(txt, output=False):
- print(txt)
- if output:
- arq = open(output, 'a')
- arq.write(cleanTxt(txt)+'\n')
- arq.close()
- def printOriginal(url, checkConnection, output):
- printParser('{0}[{1}~{0}]{1} Original: {2}'.format(GREEN, END, url), output)
- if checkConnection: printParser(check_url(url), output)
- def makeEvil(char, unicd, uninum, newurl, oldurl, output):
- printParser('\n{0}[{1}*{0}]{1} Domain name: %s\n{0}[{1}*{0}]{1} Char replaced: %s\n{0}[{1}*{0}]{1} Using Unicode: %s\n{0}[{1}*{0}]{1} Unicode number: %s\n{0}[{1}*{0}]{1} Evil URL: {3}%s{1}'.format(GREEN, END, YELLOW, RED) % (oldurl, char, unicd, uninum, newurl), output)
- import itertools
- def gen(url, tld, checkConnection=False, output=False, aval=False):
- url = url.lower()
- evils = [{'a':'\u0430'},{'c': '\u03F2'}, {'e': '\u0435'}, {'o': '\u043E'}, {'p': '\u0440'}, {'s': '\u0455'}, {'d': '\u0501'}, {'q': '\u051B'}, {'w': '\u051D'}]
- e_matchs = []
- for em in evils:
- if list(em)[0].upper() in url.upper():
- e_matchs.append(list(em)[0])
- cst = ''
- for ch in e_matchs:
- cst += list(ch)[0]
- words = []
- for i in range(1, 9):
- for j in itertools.combinations(cst, i):
- temp = ''.join(j)
- words.append(temp)
- for word in words:
- newurl = url
- unicd = []
- name = []
- chars = []
- for w in word:
- for em in evils:
- if list(em)[0] == w:
- chr = em[list(em)[0]]
- unicd.append(chr)
- chars.append(w)
- for u in unicodes:
- if list(u)[0] == chr:
- name.append(u[chr])
- newurl = newurl.replace(w, chr)
- makeEvil(chars, unicd, name, newurl+tld, url, output)
- if checkConnection: printParser(check_url(newurl+tld), output)
- if aval:
- if checkAval(newurl+tld) is None:
- printParser('{0}[{1}*{0}]{1} Available domain'.format(GREEN, END), output)
- else:
- printParser('{0}[{1}!{0}]{1} Unavailable domain'.format(YELLOW, END), output)
- # -------------- BEGIN CHECKURL MODULE----------------- #
- def check_url(url):
- '''
- Check connection
- :param url: suspicious url
- :return: status of connection
- '''
- nmScan = PortScanner()
- result = nmScan.scan(url, arguments='-sn')
- if int(result['nmap']['scanstats']['uphosts']) > 0:
- msg = '{0}[{1}*{0}]{1} Connection test: UP'.format(GREEN, END)
- else:
- msg = '{0}[{1}!{0}]{1} Connection test: DOWN'.format(YELLOW, END)
- return msg
- def check_EVIL(url):
- '''
- Check evil chars in URL
- :param url: suspicious URL
- :return: result of check and the evil chars
- '''
- bad_chars = ['\u0430', '\u03F2', '\u0435', '\u043E', '\u0440', '\u0455', '\u0501', '\u051B', '\u051D']
- result = [bad_chars[i] for i in range(len(bad_chars)) if bad_chars[i] in url]
- if result:
- msg = '{0}[{1}*{0}]{1} Evil URL detected: {2}{3}{1}'.format(GREEN,END,RED,url)
- msg += '\n{0}[{1}*{0}]{1} Unicode characters used: {2}'.format(GREEN,END,result)
- else:
- msg = '{0}[{1}!{0}]{1} Evil URL NOT detected: {2}'.format(YELLOW, END, url)
- return msg
- def urls_list(file, checkConnection, output):
- '''
- Read the file to verify Evil URL
- :param file: file with a list of Evil URLs
- :return: file reading
- '''
- with open(file) as arq:
- urls = [f.strip() for f in arq]
- for i in range(len(urls)):
- printParser(check_EVIL(urls[i]), output)
- if checkConnection:
- printParser(check_url(urls[i]), output)
- printParser('', output)
- # -------------- END CHECKURL MODULE ----------------- #
- def parseHandler():
- parser = ArgumentParser(usage="evilurl.py [options]", description="Generate unicode evil domains for IDN Homograph Attack and detect them.")
- parser.add_argument("-g", dest="generate", action="store_true", help="Generate unicode evil domains")
- parser.add_argument("-d", dest="domain", help="Domain name with termination (example.com)")
- parser.add_argument("-c", dest="checkConnection", action="store_true", help="Check generated/input domain connections")
- parser.add_argument("-o", dest="output", help="Save generated evil domains to a file")
- parser.add_argument("-f", dest="filepath", help="Import domains from a file and check them")
- parser.add_argument("-a", dest="aval", action="store_true", help="Check if domain is available")
- if len(argv) == 1:
- parser.print_help()
- exit(1)
- args = parser.parse_args()
- domain = '' if args.domain is None else args.domain
- generate = args.generate
- checkConnection = args.checkConnection
- filepath = args.filepath
- output = args.output
- aval = args.aval
- tld = ''
- for x in domain.split('.')[1:]:
- tld += '.' + x
- if output:
- cleanFile(output)
- message(output)
- if generate and not domain or generate and domain and filepath or domain and filepath:
- parser.print_help()
- elif generate and len(domain) > 0:
- printOriginal(domain, checkConnection, output)
- gen(domain.split('.')[0], tld, checkConnection, output, aval)
- elif len(domain) > 0:
- printParser(check_EVIL(domain), output)
- elif filepath:
- urls_list(filepath, checkConnection, output)
- if checkConnection and not filepath and not generate:
- printParser(check_url(domain), output)
- if output:
- print('\n{1}[{2}*{1}]{2} Logs stored to {0}'.format(output, GREEN, END))
- if __name__ == '__main__':
- try:
- message()
- parseHandler()
- except KeyboardInterrupt:
- exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement