Получение наборов доменов из ICANN (1173 зоны) и базовая обработка списков.

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
107541


Содержание

1. INTRO
2. Регистрация на сервисе и автоматическое получение данных.
3. Получение уникальных доменов во всех зонах.
4. Получение уникальных NS серверов во всех зонах.

5. Получение уникальных доменов с принадлежащими им NS серверами с во всех зонах.
6. Заключение.


1. INTRO


Здравствуйте форумчане и гости форума. В этом небольшом кейсе мы рассмотрим как получать бесплатные наборы доменов от организации ICANN, как при помощи Zennoposter быстро и легко их обрабатывать.

Наборы тематических доменов и обогащенные данные необходимы для самых различных целей, для аналитики, сбора технической и коммерческой информации, для составление интернет каталогов сайтов, для пентеста по программам Bug Bounty , ну и для продажи заинтересованным в них лицам. Причем данные должны быть “свежие”, актуализированные, по возможности максимально обогащенные дополнительными данными. Но к сожалению, такие данные которые присутствуют в интернете, либо предоставляются на платной основе, либо являются не актуальными (устаревшими,) либо не обладают нужным объемом данных которые они содержат. В этом мини кейсе мы закроем в этом потребность и сделаем это бесплатно.


2. Регистрация на сервисе и автоматическое получение данных.


Для того, чтобы приступить к работе, нам необходимо, конечно же, в первую очередь зарегистрироваться на сервисе ICANN (ICANN — некоммерческая общественная корпорация. В ее работе участвуют люди со всего мира в деле обеспечения безопасного, стабильного и отказоустойчивого функционирования интернета. ), провести все необходимые авторизации, отправить запросы администраторам доменных зон и по завершению всех действий получить все списки и архивы с доменами в автоматическом режиме. Звучит устрашающе, но поверьте это проще некуда, а во избежание ошибок допущенных мною и дальнейших автоматизации действий - была записана видеоинструкция.


Как вы смогли убедиться - это довольно просто, а в спойлере ниже код Powershell для получения списков заапрувленных и автоматическому скачиванию архивов.

Код для получения токена и списков заапрувленных зон

Powershell код для получения заапрувленных список:
cd desktop # Можете убрать если запускаете Powershell сразу в нужной папке
$headers = @{
"Accept" = "application/json"
"Content-Type" = "application/json"
}
$body = @{
"username" = "Ваша почта на ICANN"
"password" = 'Ваш пароль на ICANN'   #Пароль  обязательно в одинарных кавычках
} | ConvertTo-Json
$url = "https://account-api.icann.org/api/authenticate"
$response = Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $body
$accessToken = $response.accessToken
$headers = @{
    "Authorization" = "Bearer $accessToken"
    "Accept" = "application/json"
}
$a = Invoke-WebRequest -Uri "https://czds-api.icann.org/czds/downloads/links" -Headers $headers -Method GET
$urls = $a.Content
$urls = $urls -replace '\[|\]|"'
$urls = $urls -split ','
$queue = [System.Collections.Concurrent.ConcurrentQueue[string]]::new()
foreach ($url in $urls)
{
    Write-Host $url
    $queue.Enqueue($url)
    $url >> 1.txt
}
$c = $queue.Count
Write-Host $c + " zones aprooved"
Код для скачивания архивов заапрувленных зон. Не работает без предыдущего

Powershell код для скачивания заапрувленных списков:
$headers = @{
    "Authorization" = "Bearer $accessToken"
    "Accept" = "application/json"
}
# Путь к папке на рабочем столе, где вы хотите сохранить загруженные файлы.
$destinationPath = "$env:userprofile\Desktop\Files"
# Создаем папку, если ее еще нет.
if (-not (Test-Path -Path $destinationPath -PathType Container)) {
    New-Item -ItemType Directory -Path $destinationPath | Out-Null
}
# Проходимся по коллекции файлов и загружаем каждый из них.
foreach ($fileUrl in $queue) {
    $fileName = Split-Path $fileUrl -Leaf
    $filePath = Join-Path $destinationPath $fileName
    # Если файл уже существует, пропускаем его.
    if (Test-Path $filePath) {
       # Write-Host "File '$fileName' already exists. Skipping download."
        continue
    }
    Write-Host "Downloading file '$fileName'..."
    # Загружаем файл и сохраняем его на рабочем столе.
    Invoke-WebRequest -Uri $fileUrl -Headers $headers -OutFile $filePath
}
Write-Host "All files have been downloaded to '$destinationPath'."


3. Получение уникальных доменов во всех зонах.

Это, пожалуй, самое легкое из всего, но для начала, Вам нужно кое-что исправить в расспакованных архивах. Если Вы дождались апрува зоны com то необходимо сменить ее название с com.zone.48236 (у Вас цифры могут быть иные) на название com.

107596


Как мы помним из первого видео, список сильно "зашумлен" и нам необходимо предусмотреть все варианты для того чтобы его "почистить"

107597


Логика тут весьма простая. Получаем пути ко всем файлам из папки, создаем отдельную папку куда будем сохранять готовые результаты. Затем из каждого списка читаем строки, убираем те которые содержат мусор в виде "dnskey, nsec3param, nsec3, nsec, soa,ds, a, aaaa, тxt, ds,"rrsig". Создаем контрольную переменную чтобы не "хватать" дубликаты доменов. Также читаем файл по частям, так как некоторые файлы "тяжелые" (зона .com 25 Гб+). Ну и конечно же нужен репорт файл в котором будет отчет сколько доменов в каждой зоне и общее количество которое у нас есть на руках. Все это необходимо делать одновременно, не растягивая код на километры. Если думаете что это "вынос" мозга - то уверяю Вас, это проще простого, смотрим видео.


