Advertisement
FlyFar

evilurl.py

Dec 3rd, 2023
774
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.16 KB | Cybersecurity | 0 0
  1. #!/usr/bin/env python
  2. #------------------------------------------------------
  3. #      BY: UNDEADSEC from BRAZIL :)
  4. #      YouTube: https://www.youtube.com/c/UndeadSec
  5. #      Github: https://github.com/UndeadSec/EvilURL
  6. #------------------------------------------------------
  7. from platform import python_version
  8. from sys import exit, argv
  9. from argparse import ArgumentParser
  10. from nmap import PortScanner
  11. from whois import whois
  12.  
  13. version = python_version().startswith('2', 0, len(python_version()))
  14. if version:
  15.     print('Are you using python version {}\n'
  16.           'Please, use version 3.X of python'.format(python_version()))
  17.     exit(1)
  18.  
  19. from os import system
  20.  
  21. RED, WHITE, GREEN, END, YELLOW = '\033[91m', '\33[97m', '\033[1;32m', '\033[0m', '\33[93m'
  22.  
  23. unicodes = [{'\u0430':'Cyrillic Small Letter A'},
  24.          {'\u03F2':'Greek Lunate Sigma Symbol'},
  25.          {'\u0435':'Cyrillic Small Letter Ie'},
  26.          {'\u043E':'Cyrillic Small Letter O'},
  27.          {'\u0440':'Cyrillic Small Letter Er'},
  28.          {'\u0455':'Cyrillic Small Letter Dze'},
  29.          {'\u0501':'Cyrillic Small Letter Komi De'},
  30.          {'\u051B':'Cyrillic Small Letter Qa'},
  31.          {'\u051D':'Cyrillic Small Letter We'}]
  32.  
  33. def message(output=False):
  34.     system('clear')
  35.     printParser('''{0}                                                                  
  36. {0}88888888888           88  88{1}  88        88  88888888ba   88          
  37. {0}88                    ""  88{1}  88        88  88      "8b  88          
  38. {0}88                        88{1}  88        88  88      ,8P  88          
  39. {0}88aaaaa  8b       d8  88  88{1}  88        88  88aaaaaa8P'  88          
  40. {0}88"""""  `8b     d8'  88  88{1}  88        88  88""""88'    88      v3.0    
  41. {0}88        `8b   d8'   88  88{1}  88        88  88    `8b    88          
  42. {0}88         `8b,d8'    88  88{1}  Y8a.    .a8P  88     `8b   88          
  43. {0}88888888888  "8"      88  88{1}   `"Y8888Y"'   88      `8b  88888888  {1}
  44.  
  45. [ by UNDEAD{0}SEC{1} - Alisson Moretto @UndeadSec ]\n'''.format(RED, END), output)
  46.  
  47. def cleanTxt(txt):
  48.     for i in (RED, WHITE, GREEN, END, YELLOW):
  49.         txt = txt.replace(i, '')
  50.     return txt
  51.  
  52. def cleanFile(output):
  53.     arq = open(output, 'w')
  54.     arq.write('')
  55.     arq.close()
  56.  
  57. def checkAval(domain):
  58.     try:
  59.         return whois(domain).registrar
  60.     except:
  61.         return None
  62.  
  63. def printParser(txt, output=False):
  64.     print(txt)
  65.     if output:
  66.         arq = open(output, 'a')
  67.         arq.write(cleanTxt(txt)+'\n')
  68.         arq.close()
  69.  
  70. def printOriginal(url, checkConnection, output):
  71.     printParser('{0}[{1}~{0}]{1} Original: {2}'.format(GREEN, END, url), output)
  72.     if checkConnection: printParser(check_url(url), output)
  73.  
  74. def makeEvil(char, unicd, uninum, newurl, oldurl, output):
  75.     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)
  76.  
  77. import itertools
  78.  
  79. def gen(url, tld, checkConnection=False, output=False, aval=False):
  80.     url = url.lower()
  81.  
  82.     evils = [{'a':'\u0430'},{'c': '\u03F2'}, {'e': '\u0435'}, {'o': '\u043E'}, {'p': '\u0440'}, {'s': '\u0455'}, {'d': '\u0501'}, {'q': '\u051B'}, {'w': '\u051D'}]
  83.     e_matchs = []
  84.  
  85.     for em in evils:
  86.         if list(em)[0].upper() in url.upper():
  87.             e_matchs.append(list(em)[0])
  88.  
  89.     cst = ''
  90.     for ch in e_matchs:
  91.         cst += list(ch)[0]
  92.  
  93.     words = []
  94.     for i in range(1, 9):
  95.         for j in itertools.combinations(cst, i):
  96.             temp = ''.join(j)
  97.             words.append(temp)
  98.  
  99.     for word in words:
  100.         newurl = url
  101.         unicd = []
  102.         name = []
  103.         chars = []
  104.         for w in word:
  105.             for em in evils:
  106.                 if list(em)[0] == w:
  107.                     chr = em[list(em)[0]]
  108.                     unicd.append(chr)
  109.                     chars.append(w)
  110.                     for u in unicodes:
  111.                         if list(u)[0] == chr:
  112.                             name.append(u[chr])
  113.                     newurl = newurl.replace(w, chr)
  114.         makeEvil(chars, unicd, name, newurl+tld, url, output)
  115.         if checkConnection: printParser(check_url(newurl+tld), output)
  116.         if aval:
  117.             if checkAval(newurl+tld) is None:
  118.                 printParser('{0}[{1}*{0}]{1} Available domain'.format(GREEN, END), output)
  119.             else:
  120.                 printParser('{0}[{1}!{0}]{1} Unavailable domain'.format(YELLOW, END), output)
  121.  
  122. # -------------- BEGIN CHECKURL MODULE----------------- #
  123. def check_url(url):
  124.  
  125.     '''
  126.    Check connection
  127.    :param url: suspicious url
  128.    :return: status of connection
  129.    '''
  130.  
  131.     nmScan = PortScanner()
  132.     result = nmScan.scan(url, arguments='-sn')
  133.  
  134.     if int(result['nmap']['scanstats']['uphosts']) > 0:
  135.         msg = '{0}[{1}*{0}]{1} Connection test: UP'.format(GREEN, END)
  136.     else:
  137.         msg = '{0}[{1}!{0}]{1} Connection test: DOWN'.format(YELLOW, END)
  138.  
  139.     return msg
  140.  
  141. def check_EVIL(url):
  142.  
  143.     '''
  144.    Check evil chars in URL
  145.    :param url: suspicious URL
  146.    :return: result of check and the evil chars
  147.    '''
  148.  
  149.     bad_chars = ['\u0430', '\u03F2', '\u0435', '\u043E', '\u0440', '\u0455', '\u0501', '\u051B', '\u051D']
  150.     result = [bad_chars[i] for i in range(len(bad_chars)) if bad_chars[i] in url]
  151.  
  152.     if result:
  153.         msg = '{0}[{1}*{0}]{1} Evil URL detected: {2}{3}{1}'.format(GREEN,END,RED,url)
  154.         msg += '\n{0}[{1}*{0}]{1} Unicode characters used: {2}'.format(GREEN,END,result)
  155.     else:
  156.         msg = '{0}[{1}!{0}]{1} Evil URL NOT detected: {2}'.format(YELLOW, END, url)
  157.  
  158.     return msg
  159.  
  160. def urls_list(file, checkConnection, output):
  161.     '''
  162.    Read the file to verify Evil URL
  163.    :param file: file with a list of Evil URLs
  164.    :return: file reading
  165.    '''
  166.  
  167.     with open(file) as arq:
  168.         urls = [f.strip() for f in arq]
  169.     for i in range(len(urls)):
  170.         printParser(check_EVIL(urls[i]), output)
  171.         if checkConnection:
  172.             printParser(check_url(urls[i]), output)
  173.         printParser('', output)
  174.  
  175. # -------------- END CHECKURL MODULE ----------------- #
  176.  
  177. def parseHandler():
  178.     parser = ArgumentParser(usage="evilurl.py [options]", description="Generate unicode evil domains for IDN Homograph Attack and detect them.")
  179.     parser.add_argument("-g", dest="generate", action="store_true", help="Generate unicode evil domains")
  180.     parser.add_argument("-d", dest="domain", help="Domain name with termination (example.com)")
  181.     parser.add_argument("-c", dest="checkConnection", action="store_true", help="Check generated/input domain connections")
  182.     parser.add_argument("-o", dest="output", help="Save generated evil domains to a file")
  183.     parser.add_argument("-f", dest="filepath", help="Import domains from a file and check them")
  184.     parser.add_argument("-a", dest="aval", action="store_true", help="Check if domain is available")
  185.  
  186.     if len(argv) == 1:
  187.         parser.print_help()
  188.         exit(1)
  189.    
  190.     args = parser.parse_args()
  191.     domain = '' if args.domain is None else args.domain
  192.     generate = args.generate
  193.     checkConnection = args.checkConnection
  194.     filepath = args.filepath
  195.     output = args.output
  196.     aval = args.aval
  197.     tld = ''
  198.     for x in domain.split('.')[1:]:
  199.         tld += '.' + x
  200.     if output:
  201.         cleanFile(output)
  202.         message(output)
  203.     if generate and not domain or generate and domain and filepath or domain and filepath:
  204.         parser.print_help()
  205.     elif generate and len(domain) > 0:        
  206.         printOriginal(domain, checkConnection, output)
  207.         gen(domain.split('.')[0], tld, checkConnection, output, aval)
  208.     elif len(domain) > 0:
  209.         printParser(check_EVIL(domain), output)
  210.     elif filepath:
  211.         urls_list(filepath, checkConnection, output)
  212.     if checkConnection and not filepath and not generate:
  213.         printParser(check_url(domain), output)
  214.     if output:
  215.         print('\n{1}[{2}*{1}]{2} Logs stored to {0}'.format(output, GREEN, END))
  216.  
  217. if __name__ == '__main__':
  218.     try:
  219.         message()
  220.         parseHandler()
  221.     except KeyboardInterrupt:
  222.         exit()
Tags: attack evilurl
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement