<commit_before>#
# Typofinder for domain typo discovery
# 
# Released as open source by NCC Group Plc - http://www.nccgroup.com/
# 
# Developed by <NAME>, ollie dot whitehouse at nccgroup dot com
#
# http://www.github.com/nccgroup/typofinder
#
# Released under AGPL see LICENSE for more information#
#

import sys
import codecs
import argparse
import requests
import simplejson

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--domain', help='domain to analyze', required=False, type=str, default='nccgroup.com')
    parser.add_argument('-s', '--server',   help='server to use', required=False, type=str, default='https://labs.nccgroup.trust')
    args = parser.parse_args()

    requests.packages.urllib3.disable_warnings()
    
    strURLTypos  = args.server + "/typofinder/typov2.ncc"
    strURLEntity = args.server +  "/typofinder/entitylight.ncc"

    strHTTPHdrs      = {'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Accept': 'text/plain'}
    strTypoRequest   = "host="+args.domain+"&typos=typos&typoamount=1&tld=tld&bitflip=bitflip&homoglyph=homoglyph&doppelganger=doppelganger&charsetamount=&alexafilter=neveralexa"
    strEntityRequest = "host="
    
    arrTypoResp = requests.post(strURLTypos, data=strTypoRequest, headers=strHTTPHdrs, verify=False)

    if arrTypoResp.text.startswith("[!]"):
        print(arrTypoRest.text)
        sys.exit(0)

    strTypoJSON = arrTypoResp.json()

    for strTDomain in strTypoJSON:
        
        dataFoo = strEntityRequest+strTDomain
        
        try:
            arrDomainResp = requests.post(strURLEntity, data=dataFoo, headers=strHTTPHdrs, verify=False)
            #print(arrDomainResp.text)

            try:
                strDEntityJSON = arrDomainResp.json()
            
                print("[i] " + strDEntityJSON['strDomain'])
                if strDEntityJSON['bError'] is False:
                    for server in strDEntityJSON['nameservers']:
                        print ("[i]    --- " + server);
                else:
                        print ("[!]    --- " + strDEntityJSON['strError'])

            except simplejson.scanner.JSONDecodeError:
                print("[!] JSON decode error")

        except ConnectionAbortedError:
            print("[!] Connected abort for " + print(strTDomain.encode('cp437', 'replace')))

        except ConnectionError:
            print("[!] Connected error for " + print(strTDomain.encode('cp437', 'replace')))<commit_msg>More robust error handling, verbose option and ctrl-c handler<commit_after>#
# Typofinder for domain typo discovery
# 
# Released as open source by NCC Group Plc - http://www.nccgroup.com/
# 
# Developed by <NAME>, ollie dot whitehouse at nccgroup dot com
#
# http://www.github.com/nccgroup/typofinder
#
# Released under AGPL see LICENSE for more information#
#

import sys
import codecs
import argparse
import requests
import simplejson

if __name__ == '__main__':

    try:
        parser = argparse.ArgumentParser()
        parser.add_argument('-d', '--domain', help='domain to analyze', required=False, type=str, default='nccgroup.com')
        parser.add_argument('-s', '--server',   help='server to use', required=False, type=str, default='https://labs.nccgroup.trust')
        parser.add_argument('-v', '--verbose',   help='verbose output', required=False, dest='verbose', action='store_true')
        parser.set_defaults(verbose=False);
        args = parser.parse_args()

        requests.packages.urllib3.disable_warnings()
    
        strURLTypos  = args.server + "/typofinder/typov2.ncc"
        strURLEntity = args.server +  "/typofinder/entitylight.ncc"

        strHTTPHdrs      = {'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Accept': 'text/plain'}
        strTypoRequest   = "host="+args.domain+"&typos=typos&typoamount=1&tld=tld&bitflip=bitflip&homoglyph=homoglyph&doppelganger=doppelganger&charsetamount=&alexafilter=neveralexa"
        strEntityRequest = "host="
    
        arrTypoResp = requests.post(strURLTypos, data=strTypoRequest, headers=strHTTPHdrs, verify=False)

        if arrTypoResp.text.startswith("[!]"):
            print(arrTypoRest.text)
            sys.exit(0)

        strTypoJSON = arrTypoResp.json()

        for strTDomain in strTypoJSON:
        
            dataFoo = strEntityRequest+strTDomain
           
            arrDomainResp = requests.post(strURLEntity, data=dataFoo, headers=strHTTPHdrs, verify=False)

            try:
                strDEntityJSON = arrDomainResp.json()
            
                if args.verbose is True:
                    print("[i] " + strDEntityJSON['strDomain'])
                    if strDEntityJSON['bError'] is False:
                        for server in strDEntityJSON['nameservers']:
                            print ("[i]    --- " + server);
                    else:
                            print ("[!]    --- " + strDEntityJSON['strError'])
                else:
                    if strDEntityJSON['bError'] is False:
                        print("[i] " + strDEntityJSON['strDomain'] + " has nameservers")                           

            except simplejson.scanner.JSONDecodeError:
                print("[!] JSON decode error")

    except ConnectionAbortedError:
        print("[!] Connection abort for " + print(strTDomain.encode('cp437', 'replace')))

    except ConnectionError:
        print("[!] Connection error for " + print(strTDomain.encode('cp437', 'replace')))

    except KeyboardInterrupt:
        pass

    except:
        type, value, traceback = sys.exc_info()
        print("[i] Other error - " + str(type) + " - " + str(value))
{'fraction_non_alphanumeric': 0.12510966836287069, 'fraction_numerical': 0.003860326373047903, 'mean_word_length': 2.6144578313253013, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1172864', 'n_tokens_mistral': 1799, 'n_tokens_neox': 1743, 'n_words': 338}