Only Domains:
string path_folder = @"C:\Users\vigan\Desktop\1"; // замените путь к папке на путь к своей папке с разархивированными зонами
string targetDirectory = path_folder;
string[] fileEntries = Directory.GetFiles(targetDirectory);
var files = Directory.GetFiles(path_folder, "*", SearchOption.TopDirectoryOnly); // получение всех файлов в папке и ее подпапках
double totalSize = 0; // общий объем файлов
foreach (var file in files)
{
    totalSize += new FileInfo(file).Length; // добавление размера каждого файла к общему объему
}
double totalSizeInGb = totalSize / 1024 / 1024 / 1024; // перевод в гигабайты
project.SendInfoToLog($"Количество файлов: {files.Length}. Общий объем: {totalSizeInGb:F2} Гб.");
var filePaths = new System.Collections.Generic.List<string>(files);
DirectoryInfo dirInfo = new DirectoryInfo(targetDirectory);
List<string> fileList1 = new List<string>();
List<string> fileList2 = new List<string>();
List<string> report_list = new List<string>();
foreach (string fileName in fileEntries)
{
    fileList1.Add(fileName);
}
string control = string.Empty;
string subpath = string.Empty;
string _report = string.Empty;
int i_d = 0;
subpath = @"OnlyDomains";
_report = targetDirectory + "\\" + subpath + "\\" + "_report.txt";
if (!dirInfo.Exists)
{
    dirInfo.Create();
}
dirInfo.CreateSubdirectory(subpath);
project.SendInfoToLog("Создана субдиректория OnlyDomains");
while (fileList1 != null)
{
    i_d = 0;
    try
    {
        string path = fileList1[0];
        fileList1.RemoveAt(0);
        string name_file = path.Replace(targetDirectory, "");
        string name_file_transit = name_file.Replace("\\", "");
        string name_file_transit_out = name_file_transit.Replace(".txt", "");
        string path_domain = targetDirectory + "\\" + subpath + "\\" + name_file + ".txt";
        using (var writer_domain = new StreamWriter(new BufferedStream(File.OpenWrite(path_domain), 100 * 1024 * 1024)))
        {
            using (var file = new StreamReader(new BufferedStream(File.OpenRead(path), 100 * 1024 * 1024)))
            {
                string line;
                int count = 0; // Счетчик прочитанных строк
                while ((line = file.ReadLine()) != null)
                {
                    string[] text = line.Split('    ');
                    string domain = text[0];
                    domain = domain.TrimEnd('.');
                    if (domain == control)
                    {
                        continue ; // Пропустить дубликаты доменов
                    }
                    if (domain.Contains("."))
                    {
                        string NS = text[3];
                        NS = NS.ToLower();
                        string server = text[4];
                        server = server.TrimEnd('.');
                        if (NS.Contains("dnskey") || NS.Contains("nsec3param") || NS.Contains("nsec3") || NS.Contains("soa") || (NS.Contains("ds") || NS.Contains("a") || NS.Contains("aaaa") || NS.Contains("txt") || NS.Contains("ds") || NS.Contains("rrsig") || NS.Contains("nsec")))
                        {
                            continue ; // Пропустить домены с определенными условиями
                        }
                        string result = domain;
                        fileList2.Add(result);
                        control = domain;
                    }
                    count++;
                    if (count == 10000000)
                    {
                        // Записать обработанные домены в файл
                        foreach (string outline in fileList2)
                        {
                            writer_domain.WriteLine(outline);
                            i_d++;
                        }
                        fileList2.Clear();
                        count = 0;
                    }
                }
                // Записать оставшиеся обработанные домены в файл
                foreach (string outline in fileList2)
                {
                    writer_domain.WriteLine(outline);
                    i_d++;
                }
            }

            fileList2.Clear();
            project.SendInfoToLog("В зоне " + name_file_transit_out + " -  " + i_d + " уникальных доменов");
            string _report_string = name_file_transit_out + "|" + i_d;
            report_list.Add(_report_string);
        }
    }
    catch
    {
        break;
    }
}
int general_count = 0;
foreach (string outline_count in report_list)
{
    string[] text_count = outline_count.Split('|');
    int out_count = int.Parse(text_count[1]);
    general_count = general_count + out_count;
}

string total_count = general_count.ToString();
string full_count = " Total domains - " + total_count;
report_list.Add("_______________________________");
report_list.Add(full_count);
System.IO.StreamWriter writer_report = new System.IO.StreamWriter(_report, true);
{
    foreach (string outline in report_list)
    {
        writer_report.WriteLine(outline);
    }
}
if (writer_report != null) writer_report.Dispose();///
report_list.Clear();
project.SendInfoToLog("Всего уникальных доменов в списках - " + total_count);
project.SendInfoToLog("Обработка списка доменов завершена");

Для многих пользователей таких списков достаточно, но мы сделаем еще кое что.

4. Получение уникальных NS серверов во всех зонах.

Для различных исследований, софта и приложений списки уникальных NS серверов (пусть и не абсолютно все) имеют гораздо большее значение и важность чем сами доменные списки. На просторах интернета также можно найти как коллекции за оплату, так и бесплатные наборы с различной степени актуализации. Имеются и интернет каталоги которые можно распарсить, но если у нас на руках уже есть то что нам нужно - зачем создавать себе проблемы?

Тут логика обработки списков немного отличается от той, которая применялась при обработке уникальных доменов. В отличии от доменов, NS сервера в списке идут не по порядку, многократно повторяются по файлу. Так что как и в предыдущем случае, читаем файлы частями, выбираем только NS сервера, с каждым проходом удаляем дубликаты, по окончанию проверки каждой зоны проводим окончальную чистку выходной коллекции. Почему сначала не собрать а затем не удалить дубликаты? Во первых это извращение, а во вторых не уникальные списки NS содержат миллионы строк и гигабайты объема, можно легко "выбить" память. Также нам стоит по окончанию обработки обработки собрать со всех выходных файлов NS сервера в один общий файл, почистить на дубликаты. Ну и куда же без репорта, нужен список в котором будет указано сколько уникальных NS в каждой зоне и сколько уникальных NS серверов вообще на руках. Так же, ничего сложного, смотрим.


Код для получения уникальных NS серверов:
string path_folder = @"C:\Users\vigan\Desktop\test";
string targetDirectory = path_folder;
string[] fileEntries = Directory.GetFiles(targetDirectory);
var files = Directory.GetFiles(path_folder, "*", SearchOption.TopDirectoryOnly); // получение всех файлов в папке и ее подпапках
double totalSize = 0; // общий объем файлов
foreach (var file in files)
{
    totalSize += new FileInfo(file).Length; // добавление размера каждого файла к общему объему
}
double totalSizeInGb = totalSize / 1024 / 1024 / 1024; // перевод в гигабайты
project.SendInfoToLog($"Количество файлов: {files.Length}. Общий объем: {totalSizeInGb:F2} Гб.");
int file_count = fileEntries.Length;
DirectoryInfo dirInfo = new DirectoryInfo(targetDirectory);
HashSet<string> fileList1 = new HashSet<string>();
HashSet<string> fileList2 = new HashSet<string>();
List<string> report_list = new List<string>();
List<string> fileList3 = new List<string>();
foreach (string fileName in fileEntries)
{
    fileList1.Add(fileName);
}
string subpath_ns = @"OnlyNS";
string _report = Path.Combine(targetDirectory, subpath_ns, "_report.txt");
string path_domain_ns = Path.Combine(targetDirectory, subpath_ns);
if (!dirInfo.Exists)
{
    dirInfo.Create();
}
dirInfo.CreateSubdirectory(subpath_ns);
project.SendInfoToLog("Создана субдиректория  OnlyNS");
while (fileList1.Count > 0)
{
    int i_d = 0;
    try
    {
        string path = fileList1.First();
        fileList1.Remove(path);
        string name_file = Path.GetFileName(path);
        string name_file_transit_out = Path.GetFileNameWithoutExtension(name_file);
        string path_domain = Path.Combine(path_domain_ns, name_file + ".txt");
        using (var writer_domain = new StreamWriter(path_domain, append: false))
        using (var file = new StreamReader(path))
        {
            string line;
            int count = 0;
            while ((line = file.ReadLine()) != null)
            {
                string[] text = line.Split('    ');
                string NS = text[3].ToLower();
                string server = text[4].TrimEnd('.');
                if (!(NS.Contains("dnskey") || NS.Contains("nsec3param") || NS.Contains("nsec3") || NS.Contains("soa") || (NS.Contains("ds") || NS.Contains("a") || NS.Contains("aaaa") || NS.Contains("txt") || NS.Contains("ds") || NS.Contains("rrsig")|| NS.Contains("nsec"))))
                {
                    string result = server.ToLower();
                    fileList2.Add(result);
                }
                count++;
                if (count == 5000000)
                {
                    fileList2.RemoveWhere(item => !fileList2.Contains(item));
                }
            }
            foreach (string outline in fileList2)
            {
                writer_domain.WriteLine(outline);
                i_d++;
            }
            project.SendInfoToLog("В зоне " + name_file_transit_out + " - " + i_d + " уникальных NS серверов");
            string _report_string = name_file_transit_out + "|" + i_d.ToString();
            report_list.Add(_report_string);
            fileList2.Clear();
            count = 0;
        }
    }
    catch
    {
        continue;
    }
}
project.SendInfoToLog("Начата общая сборка всех NS");
string counter_ns = Path.Combine(targetDirectory, subpath_ns);
string targetDirectory_ns = counter_ns;
string[] fileEntries_ns = Directory.GetFiles(targetDirectory_ns);
foreach (string fileName_ns in fileEntries_ns)
{
    fileList3.Add(fileName_ns);
}
while (fileList3.Count > 0)
{
    try
    {
        string path = fileList3[0];
        fileList3.RemoveAt(0);
        using (var file = new StreamReader(path))
        {
            string line;
            while ((line = file.ReadLine()) != null)
            {
                fileList2.Add(line);
            }
        }
    }
    catch
    {
        break;
    }
}
string all = Path.Combine(targetDirectory, subpath_ns, "_all_ns.txt");
int i_d_count = 0;
using (var writer_count = new StreamWriter(all, true))
{
    foreach (string outline in fileList2)
    {
        writer_count.WriteLine(outline);
        i_d_count++;
    }
}
project.SendInfoToLog("Всего уникальных NS в всех списках - " + i_d_count);
string unique = "Total NS unique - " + i_d_count;
report_list.Add("_______________________________");
report_list.Add(unique);
using (var writer_unique = new StreamWriter(_report, true))
{
    foreach (string outline_unique in report_list)
    {
        writer_unique.WriteLine(outline_unique);
    }
}

