Инструмент исследования веб-сайтов, который показывает информацию о доменах (например, WHOIS, IP, обратные ссылки и т. д.)

Ищете инструмент, который может сделать следующее:

  • получить ввод доменного имени (или имени хоста, такого как shop.example.com)
  • создать отчет для домена / хоста для такой информации, как
    • КТО
    • IP, владелец IP, сайты на одном IP
    • проверить на черный список спама
    • проверка безопасности, список вредоносных программ
    • ссылка на записи интернет-архива
    • список обратных ссылок на хост
    • общий показатель популярности сайта, такой как Google PageRank, Alexa Traffic Rank и т. д.

Вся вышеуказанная информация должна быть получена программой из различных источников без каких-либо действий пользователя или с минимальными действиями.

Программа должна уметь объединять всю информацию в единый отчет. Отчет может быть в текстовом, doc или html формате.

Время, затраченное на создание отчета, не так важно. Однако, если доступна оценка времени создания отчета для инструмента, не стесняйтесь упоминать об этом.

Бесплатно или платно нормально.

Предпочтение отдается программе с графическим интерфейсом Windows, но приемлема и размещенная служба.

Кажется, что многие веб-сайты предоставляют такую ​​​​информацию, пожалуйста, опишите, почему некоторых из наиболее распространенных недостаточно для вас, чтобы мы могли помочь вам лучше.
Не могли бы вы объяснить несколько вещей: как вы хотите отчет? Что вы подразумеваете под PageRank? Что вы имеете в виду под Алексой? (может быть, их номер ранга?) Что вы подразумеваете под Интернет-архивом? (сколько, возможно, снимков?) Что вы подразумеваете под обратными ссылками? (Количество обратных ссылок?)
@NicolasRaoul, сайты, которые, как мне кажется, в основном предоставляют одну или часть информации. Я не встречал сайта, который мог бы объединить всю информацию в 1 шаг и выдать отчет. Если вы знаете такой сайт, пожалуйста, поделитесь ответом.
@Janekmuric, вопрос обновлен на основе вашего разъяснения.
@NicolasRaoul Всего один вопрос: сколько максимально времени потребуется для создания отчета?
@Janekmuric: Я? Вы хотели упомянуть спрашивающего? :-)
Да, я хотел спросить @kenchew
@Janekmuric обновил вопрос, включив в него время.

Ответы (1)

Я не нашел никаких веб-сайтов или программ, которые могли бы делать то, что вам нужно, поэтому вместо изучения географии я сделал программу на Python 2.7, которая сделает это за вас.

Большое спасибо jgamblin на Github за его скрипт поиска черного списка с открытым исходным кодом.

from pprint import pprint, pformat
from sys import exit, argv
from socket import gethostbyname, gethostbyaddr
from os.path import exists, isdir
from json import dumps
from time import strftime, time
from re import findall
from urllib2 import urlopen, Request, build_opener
from bs4 import BeautifulSoup as bs
import dns.resolver
from ipwhois import IPWhois

# Code below downloaded from GitHub page:
# https://github.com/jgamblin/isthisipbad/blob/master/isthisipbad.py
# Modified by Janek to fix errors.

def content_test(url, badip):
    """
    Test the content of url's response to see if it contains badip.
        Args:
            url -- the URL to request data from
            badip -- the IP address in question
        Returns:
            Boolean
    """

    try:
        request = Request(url)
        html_content = build_opener().open(request).read()

        matches = findall(badip, html_content)

        return len(matches) == 0
    except Exception, e:
        return False

