Привет коллеги, эта статья пригодится как продвинутым разведчикам, так и начинающим малышам, которые только начинают свой путь.
=====================================================================================================================================================================================================Суть: автоматизация процессов сетевой разведки.
Проблема: невозможно объять необъятный интернет
Компромис: поисковики стоят денег, и теряют свою актуальность из-за высокого спроса и соответствующего ажиотажа
Получается картина маслом, дорого или беспонтово.
не скрою, я изучал материалы лево и право сидящих на данном форуме коллег, и имея свой опыт, и собрав воедино свои знания и их почву для размышления - сделал роадмап пентеста популярных сервисов, впн шлюзов и сочных платформ, объеденив в этих скриптах рациональное использование арендованных ресурсов сервера с которого идет брут и категорически понятную визуализацию получаемой выгрузки.
И так, первое что нам нужно - весь интернет, берем вот эту историю
Этот репозиторий содержит диапазоны IP-адресов CIDR для IPv4 и IPv6 для всех стран. Его цель — предоставить полный и актуальный список диапазонов IP-адресов, сгруппированных по странам, для упрощения управления сетью, использования геолокационных сервисов и многого другого. :dash: Этот репозиторий обновляется каждый час
Репозиторий организован по странам, и в каждой стране есть свой каталог. В каждом каталоге вы найдёте два файла:
- *-ipv4-Hackers.Zone.txt: Содержит диапазоны CIDR для IPv4.
совмещаем приятное с полезным, я как то уже писал вот тут про сетевой маркер тык. Главное что нам нужно понять - как с минимальным количеством маркеров идентифицировать уникальный отпечаток, который не будет содержать двузначное или неточное отпределение того что мы ищем.
Мое целью были криптошлюзы Fortigate.
Не удалось прогрузить медиа
Я решил взять топ 20 портов на которых потенциально форточки, однако потом столкнулся с тем, что из моей выборки в 72 млн строк, 36 миллионов строк окалзались 443 порртом, проще говоря - 50 процентов потенциального шлака. Чуть позже расскажу как я это перерабатывал.
Первый этап нашей большой выборки - идентифицировать порты, и нам поможет masscan, но не совсем простой. Мы не можем передать ему одной пачкой пулл текстовых файлов с подсетями общим колличеством 200+ стран, значит нам нужно написать скрипт, и чем менне избыточный он будет, тем более отказоустойчиво он будет работать без нашего вмешательства.
функционал:
анализ ./input
в нем хранятся каталоги по странам, в каталоге *.txt с подсетями
пишет в ./output
Не удалось прогрузить медиа
В этот же момент серевер работает бесперебойно 14 дней
Не удалось прогрузить медиа
внутри каталога - страны следующее содержимое
Не удалось прогрузить медиа
явная, понятная, четковыраженная структура, которую удобно фильтровать инструментами примитивной сортировки через bash - grep,wc,find, awk и другие
Bash:
#!/bin/bash
export LC_ALL=C.UTF-8
export LANG=C.UTF-8
OUTPUT_DIR="./result"
INPUT_DIR="./zhratva"
TIMEOUT_SEC=216000000
mkdir -p "$OUTPUT_DIR"
if ! touch "$OUTPUT_DIR/.test" 2>/dev/null; then
echo "❌ НЕТ ПРАВ НА ЗАПИСЬ В $OUTPUT_DIR"
echo "Выполните:"
echo " sudo chmod 755 $OUTPUT_DIR"
echo " sudo chown \$USER:\$USER $OUTPUT_DIR"
exit 1
else
rm -f "$OUTPUT_DIR/.test"
echo "✅ Права на $OUTPUT_DIR — ОК"
fi
if ! command -v masscan &> /dev/null; then
echo "❌ masscan не установлен"
exit 1
fi
MASSCAN_CONFIG_TEMPLATE='
ports = 7443,443,8443,10443,444,541,4433,1723,1443,7443,6434,5443,9943,8083
rate = 10000000
exclude = 255.255.255.255
output-format = list
'
for file in "$INPUT_DIR"/*.txt; do
[ ! -f "$file" ] && continue
filename=$(basename "$file" .txt)
echo "========================================"
echo "🔍 ОБРАБОТКА: $filename"
echo "📂 Входной файл: $file"
cleaned_file=$(mktemp)
grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$' "$file" > "$cleaned_file"
if [ ! -s "$cleaned_file" ]; then
echo "⚠️ Нет валидных подсетей — пропускаем"
rm -f "$cleaned_file"
continue
fi
result_file="$OUTPUT_DIR/scan_result_${filename}.txt"
echo "💾 Результат будет сохранён: $result_file"
temp_config=$(mktemp)
{
echo "$MASSCAN_CONFIG_TEMPLATE"
echo "includefile = $cleaned_file"
} > "$temp_config"
echo "⚙️ Конфиг: $temp_config"
if ! touch "$result_file" 2>/dev/null; then
echo "❌ НЕ МОГУ СОЗДАТЬ $result_file — проверьте права"
rm -f "$cleaned_file" "$temp_config"
continue
else
rm -f "$result_file"
fi
echo "🚀 ЗАПУСКАЕМ:"
echo " masscan -c \"$temp_config\" -oL \"$result_file\""
timeout "$TIMEOUT_SEC" masscan -c "$temp_config" -oL "$result_file"
if [ -f "$result_file" ]; then
size=$(wc -c < "$result_file")
echo "✅ Файл $result_file создан, размер: $size байт"
if [ $size -gt 0 ]; then
echo "📄 Первые 5 строк:"
head -5 "$result_file"
else
echo "⚠️ Файл пуст — возможно, ничего не найдено"
fi
else
echo "❌ Файл $result_file НЕ создан — проверьте masscan и права"
fi
rm -f "$cleaned_file" "$temp_config"
echo "🧹 Временные файлы удалены"
echo "========================================"
done
echo "🏁 СКРИПТ ЗАВЕРШЁН"
ls -l "$OUTPUT_DIR"/scan_result_*.txt 2>/dev/null || echo "❌ Нет файлов scan_result_*.txt"
в результате было написано много скриптов по работе с данной выгрузго=кой, вот что выдала статистика:
Python:
#!/usr/bin/env python3
import os
import re
from pathlib import Path
# --- Настройки ---
RESULT_DIR = "./input — копия"
OUTPUT_BASE_DIR = "./countries"
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10 МБ
# --- Регулярное выражение для поиска строк формата: open tcp <порт> <IP> <timestamp> ---
pattern = re.compile(r'open\s+tcp\s+(\d+)\s+([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})')
def is_valid_ip(ip):
"""Проверяет, что IP состоит из 4 октетов от 0 до 255"""
try:
parts = list(map(int, ip.split('.')))
return len(parts) == 4 and all(0 <= p <= 255 for p in parts)
except ValueError:
return False
def main():
result_path = Path(RESULT_DIR)
output_base_path = Path(OUTPUT_BASE_DIR)
# Проверяем, существует ли папка с результатами
if not result_path.exists() or not result_path.is_dir():
print(f"❌ Папка {RESULT_DIR} не существует или это не директория.")
return
# Создаём базовую папку вывода
output_base_path.mkdir(exist_ok=True)
# Находим все файлы scan_result_*-ipv4-Hackers.Zone.txt
files = list(result_path.glob("*.txt"))
if not files:
print(f"❌ Не найдено ни одного файла scan_result_*-ipv4-Hackers.Zone.txt в {RESULT_DIR}")
return
print(f"🔍 Найдено {len(files)} файлов для обработки")
# --- Статистика ---
total_urls_written = 0
countries_processed = set()
ports_found = set()
files_created = 0
# Подробная статистика
country_stats = {} # { 'AD': { 'urls': 1000, 'unique_ips': set(), 'ports': { '443': 300, '8443': 700 } }, ... }
port_stats = {} # { '443': 3000, '8443': 1500, ... }
all_unique_ips = set() # Все уникальные IP за сессию
# --- /Статистика ---
for file in files:
print(f"\n📂 Обрабатываем: {file.name}")
# Извлекаем код страны из имени файла
# Пример: scan_result_AD-ipv4-Hackers.Zone.txt -> AD
name_part = file.name.replace("scan_result_", "").split("-")[0]
country_code = name_part.upper()
# Папка для вывода: по коду страны
country_dir = output_base_path / country_code
country_dir.mkdir(exist_ok=True)
print(f" 🌍 Код страны: {country_code}")
countries_processed.add(country_code)
# Инициализируем статистику для страны
if country_code not in country_stats:
country_stats[country_code] = {'urls': 0, 'unique_ips': set(), 'ports': {}}
try:
with open(file, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
matches = pattern.findall(content)
# Словарь: порт -> список URL
port_to_urls = {}
for port_str, ip in matches:
if not is_valid_ip(ip):
print(f" 🗑️ Пропущен невалидный IP: {ip}")
continue
port = port_str.strip()
url = f"https://{ip}:{port}"
ports_found.add(port)
if port not in port_to_urls:
port_to_urls[port] = []
port_to_urls[port].append((url, ip)) # Сохраняем и URL, и IP
# Для каждого порта создаём файлы с нумерацией и ограничением по размеру
for port, url_ip_pairs in port_to_urls.items():
current_file_index = 0
current_file_path = country_dir / f"{port}-{current_file_index}.txt"
current_file = open(current_file_path, 'w', encoding='utf-8')
current_size = 0
for url, ip in url_ip_pairs:
line = url + "\n"
line_size = len(line.encode('utf-8'))
if current_size + line_size > MAX_FILE_SIZE:
current_file.close()
files_created += 1
current_file_index += 1
current_file_path = country_dir / f"{port}-{current_file_index}.txt"
current_file = open(current_file_path, 'w', encoding='utf-8')
current_size = 0
current_file.write(line)
current_size += line_size
# Обновляем статистику
total_urls_written += 1
country_stats[country_code]['urls'] += 1
all_unique_ips.add(ip)
country_stats[country_code]['unique_ips'].add(ip)
if port not in country_stats[country_code]['ports']:
country_stats[country_code]['ports'][port] = 0
country_stats[country_code]['ports'][port] += 1
if port not in port_stats:
port_stats[port] = 0
port_stats[port] += 1
current_file.close()
files_created += 1
print(f" 💾 Записано {len(url_ip_pairs)} URL в файлы {port}-*.txt")
except Exception as e:
print(f"❌ Ошибка при чтении файла {file}: {e}")
# --- Вывод статистики ---
print("\n" + "="*60)
print("📊 СТАТИСТИКА ПО ОБРАБОТКЕ:")
print(f" 📁 Всего файлов обработано: {len(files)}")
print(f" 🌍 Всего стран: {len(countries_processed)}")
print(f" 🌐 Уникальных портов: {len(ports_found)}")
print(f" 📄 Всего файлов создано: {files_created}")
print(f" 🌐 Всего URL записано: {total_urls_written}")
print(f" 🌐 Всего уникальных IP адресов: {len(all_unique_ips)}")
print("-" * 60)
print("📈 СТАТИСТИКА ПО СТРАНАМ:")
for code, data in sorted(country_stats.items()):
unique_ips_count = len(data['unique_ips'])
print(f" 🌍 {code}: {data['urls']} URL, {unique_ips_count} уникальных IP")
for port, count in sorted(data['ports'].items()):
print(f" └─ Порт {port}: {count} URL")
print("-" * 60)
print("📈 СТАТИСТИКА ПО ПОРТАМ:")
for port, count in sorted(port_stats.items()):
print(f" 🌐 Порт {port}: {count} URL")
print("="*60)
# --- /Статистика ---
print(f"\n✅ Обработка завершена. Файлы сохранены в папке: {OUTPUT_BASE_DIR}")
if __name__ == "__main__":
main()
ИТОГО:
:chart_with_upwards_trend: СТАТИСТИКА ПО ПОРТАМ:
:globe_with_meridians: Порт 10443: 2976954 URL
:globe_with_meridians: Порт 1443: 2835310 URL
:globe_with_meridians: Порт 1723: 3773315 URL
:globe_with_meridians: Порт 443: 36221985 URL
:globe_with_meridians: Порт 4433: 2921649 URL
:globe_with_meridians: Порт 444: 2904445 URL
:globe_with_meridians: Порт 541: 2936708 URL
:globe_with_meridians: Порт 5443: 2647170 URL
:globe_with_meridians: Порт 6434: 2437077 URL
:globe_with_meridians: Порт 7443: 2816016 URL
:globe_with_meridians: Порт 8083: 2938710 URL
:globe_with_meridians: Порт 8443: 7778597 URL
:globe_with_meridians: Порт 9943: 2624854 URL
39 590 805 (остальные) + 36 221 985 (порт 443) = 75 812 790
Этого достаточно, чтобы устроить бомбардиро крокодило, а на сдачу забрутить argo cd
Итак, что у нас есть за две недели - в сухом остатке, с учетом что в данной выборке могут быть не только фортики, но и cisco - приличным объем для последующей обработки.
Эти два простеньких скрипта можно взять за основу под любую цель, потомучто они универсальные.
Если данная статья наберет некоторый успех - подготовлю вторую часть, в которой расскажу, как whois может помочь сузить выборку, как я написал многопточный мультичекер по поиску живых банеров и как я грамотно отправлял выборку на переработку, а на сдачу купил мороженного.
С вами был трудяга Майк, всем успехов!
👍53
❤️11
🔥11
😁6
🤔6
💯7
LIMB