Ну что же, давайте продолжим и перейдем к следующему пункту кейса.

5. Получение уникальных доменов с принадлежащими им NS серверами с во всех зонах.

Теперь давайте соберем списки в том виде в котором многие их качали с бесплатных раздач или покупали у брокеров данных. Это списки зон которые содержат в себе адрес домена и принадлежащие к этому домену NS сервера. Такие списки в основном и востребованы разными группами пользователей и стоят в продаже на различных сервисах фрилансеров и сайтах брокеров.

Из за того, что тут используется одновременно большой массив входных данных, то как бы я не пытался, но у меня не получилось "разогнать" код. Виной тому бюджетная "машина" с 8 Гб на борту, так что у Вас это может работать быстрей (у меня 45+ минут, но это из за зоны .com). Логика так же отличается от предыдущих. Читаем файл частями, при помощи LINQ собираем данные по каждому конкретному домену в строку и затем сбрасываем с дописыванием в соответствующий доменной зоне файл. Так как в предыдущих частях кода мы получили всю информацию о входящих данных по количеству, уникальности и прочему, то в данном блоке нам это не требуется. Все что необходимо - просто обработка и создание выходных файлов с указанными в заголовке параметрами. Смотрим.


Domains and NS:
string path_folder = @"C:\Users\vigan\Desktop\test";
string targetDirectory = path_folder;
string[] fileEntries = Directory.GetFiles(targetDirectory);
var files = Directory.GetFiles(path_folder, "*", SearchOption.TopDirectoryOnly);
double totalSize = 0;
foreach (var file in files)
{
    totalSize += new FileInfo(file).Length;
}
double totalSizeInGb = totalSize / 1024 / 1024 / 1024;
project.SendInfoToLog($"Количество файлов: {files.Length}. Общий объем: {totalSizeInGb:F2} Гб.");
int file_count = fileEntries.Length;
DirectoryInfo dirInfo = new DirectoryInfo(targetDirectory);
HashSet<string> fileList1 = new HashSet<string>();
HashSet<string> fileList2 = new HashSet<string>();
List<string> report_list = new List<string>();
List<string> fileList3 = new List<string>();
foreach (string fileName in fileEntries)
{
    fileList1.Add(fileName);
}
string subpath = @"DomainsAndNS";
string subdirectoryPath = Path.Combine(targetDirectory, subpath);
if (!dirInfo.Exists)
{
    dirInfo.Create();
}
if (!Directory.Exists(subdirectoryPath))
{
    Directory.CreateDirectory(subdirectoryPath);
    project.SendInfoToLog("Создана субдиректория  DomainsAndNS");
}
while (fileList1.Count > 0)
{
    try
    {
        string path = fileList1.ElementAt(0);
        fileList1.Remove(path);
        string name_file = path.Replace(targetDirectory, "");
        string name_file_transit = name_file.Replace("\\", "");
        string name_file_transit_out = name_file_transit.Replace(".txt", "");
        string path_domain = Path.Combine(subdirectoryPath, name_file_transit_out + ".txt");
        using (var file = new StreamReader(new BufferedStream(File.OpenRead(path), 100 * 1024 * 1024)))
        {
            int count = 0;
            string line;
            while ((line = file.ReadLine()) != null)
            {
                string[] text = line.Split('\t');
                string NS = text[3].ToLower();
                string server = text[4].TrimEnd('.');
                if (!(NS.Contains("dnskey") || NS.Contains("nsec3param") || NS.Contains("nsec3") || NS.Contains("soa") || NS.Contains("ds") || NS.Contains("a") || NS.Contains("aaaa") || NS.Contains("txt") || NS.Contains("rrsig")|| NS.Contains("nsec")))
                {
                    string domain = text[0];
                    domain = domain.TrimEnd('.');
                    string result = domain + " | " + server;
                    fileList2.Add(result);
                    count++;
                    if (count == 1000000)
                    {
                        var list2 = new List<string>();
                        fileList2.GroupBy(x => x.Split('|').First().Trim())
                            .ToList()
                            .ForEach(x => list2.Add(string.Join(" | ", new[]
                            {
                                x.Key, string.Join(", ", x.Select(v => v.Split('|').Last().Trim()))
                            })));
                        fileList3.Add(string.Join("\n", list2));
                       using (StreamWriter writer = new StreamWriter(path_domain, append: true))
                        {
                            foreach (string outline in fileList3)
                            {
                                writer.WriteLine(outline);
                            }
                        }
                        fileList3.Clear();
                        fileList2.Clear();
                        count = 0;
                    }
                }
            }
            if (fileList2.Count > 0)
{
var list2 = new List<string>();
fileList2.GroupBy(x => x.Split('|').First().Trim())
.ToList()
.ForEach(x => list2.Add(string.Join(" | ", new[]
{
x.Key, string.Join(", ", x.Select(v => v.Split('|').Last().Trim()))
})));
                fileList3.Add(string.Join("\n", list2));
                using (StreamWriter writer = new StreamWriter(path_domain, append: true))
            {
                foreach (string outline in fileList3)
                {
                    writer.WriteLine(outline);
                }
            }
            fileList3.Clear();
            fileList2.Clear();
        }
        using (StreamWriter writer_domain = new StreamWriter(path_domain, append: true))
        {
            foreach (string outline in fileList2)
            {
                writer_domain.WriteLine(outline);
            }
            project.SendInfoToLog("Зона  " + name_file_transit_out + " обработана");
        }
    }
}
catch
{
    continue;
}

}

На этом мы закончили данный мини кейс по получению доменных списков из тематических зон ICANN. Конечно же самих зон гораздо больше , это зоны конкретных страновых геозон (DE,UK, PL .... e.t.c.) а также их суффиксов (com.au, gov.lt ...e.t.c.) и так далее. Но данный кейс только по ICANN.