bls = ["b.barracudacentral.org", "bl.spamcannibal.org", "bl.spamcop.net",
       "blacklist.woody.ch", "cbl.abuseat.org", "cdl.anti-spam.org.cn",
       "combined.abuse.ch", "combined.rbl.msrbl.net", "db.wpbl.info",
       "dnsbl-1.uceprotect.net", "dnsbl-2.uceprotect.net",
       "dnsbl-3.uceprotect.net", "dnsbl.cyberlogic.net",
       "dnsbl.sorbs.net", "drone.abuse.ch", "drone.abuse.ch",
       "duinv.aupads.org", "dul.dnsbl.sorbs.net", "dul.ru",
       "dyna.spamrats.com", "dynip.rothen.com",
       "http.dnsbl.sorbs.net", "images.rbl.msrbl.net",
       "ips.backscatterer.org", "ix.dnsbl.manitu.net",
       "korea.services.net", "misc.dnsbl.sorbs.net",
       "noptr.spamrats.com", "ohps.dnsbl.net.au", "omrs.dnsbl.net.au",
       "orvedb.aupads.org", "osps.dnsbl.net.au", "osrs.dnsbl.net.au",
       "owfs.dnsbl.net.au", "pbl.spamhaus.org", "phishing.rbl.msrbl.net",
       "probes.dnsbl.net.au", "proxy.bl.gweep.ca", "rbl.interserver.net",
       "rdts.dnsbl.net.au", "relays.bl.gweep.ca", "relays.nether.net",
       "residential.block.transip.nl", "ricn.dnsbl.net.au",
       "rmst.dnsbl.net.au", "smtp.dnsbl.sorbs.net",
       "socks.dnsbl.sorbs.net", "spam.abuse.ch", "spam.dnsbl.sorbs.net",
       "spam.rbl.msrbl.net", "spam.spamrats.com", "spamrbl.imp.ch",
       "t3direct.dnsbl.net.au", "tor.dnsbl.sectoor.de",
       "torserver.tor.dnsbl.sectoor.de", "ubl.lashback.com",
       "ubl.unsubscore.com", "virus.rbl.jp", "virus.rbl.msrbl.net",
       "web.dnsbl.sorbs.net", "wormrbl.imp.ch", "xbl.spamhaus.org",
       "zen.spamhaus.org", "zombie.dnsbl.sorbs.net"]

URLS = [
    #TOR
    ('http://torstatus.blutmagie.de/ip_list_exit.php/Tor_ip_list_EXIT.csv',
     'is not a TOR Exit Node',
     'is a TOR Exit Node',
     False),

    #EmergingThreats
    ('http://rules.emergingthreats.net/blockrules/compromised-ips.txt',
     'is not listed on EmergingThreats',
     'is listed on EmergingThreats',
     True),

    #AlienVault
    ('http://reputation.alienvault.com/reputation.data',
     'is not listed on AlienVault',
     'is listed on AlienVault',
     True),

    #BlocklistDE
    ('http://www.blocklist.de/lists/bruteforcelogin.txt',
     'is not listed on BlocklistDE',
     'is listed on BlocklistDE',
     True),

    #Dragon Research Group - SSH
    ('http://dragonresearchgroup.org/insight/sshpwauth.txt',
     'is not listed on Dragon Research Group - SSH',
     'is listed on Dragon Research Group - SSH',
     True),

    #Dragon Research Group - VNC
    ('http://dragonresearchgroup.org/insight/vncprobe.txt',
     'is not listed on Dragon Research Group - VNC',
     'is listed on Dragon Research Group - VNC',
     True),

    #OpenBLock
    ('http://www.openbl.org/lists/date_all.txt',
     'is not listed on OpenBlock',
     'is listed on OpenBlock',
     True),

    #NoThinkMalware
    ('http://www.nothink.org/blacklist/blacklist_malware_http.txt',
     'is not listed on NoThink Malware',
     'is listed on NoThink Malware',
     True),

    #NoThinkSSH
    ('http://www.nothink.org/blacklist/blacklist_ssh_all.txt',
     'is not listed on NoThink SSH',
     'is listed on NoThink SSH',
     True),

    #Feodo
    ('http://rules.emergingthreats.net/blockrules/compromised-ips.txt',
     'is not listed on Feodo',
     'is listed on Feodo',
     True),

    #antispam.imp.ch
    ('http://antispam.imp.ch/spamlist',
     'is not listed on antispam.imp.ch',
     'is listed on antispam.imp.ch',
     True),

    #dshield
    ('http://www.dshield.org/ipsascii.html?limit=10000',
     'is not listed on dshield',
     'is listed on dshield',
     True),

    #malc0de
    ('http://malc0de.com/bl/IP_Blacklist.txt',
     'is not listed on malc0de',
     'is listed on malc0de',
     True),

    #MalWareBytes
    ('http://hosts-file.net/rss.asp',
     'is not listed on MalWareBytes',
     'is listed on MalWareBytes',
     True)]

def blacklist(badip):
    BAD = 0
    GOOD = 0

    for url, succ, fail, mal in URLS:
        test = content_test(url, badip)
        if test == True:
            GOOD = GOOD + 1
        elif test == False:
            BAD = BAD + 1

    BAD = BAD
    GOOD = GOOD

    for bl in bls:
        try:
                my_resolver = dns.resolver.Resolver()
                query = '.'.join(reversed(str(badip).split("."))) + "." + bl
                my_resolver.timeout = 5
                my_resolver.lifetime = 5
                answers = my_resolver.query(query, "A")
                answer_txt = my_resolver.query(query, "TXT")
                BAD = BAD + 1

        except dns.resolver.NXDOMAIN:
            GOOD = GOOD + 1

        except dns.resolver.Timeout:
            pass

        except dns.resolver.NoNameservers:
            pass

        except dns.resolver.NoAnswer:
           pass

    return str(BAD) + "/" + str(BAD+GOOD)