6. Заключение

Ну что же, как мы с вами смогли убедиться, Zennoposter это очень мощный инструмент и позволяет делать вроде бы сложные вещи быстро и эффективно. А с возможностью писать код на C# настолько масштабируют его возможности что они почти безграничны. Надеюсь что данный мини кейс поможет многим пользователям всегда иметь под рукой актуальные наборы данных (доменные списки) , а в случае необходимости очень быстро их скачать и обработать, ведь как я показывал - скорость обработки достаточна высока. Пусть мой код не идеален, но так и я не кодер, а всего лишь любитель самоучка.

Конечно, мы рассмотрели только базовую обработку, ну и автоматическое получение списков, но на самом деле это только верхушка айсберга. Кому возможно нужны только ключи зон для фильтрации трафика, кому то только корневые NS для дальнейшей обработки доменных списков (как вариант получение mx/txt.dkim/dmarc e.t.c. при помощи, например DNSClient от Micha Conrad), кому то надо пропинговать домены и получить при помощи наборов данных от IANA geo-данные о расположение парковок сайтов чтобы не "воткнуться" в законы GDPR или 152-Ф3, кому то (в основном пентестерам но не ограничиваясь ими) необходимо из набора NS серверов при помощи таблицы суффиксов Mozzilla вычислить хостинг провайдеров для базового понимания на каких предположительно технологиях может работать сайт/сайты для сужения набора инструментов для исследований. Этот список можно продолжать и продолжать и одной статьи для этого конечно недостаточно. Но все же - пишите в комментариях чтобы вы еще хотели увидить, какие вопросы вас интересуют и я по возможности быстро - постараюсь подготовить для вас решение в открытом доступе на базе Zennoposter.

На этом у меня все, доброго дня и удачи всем участникам конкурса!
 
Номер конкурса статей
Девятнадцатый конкурс статей

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.

Последнее редактирование модератором:

Дмитрий202020

Активный пользователь
Регистрация
15.09.2020
Сообщения
265
Благодарностей
61
Баллы
28
Посмотреть вложение 107541

Содержание

1. INTRO
2. Регистрация на сервисе и автоматическое получение данных.
3. Получение уникальных доменов во всех зонах.
4. Получение уникальных NS серверов во всех зонах.

5. Получение уникальных доменов с принадлежащими им NS серверами с во всех зонах.
6. Заключение.


1. INTRO


Здравствуйте форумчане и гости форума. В этом небольшом кейсе мы рассмотрим как получать бесплатные наборы доменов от организации ICANN, как при помощи Zennoposter быстро и легко их обрабатывать.

Наборы тематических доменов и обогащенные данные необходимы для самых различных целей, для аналитики, сбора технической и коммерческой информации, для составление интернет каталогов сайтов, для пентеста по программам Bug Bounty , ну и для продажи заинтересованным в них лицам. Причем данные должны быть “свежие”, актуализированные, по возможности максимально обогащенные дополнительными данными. Но к сожалению, такие данные которые присутствуют в интернете, либо предоставляются на платной основе, либо являются не актуальными (устаревшими,) либо не обладают нужным объемом данных которые они содержат. В этом мини кейсе мы закроем в этом потребность и сделаем это бесплатно.


2. Регистрация на сервисе и автоматическое получение данных.


Для того, чтобы приступить к работе, нам необходимо, конечно же, в первую очередь зарегистрироваться на сервисе ICANN (ICANN — некоммерческая общественная корпорация. В ее работе участвуют люди со всего мира в деле обеспечения безопасного, стабильного и отказоустойчивого функционирования интернета. ), провести все необходимые авторизации, отправить запросы администраторам доменных зон и по завершению всех действий получить все списки и архивы с доменами в автоматическом режиме. Звучит устрашающе, но поверьте это проще некуда, а во избежание ошибок допущенных мною и дальнейших автоматизации действий - была записана видеоинструкция.


Как вы смогли убедиться - это довольно просто, а в спойлере ниже код Powershell для получения списков заапрувленных и автоматическому скачиванию архивов.

Код для получения токена и списков заапрувленных зон

Powershell код для получения заапрувленных список:
cd desktop # Можете убрать если запускаете Powershell сразу в нужной папке
$headers = @{
"Accept" = "application/json"
"Content-Type" = "application/json"
}
$body = @{
"username" = "Ваша почта на ICANN"
"password" = 'Ваш пароль на ICANN'   #Пароль  обязательно в одинарных кавычках
} | ConvertTo-Json
$url = "https://account-api.icann.org/api/authenticate"
$response = Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $body
$accessToken = $response.accessToken
$headers = @{
    "Authorization" = "Bearer $accessToken"
    "Accept" = "application/json"
}
$a = Invoke-WebRequest -Uri "https://czds-api.icann.org/czds/downloads/links" -Headers $headers -Method GET
$urls = $a.Content
$urls = $urls -replace '\[|\]|"'
$urls = $urls -split ','
$queue = [System.Collections.Concurrent.ConcurrentQueue[string]]::new()
foreach ($url in $urls)
{
    Write-Host $url
    $queue.Enqueue($url)
    $url >> 1.txt
}
$c = $queue.Count
Write-Host $c + " zones aprooved"
Код для скачивания архивов заапрувленных зон. Не работает без предыдущего

Powershell код для скачивания заапрувленных списков:
$headers = @{
    "Authorization" = "Bearer $accessToken"
    "Accept" = "application/json"
}
# Путь к папке на рабочем столе, где вы хотите сохранить загруженные файлы.
$destinationPath = "$env:userprofile\Desktop\Files"
# Создаем папку, если ее еще нет.
if (-not (Test-Path -Path $destinationPath -PathType Container)) {
    New-Item -ItemType Directory -Path $destinationPath | Out-Null
}
# Проходимся по коллекции файлов и загружаем каждый из них.
foreach ($fileUrl in $queue) {
    $fileName = Split-Path $fileUrl -Leaf
    $filePath = Join-Path $destinationPath $fileName
    # Если файл уже существует, пропускаем его.
    if (Test-Path $filePath) {
       # Write-Host "File '$fileName' already exists. Skipping download."
        continue
    }
    Write-Host "Downloading file '$fileName'..."
    # Загружаем файл и сохраняем его на рабочем столе.
    Invoke-WebRequest -Uri $fileUrl -Headers $headers -OutFile $filePath
}
Write-Host "All files have been downloaded to '$destinationPath'."


3. Получение уникальных доменов во всех зонах.

Это пожалуй самое легкое из всего, но для начала, Вам нужно кое что исправить в расспакованных архивах. Если Вы дождались апрува зоны com то необходимо сменить ее название с com.zone.48236 (у Вас цифры могут быть иные) на название com.

Посмотреть вложение 107596

Как мы помним из первого видео, список сильно "зашумлен" и нам необходимо предусмотреть все варианты для того чтобы его "почистить"

Посмотреть вложение 107597

Логика тут весьма простая. Получаем пути ко всем файлам из папки, создаем отдельную папку куда будем сохранять готовые результаты. Затем из каждого списка читаем строки, убираем те которые содержат мусор в виде "dnskey, nsec3param, nsec3, nsec, soa,ds, a, aaaa, тxt, ds,"rrsig". Создаем контрольную переменную чтобы не "хватать" дубликаты доменов. Также читаем файл по частям, так как некоторые файлы "тяжелые" (зона .com 25 Гб+). Ну и конечно же нужен репорт файл в котором будет отчет сколько доменов в каждой зоне и общее количество которое у нас есть на руках. Все это необходимо делать одновременно, не растягивая код на километры. Если думаете что это "вынос" мозга - то уверяю Вас, это проще простого, смотрим видео.


Only Domains:
string path_folder = @"C:\Users\vigan\Desktop\1"; // замените путь к папке на путь к своей папке с разархивированными зонами
string targetDirectory = path_folder;
string[] fileEntries = Directory.GetFiles(targetDirectory);
var files = Directory.GetFiles(path_folder, "*", SearchOption.TopDirectoryOnly); // получение всех файлов в папке и ее подпапках
double totalSize = 0; // общий объем файлов
foreach (var file in files)
{
    totalSize += new FileInfo(file).Length; // добавление размера каждого файла к общему объему
}
double totalSizeInGb = totalSize / 1024 / 1024 / 1024; // перевод в гигабайты
project.SendInfoToLog($"Количество файлов: {files.Length}. Общий объем: {totalSizeInGb:F2} Гб.");
var filePaths = new System.Collections.Generic.List<string>(files);
DirectoryInfo dirInfo = new DirectoryInfo(targetDirectory);
List<string> fileList1 = new List<string>();
List<string> fileList2 = new List<string>();
List<string> report_list = new List<string>();
foreach (string fileName in fileEntries)
{
    fileList1.Add(fileName);
}
string control = string.Empty;
string subpath = string.Empty;
string _report = string.Empty;
int i_d = 0;
subpath = @"OnlyDomains";
_report = targetDirectory + "\\" + subpath + "\\" + "_report.txt";
if (!dirInfo.Exists)
{
    dirInfo.Create();
}
dirInfo.CreateSubdirectory(subpath);
project.SendInfoToLog("Создана субдиректория OnlyDomains");
while (fileList1 != null)
{
    i_d = 0;
    try
    {
        string path = fileList1[0];
        fileList1.RemoveAt(0);
        string name_file = path.Replace(targetDirectory, "");
        string name_file_transit = name_file.Replace("\\", "");
        string name_file_transit_out = name_file_transit.Replace(".txt", "");
        string path_domain = targetDirectory + "\\" + subpath + "\\" + name_file + ".txt";
        using (var writer_domain = new StreamWriter(new BufferedStream(File.OpenWrite(path_domain), 100 * 1024 * 1024)))
        {
            using (var file = new StreamReader(new BufferedStream(File.OpenRead(path), 100 * 1024 * 1024)))
            {
                string line;
                int count = 0; // Счетчик прочитанных строк
                while ((line = file.ReadLine()) != null)
                {
                    string[] text = line.Split('    ');
                    string domain = text[0];
                    domain = domain.TrimEnd('.');
                    if (domain == control)
                    {
                        continue ; // Пропустить дубликаты доменов
                    }
                    if (domain.Contains("."))
                    {
                        string NS = text[3];
                        NS = NS.ToLower();
                        string server = text[4];
                        server = server.TrimEnd('.');
                        if (NS.Contains("dnskey") || NS.Contains("nsec3param") || NS.Contains("nsec3") || NS.Contains("soa") || (NS.Contains("ds") || NS.Contains("a") || NS.Contains("aaaa") || NS.Contains("txt") || NS.Contains("ds") || NS.Contains("rrsig") || NS.Contains("nsec")))
                        {
                            continue ; // Пропустить домены с определенными условиями
                        }
                        string result = domain;
                        fileList2.Add(result);
                        control = domain;
                    }
                    count++;
                    if (count == 10000000)
                    {
                        // Записать обработанные домены в файл
                        foreach (string outline in fileList2)
                        {
                            writer_domain.WriteLine(outline);
                            i_d++;
                        }
                        fileList2.Clear();
                        count = 0;
                    }
                }
                // Записать оставшиеся обработанные домены в файл
                foreach (string outline in fileList2)
                {
                    writer_domain.WriteLine(outline);
                    i_d++;
                }
            }

            fileList2.Clear();
            project.SendInfoToLog("В зоне " + name_file_transit_out + " -  " + i_d + " уникальных доменов");
            string _report_string = name_file_transit_out + "|" + i_d;
            report_list.Add(_report_string);
        }
    }
    catch
    {
        break;
    }
}
int general_count = 0;
foreach (string outline_count in report_list)
{
    string[] text_count = outline_count.Split('|');
    int out_count = int.Parse(text_count[1]);
    general_count = general_count + out_count;
}

string total_count = general_count.ToString();
string full_count = " Total domains - " + total_count;
report_list.Add("_______________________________");
report_list.Add(full_count);
System.IO.StreamWriter writer_report = new System.IO.StreamWriter(_report, true);
{
    foreach (string outline in report_list)
    {
        writer_report.WriteLine(outline);
    }
}
if (writer_report != null) writer_report.Dispose();///
report_list.Clear();
project.SendInfoToLog("Всего уникальных доменов в списках - " + total_count);
project.SendInfoToLog("Обработка списка доменов завершена");

Для многих пользователей таких списков достаточно, но мы сделаем еще кое что.

4. Получение уникальных NS серверов во всех зонах.

Для различных исследований, софта и приложений списки уникальных NS серверов (пусть и не абсолютно все) имеют гораздо большее значение и важность чем сами доменные списки. На просторах интернета также можно найти как коллекции за оплату, так и бесплатные наборы с различной степени актуализации. Имеются и интернет каталоги которые можно распарсить, но если у нас на руках уже есть то что нам нужно - зачем создавать себе проблемы?

Тут логика обработки списков немного отличается от той, которая применялась при обработке уникальных доменов. В отличии от доменов, NS сервера в списке идут не по порядку, многократно повторяются по файлу. Так что как и в предыдущем случае, читаем файлы частями, выбираем только NS сервера, с каждым проходом удаляем дубликаты, по окончанию проверки каждой зоны проводим окончальную чистку выходной коллекции. Почему сначала не собрать а затем не удалить дубликаты? Во первых это извращение, а во вторых не уникальные списки NS содержат миллионы строк и гигабайты объема, можно легко "выбить" память. Также нам стоит по окончанию обработки обработки собрать со всех выходных файлов NS сервера в один общий файл, почистить на дубликаты. Ну и куда же без репорта, нужен список в котором будет указано сколько уникальных NS в каждой зоне и сколько уникальных NS серверов вообще на руках. Так же, ничего сложного, смотрим.