# Code ABOVE downloaded from GitHub page:
# https://github.com/jgamblin/isthisipbad/blob/master/isthisipbad.py
# Modified by Janek to fix errors.  

def get_rank(domain_to_query):
    result = {'Global':'', "Country":''}
    url = "http://www.alexa.com/siteinfo/" + domain_to_query
    page = urlopen(url).read()
    soup = bs(page, "html.parser")
    for span in soup.find_all('span'):
        if span.has_attr("class"):
            if "globleRank" in span["class"]:
                for strong in span.find_all("strong"):
                    if strong.has_attr("class"):
                        if "metrics-data" in strong["class"]:
                            result['Global'] = strong.text.replace("\n", "").replace(" ", "")
            if "countryRank" in span["class"]:
                image = span.find_all("img")
                for img in image:
                    if img.has_attr("title"):
                        country = img["title"]
                for strong in span.find_all("strong"):
                    if strong.has_attr("class"):
                        if "metrics-data" in strong["class"]:
                            result["Country"] = country + ": " + strong.text.replace("\n", "").replace(" ", "")
    return result

def parseData(ip, data, whdata, blk, rank, tim, iphost):
    whois = whdata["nets"]
    dnet = data["network"]
    ob = data["objects"]
    curtime = strftime("%d %B %Y %H:%M:%S")

    if curtime[0] == "0":
        curtime = curtime[1:]

    timee = str(tim).split(".")[0] + "." + str(tim).split(".")[1][:2]
    outStr = "WARNING: Data below may be inaccurate\nTarget: " + ip + "\nGenerated: " + curtime + "\nTime took to generate: " + timee + " seconds" + "\n\n"

    outStr += "IP host: " + iphost + "\n\n"

    outStr += "Blacklist: " + blk + "\n\n"
    outStr += "Archive: http://web.archive.org/web/*/" + iphost + "\n"
    outStr += "Global Alexa rank: " + rank["Global"] + "\n"
    outStr += "Country Alexa rank: "+ rank["Country"] + "\n\n"


    outStr += "Legacy Whois:\n"
    net = 1
    for i in whois:
        outStr += "  Network " + str(net) + ":\n"
        try:
            outStr += "    IP: " + str(whdata["query"]) + "\n"
        except:
            outStr += "    IP: Not found\n"
        try:
            outStr += "    Name: " + str(i["name"]) + "\n"
        except:
            outStr += "    Name: Not found\n"
        try:
            outStr += "    Abuse E-mails: " + str(i["abuse_emails"]) + "\n"
        except:
            outStr += "    Abuse E-mails: Not found\n"
        try:
            outStr += "    Adress: " + str(i["adress"]) + "\n"
        except:
            outStr += "    Adress: Not found\n"
        try:
            outStr += "    Country: " + str(i["country"]) + "\n"
        except:
            outStr += "    Country: Not found\n"
        try:
            outStr += "    City: " + str(i["city"]) + "\n"
        except:
            outStr += "    City: Not found\n"
        try:
            outStr += "    Postal code: " + str(i["postal_code"]) + "\n"
        except:
            outStr += "    Postal code: Not found\n"
        try:
            outStr += "    Created: " + str(i["created"]) + "\n"
        except:
            outStr += "    Created: Not found\n"
        try:
            outStr += "    Description: " + str(i["description"]) + "\n"
        except:
            outStr += "    Description: Not found\n"
        try:
            outStr += "    Handle: " + str(i["handle"]) + "\n"
        except:
            outStr += "    Handle: Not found\n"
        try:
            outStr += "    Misc E-mails: " + str(i["misc_emails"]) + "\n"
        except:
            outStr += "    Misc E-mails: Not found\n"
        try:
            outStr += "    IP range: " + str(i["range"]) + "\n"
        except:
            outStr += "    IP range: Not found\n"
        try:
            outStr += "    State: " + str(i["state"]) + "\n"
        except:
            outStr += "    State: Not found\n"
        try:
            outStr += "    Tech E-mails: " + str(i["tech_emails"]) + "\n"
        except:
            outStr += "    Tech E-mails: Not found\n"
        try:
            outStr += "    Updated: " + str(i["updated"]) + "\n\n"
        except:
            outStr += "    Updated: Not found\n\n"

        net += 1

    outStr += "\nRDAP (HTTP) Whois:\n"

    try:
        outStr += "  Name: " + str(dnet["name"]) + "\n"
    except:
        outStr += "  Name: Not found\n"
    try:
        outStr += "  Start adress: " + str(dnet["start_adress"]) + "\n"
    except:
        outStr += "  Start adress: Not found\n"
    try:
        outStr += "  End adress: " + str(dnet["end_adress"]) + "\n"
    except:
        outStr += "  End adress: Not found\n"
    try:
        outStr += "  IP verion: " + str(dnet["ip_versoin"]) + "\n"
    except:
        outStr += "  IP version: Not found\n"

    outStr += "  Events:\n"

    e = 1
    for i in dnet["events"]:
        outStr += "    Event " + str(e) + ":\n"
        try:
            outStr += "      Action: " + str(i["action"]) + "\n"
        except:
            outStr += "      Action: Not found\n"
        try:
            outStr += "      Actor: " + str(i["actor"]) + "\n"
        except:
            outStr += "      Actor: Not found\n"
        try:
            outStr += "      Timestamp: " + str(i["timestamp"]) + "\n"
        except:
            outStr += "      Timestamp: Not found\n"

        e += 1

    outStr += "\n  Objects:\n"
    for i in ob:
        z = ob[i]["contact"]
        outStr += "    " + str(i) + ":\n"
        try:
            outStr += "      Name: " + str(z["name"]) + "\n"
        except:
            outStr += "      Name: Not found\n"
        try:
            outStr += "      E-mail: " + str(z["email"][0]["value"]) + "\n"
        except:
            outStr += "      E-mail: Not found\n"
        try:
            outStr += "      Kind: " + str(z["kind"]) + "\n"
        except:
            outStr += "      Kind: Not found\n"
        try:
            outStr += "      Phone: " + str(z["phone"][0]["value"]) + "\n"
        except:
            outStr += "      Phone: Not found\n"
        try:
            outStr += "      Title: " + str(z["title"]) + "\n"

        except:
            outStr += "      Title: Not found\n"
        try:
            outStr += "      Links: "
        except:
            outStr += "      Links: Not found\n"

        if ob[i]["links"]:
            if not len(ob[i]["links"]) == 0:
                for j in ob[i]["links"]:
                    outStr += str(j).replace("\n", " ")
                    outStr += "  "
        else:
            outStr += "Not found"

        outStr += "\n      Contact: "
        if z["address"]:
            for j in z["address"]:
                outStr += str(j["value"].replace("\n", ", "))

        else:
            outStr += "Not found"
        outStr += "\n\n"
    return outStr