Код для получения уникальных NS серверов:
string path_folder = @"C:\Users\vigan\Desktop\test";
string targetDirectory = path_folder;
string[] fileEntries = Directory.GetFiles(targetDirectory);
var files = Directory.GetFiles(path_folder, "*", SearchOption.TopDirectoryOnly); // получение всех файлов в папке и ее подпапках
double totalSize = 0; // общий объем файлов
foreach (var file in files)
{
    totalSize += new FileInfo(file).Length; // добавление размера каждого файла к общему объему
}
double totalSizeInGb = totalSize / 1024 / 1024 / 1024; // перевод в гигабайты
project.SendInfoToLog($"Количество файлов: {files.Length}. Общий объем: {totalSizeInGb:F2} Гб.");
int file_count = fileEntries.Length;
DirectoryInfo dirInfo = new DirectoryInfo(targetDirectory);
HashSet<string> fileList1 = new HashSet<string>();
HashSet<string> fileList2 = new HashSet<string>();
List<string> report_list = new List<string>();
List<string> fileList3 = new List<string>();
foreach (string fileName in fileEntries)
{
    fileList1.Add(fileName);
}
string subpath_ns = @"OnlyNS";
string _report = Path.Combine(targetDirectory, subpath_ns, "_report.txt");
string path_domain_ns = Path.Combine(targetDirectory, subpath_ns);
if (!dirInfo.Exists)
{
    dirInfo.Create();
}
dirInfo.CreateSubdirectory(subpath_ns);
project.SendInfoToLog("Создана субдиректория  OnlyNS");
while (fileList1.Count > 0)
{
    int i_d = 0;
    try
    {
        string path = fileList1.First();
        fileList1.Remove(path);
        string name_file = Path.GetFileName(path);
        string name_file_transit_out = Path.GetFileNameWithoutExtension(name_file);
        string path_domain = Path.Combine(path_domain_ns, name_file + ".txt");
        using (var writer_domain = new StreamWriter(path_domain, append: false))
        using (var file = new StreamReader(path))
        {
            string line;
            int count = 0;
            while ((line = file.ReadLine()) != null)
            {
                string[] text = line.Split('    ');
                string NS = text[3].ToLower();
                string server = text[4].TrimEnd('.');
                if (!(NS.Contains("dnskey") || NS.Contains("nsec3param") || NS.Contains("nsec3") || NS.Contains("soa") || (NS.Contains("ds") || NS.Contains("a") || NS.Contains("aaaa") || NS.Contains("txt") || NS.Contains("ds") || NS.Contains("rrsig")|| NS.Contains("nsec"))))
                {
                    string result = server.ToLower();
                    fileList2.Add(result);
                }
                count++;
                if (count == 5000000)
                {
                    fileList2.RemoveWhere(item => !fileList2.Contains(item));
                }
            }
            foreach (string outline in fileList2)
            {
                writer_domain.WriteLine(outline);
                i_d++;
            }
            project.SendInfoToLog("В зоне " + name_file_transit_out + " - " + i_d + " уникальных NS серверов");
            string _report_string = name_file_transit_out + "|" + i_d.ToString();
            report_list.Add(_report_string);
            fileList2.Clear();
            count = 0;
        }
    }
    catch
    {
        continue;
    }
}
project.SendInfoToLog("Начата общая сборка всех NS");
string counter_ns = Path.Combine(targetDirectory, subpath_ns);
string targetDirectory_ns = counter_ns;
string[] fileEntries_ns = Directory.GetFiles(targetDirectory_ns);
foreach (string fileName_ns in fileEntries_ns)
{
    fileList3.Add(fileName_ns);
}
while (fileList3.Count > 0)
{
    try
    {
        string path = fileList3[0];
        fileList3.RemoveAt(0);
        using (var file = new StreamReader(path))
        {
            string line;
            while ((line = file.ReadLine()) != null)
            {
                fileList2.Add(line);
            }
        }
    }
    catch
    {
        break;
    }
}
string all = Path.Combine(targetDirectory, subpath_ns, "_all_ns.txt");
int i_d_count = 0;
using (var writer_count = new StreamWriter(all, true))
{
    foreach (string outline in fileList2)
    {
        writer_count.WriteLine(outline);
        i_d_count++;
    }
}
project.SendInfoToLog("Всего уникальных NS в всех списках - " + i_d_count);
string unique = "Total NS unique - " + i_d_count;
report_list.Add("_______________________________");
report_list.Add(unique);
using (var writer_unique = new StreamWriter(_report, true))
{
    foreach (string outline_unique in report_list)
    {
        writer_unique.WriteLine(outline_unique);
    }
}

Ну что же, давайте продолжим и перейдем к следующему пункту кейса.

5. Получение уникальных доменов с принадлежащими им NS серверами с во всех зонах.

Теперь давайте соберем списки в том виде в котором многие их качали с бесплатных раздач или покупали у брокеров данных. Это списки зон которые содержат в себе адрес домена и принадлежащие к этому домену NS сервера. Такие списки в основном и востребованы разными группами пользователей и стоят в продаже на различных сервисах фрилансеров и сайтах брокеров.

Из за того, что тут используется одновременно большой массив входных данных, то как бы я не пытался, но у меня не получилось "разогнать" код. Виной тому бюджетная "машина" с 8 Гб на борту, так что у Вас это может работать быстрей (у меня 45+ минут, но это из за зоны .com). Логика так же отличается от предыдущих. Читаем файл частями, при помощи LINQ собираем данные по каждому конкретному домену в строку и затем сбрасываем с дописыванием в соответствующий доменной зоне файл. Так как в предыдущих частях кода мы получили всю информацию о входящих данных по количеству, уникальности и прочему, то в данном блоке нам это не требуется. Все что необходимо - просто обработка и создание выходных файлов с указанными в заголовке параметрами. Смотрим.


Domains and NS:
string path_folder = @"C:\Users\vigan\Desktop\test";
string targetDirectory = path_folder;
string[] fileEntries = Directory.GetFiles(targetDirectory);
var files = Directory.GetFiles(path_folder, "*", SearchOption.TopDirectoryOnly);
double totalSize = 0;
foreach (var file in files)
{
    totalSize += new FileInfo(file).Length;
}
double totalSizeInGb = totalSize / 1024 / 1024 / 1024;
project.SendInfoToLog($"Количество файлов: {files.Length}. Общий объем: {totalSizeInGb:F2} Гб.");
int file_count = fileEntries.Length;
DirectoryInfo dirInfo = new DirectoryInfo(targetDirectory);
HashSet<string> fileList1 = new HashSet<string>();
HashSet<string> fileList2 = new HashSet<string>();
List<string> report_list = new List<string>();
List<string> fileList3 = new List<string>();
foreach (string fileName in fileEntries)
{
    fileList1.Add(fileName);
}
string subpath = @"DomainsAndNS";
string subdirectoryPath = Path.Combine(targetDirectory, subpath);
if (!dirInfo.Exists)
{
    dirInfo.Create();
}
if (!Directory.Exists(subdirectoryPath))
{
    Directory.CreateDirectory(subdirectoryPath);
    project.SendInfoToLog("Создана субдиректория  DomainsAndNS");
}
while (fileList1.Count > 0)
{
    try
    {
        string path = fileList1.ElementAt(0);
        fileList1.Remove(path);
        string name_file = path.Replace(targetDirectory, "");
        string name_file_transit = name_file.Replace("\\", "");
        string name_file_transit_out = name_file_transit.Replace(".txt", "");
        string path_domain = Path.Combine(subdirectoryPath, name_file_transit_out + ".txt");
        using (var file = new StreamReader(new BufferedStream(File.OpenRead(path), 100 * 1024 * 1024)))
        {
            int count = 0;
            string line;
            while ((line = file.ReadLine()) != null)
            {
                string[] text = line.Split('\t');
                string NS = text[3].ToLower();
                string server = text[4].TrimEnd('.');
                if (!(NS.Contains("dnskey") || NS.Contains("nsec3param") || NS.Contains("nsec3") || NS.Contains("soa") || NS.Contains("ds") || NS.Contains("a") || NS.Contains("aaaa") || NS.Contains("txt") || NS.Contains("rrsig")|| NS.Contains("nsec")))
                {
                    string domain = text[0];
                    domain = domain.TrimEnd('.');
                    string result = domain + " | " + server;
                    fileList2.Add(result);
                    count++;
                    if (count == 1000000)
                    {
                        var list2 = new List<string>();
                        fileList2.GroupBy(x => x.Split('|').First().Trim())
                            .ToList()
                            .ForEach(x => list2.Add(string.Join(" | ", new[]
                            {
                                x.Key, string.Join(", ", x.Select(v => v.Split('|').Last().Trim()))
                            })));
                        fileList3.Add(string.Join("\n", list2));
                       using (StreamWriter writer = new StreamWriter(path_domain, append: true))
                        {
                            foreach (string outline in fileList3)
                            {
                                writer.WriteLine(outline);
                            }
                        }
                        fileList3.Clear();
                        fileList2.Clear();
                        count = 0;
                    }
                }
            }
            if (fileList2.Count > 0)
{
var list2 = new List<string>();
fileList2.GroupBy(x => x.Split('|').First().Trim())
.ToList()
.ForEach(x => list2.Add(string.Join(" | ", new[]
{
x.Key, string.Join(", ", x.Select(v => v.Split('|').Last().Trim()))
})));
                fileList3.Add(string.Join("\n", list2));
                using (StreamWriter writer = new StreamWriter(path_domain, append: true))
            {
                foreach (string outline in fileList3)
                {
                    writer.WriteLine(outline);
                }
            }
            fileList3.Clear();
            fileList2.Clear();
        }
        using (StreamWriter writer_domain = new StreamWriter(path_domain, append: true))
        {
            foreach (string outline in fileList2)
            {
                writer_domain.WriteLine(outline);
            }
            project.SendInfoToLog("Зона  " + name_file_transit_out + " обработана");
        }
    }
}
catch
{
    continue;
}

}

На этом мы закончили данный мини кейс по получению доменных списков из тематических зон ICANN. Конечно же самих зон гораздо больше , это зоны конкретных страновых геозон (DE,UK, PL .... e.t.c.) а также их суффиксов (com.au, gov.lt ...e.t.c.) и так далее. Но данный кейс только по ICANN.

6. Заключение

Ну что же, как мы с вами смогли убедиться, Zennoposter это очень мощный инструмент и позволяет делать вроде бы сложные вещи быстро и эффективно. А с возможностью писать код на C# настолько масштабируют его возможности что они почти безграничны. Надеюсь что данный мини кейс поможет многим пользователям всегда иметь под рукой актуальные наборы данных (доменные списки) , а в случае необходимости очень быстро их скачать и обработать, ведь как я показывал - скорость обработки достаточна высока. Пусть мой код не идеален, но так и я не кодер, а всего лишь любитель самоучка.

Конечно, мы рассмотрели только базовую обработку, ну и автоматическое получение списков, но на самом деле это только верхушка айсберга. Кому возможно нужны только ключи зон для фильтрации трафика, кому то только корневые NS для дальнейшей обработки доменных списков (как вариант получение mx/txt.dkim/dmarc e.t.c. при помощи, например DNSClient от Micha Conrad), кому то надо пропинговать домены и получить при помощи наборов данных от IANA geo-данные о расположение парковок сайтов чтобы не "воткнуться" в законы GDPR или 152-Ф3, кому то (в основном пентестерам но не ограничиваясь ими) необходимо из набора NS серверов при помощи таблицы суффиксов Mozzilla вычислить хостинг провайдеров для базового понимания на каких предположительно технологиях может работать сайт/сайты для сужения набора инструментов для исследований. Этот список можно продолжать и продолжать и одной статьи для этого конечно недостаточно. Но все же - пишите в комментариях чтобы вы еще хотели увидить, какие вопросы вас интересуют и я по возможности быстро - постараюсь подготовить для вас решение в открытом доступе на базе Zennoposter.

На этом у меня все, доброго дня и удачи всем участникам конкурса!
Ну и сложную же тему вы написали, аж мозг взрывается)))
 
  • Спасибо
Реакции: DevOps

Дмитрий202020

Активный пользователь
Регистрация
15.09.2020
Сообщения
265
Благодарностей
61
Баллы
28
Без бутылки водки и блока сигарет не разберешься, по этому я в магаз :D
 
  • Спасибо
Реакции: DevOps

molotok

Client
Регистрация
17.04.2015
Сообщения
733
Благодарностей
358
Баллы
63
Для чего эти домены можно использовать?
 
  • Спасибо
Реакции: djaga

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
Ну и сложную же тему вы написали, аж мозг взрывается)))
На самом деле все очень просто. Тем более приложенный код не требует никаких лишних телодвижений кроме как указать путь к папке.
И в тоже время, если развернуть эту тему и мсоделировать данные то можно организовать неплохой бизнес. Посмотрите сколько стоят обогощеные наборы таких данных на Западе
 
  • Спасибо
Реакции: yuresd

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
Для чего эти домены можно использовать?
Цели могут самые разные, от продажи наборов, сборов данных, проведения аналитики, создание собственных интерактивных каталогов с использованием Shema схем с целью привлечения трафика на свой основной сайт, до пентеста. На самом деле все варианты просто невозможно даже озвучить
 
Последнее редактирование:
  • Спасибо
Реакции: SERG454 и molotok

seodamage

Client
Регистрация
08.09.2014
Сообщения
197
Благодарностей
52
Баллы
28
Шикарно, ушёл регаться в icann) желаю занять призовое место

по поводу обработки если стоит задача только получить домены, можно попробовать сделать всё через awk на бесплатной оракловской впске где 24 гига оперы)

что то типо того