def getData(ip):
    obj = IPWhois(ip)
    results = obj.lookup_rdap(depth=1)
    return results

def whgetData(ip):
    obj = IPWhois(ip)
    results = obj.lookup()
    return results

def showHelp():
    name = argv[0].replace("\\","/").split("/")[-1]
    print("""
Simple website report (Whois) generator
Usage:
    %s website [-json]
            [-file <file>]
            [-raw]

Arguments:
    website       Website IPv4 or domain
    -json         Convert output to json 
    -file         Save output to a file
    -raw          Output full Whois lookup in raw format

""" % name)

if __name__ == "__main__":
    args = argv

    if len(args) < 2:
        print("Too few arguments!")
        showHelp()
        exit(1)

    if len(args) > 5:
        print("Too many arguments!")
        showHelp()
        exit(1)

    allowedArgs = ["-file", "-json", "-raw"]
    noLast = ["-file"]

    b = 2
    for i in args[2:]:
        if i not in allowedArgs and args[b-1] not in noLast:
            print("Invalid option (%s)" % i)
            showHelp()
            exit(1)
        b += 1

    for i in args[2:]:
        if args.count(i) > 1 and i in allowedArgs:
            print("Option appearing more then once (%s)" % i)
            showHelp()
            exit(1)

    if args[-1] in noLast:
        print("Option has no arguments (%s)" % args[-1])
        showHelp()
        exit(1)

    if "-json" in args and "-raw" in args:
        print("Can't use -json and -raw in the same time")
        showHelp()
        exit(1)

    rawIP = args[1]
    if rawIP.replace(".","").isdigit() == True:
        ip = rawIP
    else:
        ip = gethostbyname(rawIP)

    if "-file" in args:
        filename = args[args.index("-file") + 1]
        if exists(filename) == True:
            print("File already exists (%s)" % filename) 
            showHelp()
            exit(1)

        directory = "/".join(filename.replace("\\","/").split("/")[0:-1])

        if len(directory) > 0 and isdir(directory) == False:
            print("Directory does not exist (%s)" % directory) 
            showHelp()
            exit(1)

        fileOn = True
    else:
        fileOn = False

    t1 = time()
    data = getData(ip)
    whdata = whgetData(ip)
    blk = blacklist(ip)

    if rawIP.replace(".","").isdigit() == True:
        try:
            iphost = gethostbyaddr(ip)
        except:
            iphost = "Not found"
    else:
        iphost = rawIP

    rank = get_rank(iphost)
    t2 = time()

    t = t2-t1
    if "-file" not in args:
        if "-json" in args:
            all = {"http_whois":data, "legacy_whois":whdata, "blacklist":blk, "rank":rank, "time":t}
            print(dumps(all, ensure_ascii=False) + "\n")
            exit(0)

        elif "-raw" in args:
            all = {"http_whois":data, "legacy_whois":whdata, "blacklist":blk, "rank":rank, "time":t}
            pprint(all)
            exit(0)

        else:
            parsed = parseData(ip, data, whdata, blk, rank, t, iphost)
            print(parsed)
            exit(0)

    else:
        if "-json" in args:
            all = {"http_whois":data, "legacy_whois":whdata, "blacklist":blk, "rank":rank, "time":t}
            forWrite = dumps(all, ensure_ascii=False) + "\n"
            f = open(filename,"w")
            f.write(forWrite)
            f.close()
            print("File created!")
            exit(0)

        elif "-raw" in args:
            all = {"http_whois":data, "legacy_whois":whdata, "blacklist":blk, "rank":rank, "time":t}
            forWrite = pformat(all)
            f = open(filename,"w")
            f.write(forWrite)
            f.close()
            print("File created!")
            exit(0)

        else:
            parsed = parseData(ip, data, whdata, blk, rank, t, iphost)
            forWrite = parsed
            f = open(filename,"w")
            f.write(forWrite)
            f.close()
            print("File created!")
            exit(0)

Что делать:

  1. Скачать Python 2.7.x
  2. Установите его (установите флажок «Добавить python.exe в путь» при установке)
  3. Скопируйте и вставьте приведенный выше код в файл с именемyournamehere.py
  4. Теперь вы можете запустить программу cmdсо следующим запросом:

python yournamehere.py www.google.com

dnspythonПРИМЕЧАНИЕ. Для работы кода bs4необходимо установить следующие библиотеки.ipwhois

Чтобы установить их, перейдите в cmd и введите построчно:

pip install dnspython
pip install ipwhois
pip install bs4

Помощь:

Simple website report (Whois) generator
Usage:
        netreport.py website [-json]
                        [-file <file>]
                        [-raw]

Arguments:
        website           Website IPv4 or domain
        -json             Convert output to json
        -file             Save output to a file
        -raw          Output full Whois lookup in raw format

Если вы хотите отформатировать выходной полный отчет в словаре Pythonic, используйте `-raw.

Если вы хотите отформатировать вывод в json, используйте «-json».

-rawи -jsonне могут использоваться одновременно.

Если вы хотите сохранить вывод в файл, используйте-file

Примеры:

python yournamehere.py www.google.com
python yournamehere.py www.google.com -json
python yournamehere.py www.google.com -file myreport.txt
python yournamehere.py www.google.com -raw -file myfile.txt
python yournamehere.py www.google.com -file C:\Users\Jan\Desktop\file.txt

Скорость:

Это довольно медленно. Для www.google.comсоздания отчета требуется ~ 30 секунд. Мой интернет тоже медленный: 4 Мбит/с на входе, 0,5 Мбит/с на входе (да, очень медленный)

Не совсем то, что мне нужно, но определенно заслуживает одобрения за (огромные!) усилия по составлению кода и ответа. Спасибо!
Ну, это все, что у меня есть. В любом случае, я не уверен, что вы ищете, потому что программа делает все в вашем списке, кроме обратных ссылок. Мне сейчас нужно учить географию. (и это лучший веб-сайт, который я мог найти, чтобы делать то, что вам нужно, но на нем отсутствует много информации Centralops.net/co/DomainDossier.aspx )
Спасибо, что нашли время, чтобы собрать ответ вместе. Очень признателен.