Bash:
awk '{print $1}' /tmp/domains/* >> /tmp/domains/result.txt
затем убрать дубли
и точку в конце строки поменять на конец строки
 
Последнее редактирование:
  • Спасибо
Реакции: DevOps

Gfoblin

Client
Регистрация
30.05.2013
Сообщения
4 518
Благодарностей
990
Баллы
113
Мож есть возможность ловить то что экспайрится? )
 

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
Шикарно, ушёл регаться в icann) желаю занять призовое место

по поводу обработки если стоит задача только получить домены, можно попробовать сделать всё через awk на бесплатной оракловской впске где 24 гига оперы)

что то типо того

Bash:
awk '{print $1}' /tmp/domains/* >> /tmp/domains/result.txt
затем убрать дубли
и точку в конце строки поменять на конец строки
Спасибо что напомнили. Как раз думал куда запарковать прокси судью
 
  • Спасибо
Реакции: seodamage

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
По пингу. Если Вам необходимо пропинговать какую нибудь большую зону, то это стоит проводить на сервере с широким каналом. Если под рукой есть такая техника - то можно при помощи DNSClient собрать решение которое позволит обходить ограничение провайдера (не будет использовать для запросов dns интернет провайдера) и может, (на бенче) отправлять до 80/100 000 запросов в секунду.

Если же Вам необходимо пропинговать те же ns сервера чтобы потом по ГЕО определить местоположения парковок, то можно использоватиь примитив. Смотрим


Ну и сам код который может во многопотоке на любой лицензии пропинговать адреса во многопоточном режиме (хоть 10 хоть 10 000)

Pinger:
string inputFile = @"C:\Users\vigan\Desktop\test\IP\_all_ns.txt";
string outputFile = @"C:\Users\vigan\Desktop\test\IP\good.txt";
string badResultsFile = @"C:\Users\vigan\Desktop\test\IP\bad.txt";
int numThreads = 250;
var urls = File.ReadAllLines(inputFile);
var resultDict = new ConcurrentDictionary<string, IPAddress>();
var badResultsDict = new ConcurrentDictionary<string, string>();
Parallel.ForEach(urls, new ParallelOptions { MaxDegreeOfParallelism = numThreads }, url =>
{
    try
    {
        IPHostEntry hostEntry = Dns.GetHostEntry(url);
        IPAddress ipAddress = hostEntry.AddressList[0];
        project.SendInfoToLog(url+" | "+ipAddress.ToString());
        resultDict.TryAdd(url, ipAddress);
    }
    catch (Exception ex)
    {
       string error = $"Error processing URL: {url} - {ex.Message}";
        badResultsDict.TryAdd(url,error);
    }
});
using (StreamWriter writer = new StreamWriter(outputFile))
{
    foreach (var kvp in resultDict)
    {
        writer.WriteLine($"{kvp.Key}|{kvp.Value}");
    }
}
using (StreamWriter writer = new StreamWriter(badResultsFile))
{
    foreach (var kvp in badResultsDict)
    {
        writer.WriteLine($"{kvp.Key}|{kvp.Value}");
    }
}
 
  • Спасибо
Реакции: seodamage

bad robot

Client
Регистрация
07.03.2011
Сообщения
178
Благодарностей
28
Баллы
28
хотелось бы видеть реальный кейс монетизации этих данных
 

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
хотелось бы видеть реальный кейс монетизации этих данных
Это кейс по автоматическому получению и обработке данных. В категории -* Нестандартные хаки. Это не про заработок - это про информацию.
Но если Вы не очень спешите - то подпишитесь на обновления - я в данной ветке продолжу эту тему, в том числе и по монетизации. Не тупо продаже наборов данных (хотя и это будет) а по применению этих данных для заработка.
 

Gfoblin

Client
Регистрация
30.05.2013
Сообщения
4 518
Благодарностей
990
Баллы
113
Не совсем понял вопрос, если не сложно - разверните его
Ну домен заканчивается и он освобождается, минуя expireddomains.net - можно словить это событие может в курсе?
 
  • Спасибо
Реакции: AlisaZ

AlisaZ

Client
Регистрация
17.09.2014
Сообщения
159
Благодарностей
174
Баллы
43
Главное чтоб обещанное не осталось словами, а реально было как обещано )))
 
  • Спасибо
Реакции: DevOps и djaga

seodamage

Client
Регистрация
08.09.2014
Сообщения
197
Благодарностей
52
Баллы
28

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
Ну домен заканчивается и он освобождается, минуя expireddomains.net - можно словить это событие может в курсе?
Во первых спасибо за ссылку, я потерял закладку с этим сайтом. Второе - непосредственно из списков ICANN такую информацию нельзя получить. Это нужно через whois/rdap собирать информацию либо по определнной зоне, либо проверять все и складывать в БД. По зоне ру/рф/су - можно выкачать список всех когда либо зарегистрированных доменов в этих зонах и сравнить с текущим списком (действующим) - разница и будет свободные домены. Но опять таки нужно учитывать что не каждый освобождающийся и свободный домен может быть полезен. Их необходимо проверять на блокировки, наличие в черных списках и спам листах.
 
  • Спасибо
Реакции: Gfoblin

seodamage

Client
Регистрация
08.09.2014
Сообщения
197
Благодарностей
52
Баллы
28
Вы можете скачать то что есть. При следующем скачивании скрипт PowerShell не будет какчать зоны которые уже есть в папке
я лучше потом за раз все обработаю :ay:

По зоне ру/рф/су - можно выкачать список всех когда либо зарегистрированных доменов в этих зонах и сравнить с текущим списком (действующим) - разница и будет свободные домены.
по этим доменам выкачиваю таким способом https://antoshabrain.blogspot.com/2017/07/Spiski-Vseh-Domenov-RU-SU-RF.html
 
  • Спасибо
Реакции: DevOps

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
я лучше потом за раз все обработаю :ay:
- Имейте в виду - некоторые админы мгут тупо забивать и наборы будут висеть в pending довольно долго. Основные зоны апроувятся быстро, бизнес - могут задерживать, экзотические как раз могу висеть долго. Также отклонят пару тройку десятков зон, но там не публичные многие.

по этим доменам выкачиваю таким способом https://antoshabrain.blogspot.com/2017/07/Spiski-Vseh-Domenov-RU-SU-RF.html
Спасибо, тоже потерял эту закладку при переезде. Как раз комментатору выше это в тему если работает по русскому сегменту. Жаль только что они парсят без ns серверов
 
Последнее редактирование:
  • Спасибо
Реакции: seodamage

GreenWay

Client
Регистрация
11.05.2012
Сообщения
428
Благодарностей
132
Баллы
43
Под такие объемы в самый раз БД использовать, например SQLite
 
  • Спасибо
Реакции: DevOps

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
Под такие объемы в самый раз БД использовать, например SQLite
На данном этапе пока нет. Объем пока еще совсем маленький. Да и не стоит задача для быстрой выдачи, а вот чуть дальше, да, уже будет и БД
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 680
Благодарностей
1 863
Баллы
113
Спасибо за полезную информацию, подробности и примеры кода. :ay: :ay:
 
  • Спасибо
Реакции: DevOps

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
Спасибо за полезную информацию, подробности и примеры кода. :ay: :ay:
В комментариях будет продолжение. Все кейсы уложить в формат статьи не получилось, записываю потихоньку. Тем более тема для своих проектов весьма необходима (упс, спойлер :-) )
 
  • Спасибо
Реакции: seodamage и radv

radv

Client
Регистрация
11.05.2015
Сообщения
3 680
Благодарностей
1 863
Баллы
113
Домены всегда нужны для онлайн работы )
 
  • Спасибо
Реакции: DevOps

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
Домены всегда нужны для онлайн работы )
Спойлер #2

Домены, NS/MX/TXT 21/23/25 порты, CMS и технологии, Хостеры и провайдеры, диапазоны адресов и RIR/LIR/AS
Все это в разной степени готовности. Очень трудно переносить с VS в ZP
 

d4k

Client
Регистрация
24.12.2014
Сообщения
27
Благодарностей
5
Баллы
3
Мой голос сюда! Пока что лучшая работа в конкурсе, ИМХО.
 
  • Спасибо
Реакции: Hannes, seodamage и DevOps

DevOps

Client
Регистрация
30.11.2020
Сообщения
496
Благодарностей
313
Баллы
63
Мой голос сюда! Пока что лучшая работа в конкурсе, ИМХО.
Мне тоже всегда по душе были именно технические статьи в конкурсах, поэтому долго и не писал, не было подходящего кейса
 
  • Спасибо
Реакции: d4k

Nord

Client
Регистрация
22.03.2012
Сообщения
2 375
Благодарностей
1 435
Баллы
113

Nord

Client
Регистрация
22.03.2012
Сообщения
2 375
Благодарностей
1 435
Баллы
113
заработало, когда заменил это на

C#:
string[] text = line.Split('\t');
В коде 4 пробела, когда я вставил в прошлом ответе - вставился один) Возможно, так же само табуляция превратилась в те 4 пробела
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)