Как стать автором
Обновить

Сравнение нейросетей для создания ПО. Для сканирования хостов и поиска никнеймов

Время на прочтение21 мин
Количество просмотров2.3K

Приветствуем дорогих читателей! Начинаем рубрику посвящённую нейросетям и их применению в сфере ИБ. В этой статье мы сравним 3 самых популярных и одну малоизвестную ИИ в разработке скриптов для эффективного поиска никнеймов и сканирования хостов на уязвимости.

Дисклеймер: Все данные, предоставленные в статье, взяты из открытых источников. Не призывают к действию и предоставлены только для ознакомления и изучения механизмов используемых технологий.

Постановка задачи

Предположим что требуется создать два скрипта на ЯП Python. Первый скрипт должен сканировать маску подсети или отдельно взятые хосты на сбор следующей информации: открытые порты, сервисы использующие порты и их версии, поиск CVE под эти сервисы. Второй скрипт должен искать никнейм в социальных сетях и иных интернет-ресурсов актуальных для СНГ, в том числе предоставлять краткую информацию о аккаунте если она имеется. В качестве тестируемых ИИ возьмём: ChatGPT, Perplexity, DeepSeek и Together.

Этапы создания и промпты к ним

Этапы создания сетевого сканера:

  • Сканирование сети.

    • Промпт: “Напиши на python сетевой сканер в котором можно задавать в параметрах собственную маску подсети”;

  • Сканирование устройств на открытые порты и версии доступных сервисов.

    • Промпт: “Теперь нужно чтобы он сканировал порты и отображал работающие на них сервисы с версией ПО”;

  • Поиск CVE по сервисам и их версиям.

    • Промпт: “Теперь добавь поиск уязвимостей по каждому сервису”.

Этапы создания скрипта для поиска никнейма:

  • Проверка наличия на популярных соц.сетях и интернет-ресурсах в странах СНГ.

    • Промпт: “Напиши скрипт на Python для поиска никнейма по самым популярным социальным сетям и ресурсам СНГ”;

  • Выдача краткой информации по каждой найденной учётной записи.

    • Промпт: “Теперь нужно добавить краткую информацию к каждому найденному аккаунту”.

После тестов будем проводить анализ кода каждого скрипта который получиться в итоге.

Инструмент GodMode

Для наибольшего удобства возьмём проект с открытым исходным кодом GodMode, он позволяет превратить браузер Chromium в интерактивную панель для группового запроса в несколько нейросетей.

Установка заключается в клонировании репозитория и его установки через npm:

git clone https://github.com/smol-ai/GodMode.git
cd GodMode
npm install --force
npm run start

Тест ChatGPT

Создание сетевого сканера

Сканирование сети

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

Сканирование устройств на открытые порты и версии доступных сервисов

Здесь скрипт сработал как и требовалось, видны открытые порты и сервисы на них. Бонусом показан код HTML-страницы которая лежит на 80ом порту. Отображаются состояния сервисов(Bad Request/ready), что добавляет удобства анализу.

Поиск CVE по сервисам и их версиям

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

#!/usr/bin/env python3

import ipaddress
import subprocess
import concurrent.futures
import argparse
import socket
import platform

# 🔐 Локальная база уязвимостей
VULNERABILITIES = {
    "apache/2.4.49": ["CVE-2021-41773", "CVE-2021-42013"],
    "nginx/1.18.0": ["CVE-2021-23017"],
    "openssh_7.2p2": ["CVE-2016-0777"],
    "mysql 5.7.29": ["CVE-2020-2574"],
    "proftpd 1.3.5": ["CVE-2019-12815"],
    "vsftpd 2.3.4": ["CVE-2011-2523"]
}

def banner():
    print("="*60)
    print("     Сетевой сканер с определением сервисов и CVE")
    print("="*60)

def is_host_alive(ip):
    try:
        param = "-n" if platform.system().lower() == "windows" else "-c"
        result = subprocess.run(
            ["ping", param, "1", "-W", "1", str(ip)],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL
        )
        return ip if result.returncode == 0 else None
    except Exception:
        return None

def grab_banner(ip, port):
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.settimeout(1)
            s.connect((str(ip), port))
            s.sendall(b"\r\n")
            banner = s.recv(1024).decode(errors="ignore").strip()
            return banner
    except:
        return ""

def scan_port(ip, port):
    try:
        with socket.socket() as s:
            s.settimeout(0.5)
            s.connect((str(ip), port))
            banner = grab_banner(ip, port)
            return (port, banner)
    except:
        return None

def scan_host_ports(ip, ports):
    open_ports = []
    for port in ports:
        result = scan_port(ip, port)
        if result:
            port, banner = result
            open_ports.append((port, banner))
    return open_ports

def scan_network(subnet, ports):
    active_hosts = []
    with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:
        futures = {executor.submit(is_host_alive, ip): ip for ip in ipaddress.IPv4Network(subnet)}
        for future in concurrent.futures.as_completed(futures):
            ip = future.result()
            if ip:
                print(f"[+] Хост активен: {ip}")
                active_hosts.append(ip)

    print("\n[~] Сканирование портов на активных хостах...\n")
    for ip in active_hosts:
        open_ports = scan_host_ports(ip, ports)
        if open_ports:
            print(f"[•] Хост {ip} — открытые порты:")
            for port, banner in open_ports:
                service = identify_service(banner, port)
                cves = find_vulnerabilities(banner)
                print(f"    [+] Порт {port}/tcp | Сервис: {service} | Баннер: {banner}")
                if cves:
                    print(f"        [!] Уязвимости: {', '.join(cves)}")
            print()
        else:
            print(f"[-] Хост {ip}: открытых портов не найдено.\n")

def identify_service(banner, port):
    if banner:
        banner = banner.lower()
        if "ftp" in banner:
            return "FTP"
        elif "ssh" in banner:
            return "SSH"
        elif "http" in banner:
            return "HTTP"
        elif "smtp" in banner:
            return "SMTP"
        elif "mysql" in banner:
            return "MySQL"
        elif "rdp" in banner or "remote desktop" in banner:
            return "RDP"
        elif "smb" in banner:
            return "SMB"
        elif "telnet" in banner:
            return "Telnet"
    known_ports = {
        21: "FTP", 22: "SSH", 23: "Telnet", 25: "SMTP", 53: "DNS",
        80: "HTTP", 110: "POP3", 139: "SMB", 143: "IMAP", 443: "HTTPS",
        3306: "MySQL", 3389: "RDP", 8080: "HTTP-Alt"
    }
    return known_ports.get(port, "Неизвестно")

def find_vulnerabilities(banner):
    banner = banner.lower()
    found = []
    for vuln_banner, cves in VULNERABILITIES.items():
        if vuln_banner in banner:
            found.extend(cves)
    return found

def main():
    banner()
    parser = argparse.ArgumentParser(description="Сканирование сети и сервисов с CVE.")
    parser.add_argument("subnet", help="Подсеть для сканирования, например 192.168.1.0/24")
    parser.add_argument("--ports", help="Список портов через запятую (по умолчанию популярные)", default="21,22,23,25,53,80,110,139,143,443,3306,3389,8080")
    args = parser.parse_args()

    try:
        port_list = [int(p.strip()) for p in args.ports.split(",")]
        print(f"[~] Сканирование подсети: {args.subnet}")
        scan_network(args.subnet, port_list)
    except ValueError:
        print("[!] Ошибка: неверный формат портов или подсети.")

if __name__ == "__main__":
    main()

Создание скрипта для поиска никнеймов

Проверка наличия на популярных соц.сетях и интернет-ресурсах в странах СНГ

Выдача результатов удобная, имеются статусы отображения(Найден/Нет/Ошибка подключения), список соц.сетей и интернет-ресурсов соответствует действительности.

Выдача краткой информации по каждой найденной учётной записи

Изменения в коде снизили эффективность, видно значительное сокращение списка ресурсов.** Это произошло на этапе промпта “Теперь нужно добавить краткую информацию к каждому найденному аккаунту”. Но в целом с поставленной задачей справился нормально.

#!/usr/bin/env python3

import requests
import concurrent.futures
import argparse
import re
from bs4 import BeautifulSoup

# 📡 Популярные СНГ-платформы
SITES = {
    "VK": "https://vk.com/{}",
    "Telegram": "https://t.me/{}",
    "YouTube": "https://www.youtube.com/@{}",
    "GitHub": "https://github.com/{}"
}

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}

def fetch_profile_info(site, url, username):
    try:
        r = requests.get(url, headers=HEADERS, timeout=5)
        if r.status_code != 200:
            return None

        soup = BeautifulSoup(r.text, 'html.parser')
        if site == "VK":
            title = soup.title.string if soup.title else ""
            match = re.search(r'(.+)\| ВКонтакте', title)
            if match:
                return match.group(1).strip()
        elif site == "Telegram":
            desc = soup.find("meta", {"property": "og:description"})
            if desc:
                return desc.get("content", "").strip()
        elif site == "YouTube":
            meta = soup.find("meta", {"name": "title"})
            if meta:
                return meta.get("content", "").strip()
        elif site == "GitHub":
            name = soup.find("span", class_="p-name")
            if name:
                return name.get_text(strip=True)
        return None
    except Exception:
        return None

def check_username(site_name, url_template, username):
    url = url_template.format(username)
    try:
        response = requests.get(url, headers=HEADERS, timeout=5)
        if response.status_code == 200:
            info = fetch_profile_info(site_name, url, username)
            return (site_name, url, "✅ Найден", info)
        elif response.status_code in [301, 302, 403]:
            return (site_name, url, "⚠️ Возможен, но закрыт", None)
        else:
            return (site_name, url, "❌ Нет", None)
    except requests.RequestException:
        return (site_name, url, "❌ Ошибка подключения", None)

def main():
    parser = argparse.ArgumentParser(description="Поиск ника по СНГ-сайтам с краткой инфой.")
    parser.add_argument("username", help="Никнейм пользователя")
    args = parser.parse_args()

    print("=" * 60)
    print(f"🔍 Поиск ника: {args.username}")
    print("=" * 60)

    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        futures = []
        for site, template in SITES.items():
            futures.append(executor.submit(check_username, site, template, args.username))
        for future in concurrent.futures.as_completed(futures):
            site, url, status, info = future.result()
            print(f"[{site:<10}] {status} — {url}")
            if info:
                print(f"              ↪ {info}")

if __name__ == "__main__":
    main()

Тест Perplexity

Создание сетевого сканера

Сканирование сети

Скрипт справился со своей задачей и дополнительно отобразил MAC-адреса.

Сканирование устройств на открытые порты и версии доступных сервисов

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

Поиск CVE по сервисам и их версиям

Заметно, что результатов в выдаче стало сильно меньше и скрипт даже не перешёл к проверке следующего адреса. Функцию поиска CVE нейросеть реализовала средствами API сайта. Использовав API сайта, скрипт не вывел уязвимостей, не проверил следующие адреса и забыл про выдачу MAC-адресов.

import argparse
import requests
import subprocess
from scapy.all import ARP, Ether, srp
import xml.etree.ElementTree as ET

VULNERS_API_KEY = "YOUR_API_KEY"
VULNERS_URL = "https://vulners.com/api/v3/search/lucene/"

def get_vulnerabilities(service, version):
    """Получение уязвимостей через Vulners API"""
    headers = {'Content-Type': 'application/json'}
    query = f'type:cve AND affectedSoftware.name:"{service}" AND affectedSoftware.version:"{version}"'
    
    try:
        response = requests.get(
            VULNERS_URL,
            headers=headers,
            params={
                'query': query,
                'apiKey': VULNERS_API_KEY
            }
        )
        return response.json().get('data', {}).get('search', [])
    except Exception as e:
        return [f"Ошибка запроса: {str(e)}"]

def parse_nmap_xml(xml_output):
    """Парсинг вывода Nmap XML"""
    root = ET.fromstring(xml_output)
    results = []
    
    for host in root.findall('host'):
        ip = host.find('address').get('addr')
        for port in host.findall('ports/port'):
            if port.find('state').get('state') == 'open':
                service = port.find('service')
                service_name = service.get('name', 'unknown')
                product = service.get('product', '')
                version = service.get('version', '')
                
                results.append({
                    'ip': ip,
                    'port': port.get('portid'),
                    'service': f"{product} {version}".strip(),
                    'name': service_name
                })
    return results

def enhanced_service_scan(target, ports):
    """Улучшенное сканирование с XML-выводом"""
    try:
        ports_str = ','.join(map(str, ports))
        result = subprocess.run(
            ['nmap', '-sV', '-oX', '-', '-p', ports_str, target],
            capture_output=True,
            text=True,
            check=True
        )
        return parse_nmap_xml(result.stdout)
    except subprocess.CalledProcessError as e:
        return [f"Ошибка Nmap: {e.stderr}"]
    except FileNotFoundError:
        return ["Nmap не установлен"]

def main():
    parser = argparse.ArgumentParser(description='Сканер уязвимостей сетевых сервисов')
    parser.add_argument('-t', '--target', required=True, help='Целевой IP или подсеть')
    parser.add_argument('-p', '--ports', default='1-1024', 
                      help='Диапазон портов (по умолчанию: 1-1024)')
    args = parser.parse_args()

    ports = range(*map(int, args.ports.split('-')))
    services = enhanced_service_scan(args.target, ports)
    
    print(f"\nРезультаты сканирования {args.target}:")
    for service in services:
        print(f"\n{service['ip']}:{service['port']} - {service['service']}")
        
        if service['service'] != '':
            vulns = get_vulnerabilities(service['name'], service['service'])
            if vulns:
                print("Найденные уязвимости:")
                for vuln in vulns[:3]:  # Показываем топ-3 уязвимости
                    print(f"  - {vuln.get('_source', {}).get('title', 'Unknown')}")
                    print(f"    CVE: {vuln.get('_source', {}).get('cvelist', ['N/A'])[0]}")
                    print(f"    Ссылка: {vuln.get('_source', {}).get('href', 'N/A')}")
            else:
                print("Уязвимостей не обнаружено")

if __name__ == "__main__":
    main()

Создание скрипта для поиска никнеймов

Проверка наличия на популярных соц.сетях и интернет-ресурсах в странах СНГ

Реализация скрипта получилась настолько медленной, что в течение 10 минут так и не было найдено ни одного совпадения и пришлось завершить его работу.

Выдача краткой информации по каждой найденной учётной записи

В этот раз получилось реализовать поиск. Набор соц.сетей и ресурсов подходит под СНГ. Результатом работы скрипта является информация, полученная путем парсинга HTML-страниц. К сожалению, добиться таких же результатов, как у GPT, не удалось. ChatGPT нашёл ссылку на ВК и предоставил краткую информацию, скрипт от Perplexity совсем не увидел наличие никнейма на этой платформе.

import requests
from bs4 import BeautifulSoup

def get_account_info(url, platform):
    """Получение краткой информации о профиле"""
    try:
        response = requests.get(url, timeout=10)
        soup = BeautifulSoup(response.text, 'html.parser')
        
        info = {
            'url': url,
            'platform': platform.capitalize(),
            'name': 'Не удалось получить',
            'bio': 'Нет информации',
            'posts': 'Нет данных',
            'followers': 'Нет данных'
        }
        
        if platform == 'vk':
            name_tag = soup.find('h1', class_='page_name')
            if name_tag: info['name'] = name_tag.text.strip()
            
            bio_tag = soup.find('div', class_='page_current_info')
            if bio_tag: info['bio'] = bio_tag.text.strip()
            
            counters = soup.find_all('div', class_='counts_module_info')
            if counters:
                if len(counters) > 0: info['posts'] = counters[0].text.strip()
                if len(counters) > 1: info['followers'] = counters[1].text.strip()
        
        elif platform == 'instagram':
            meta = soup.find('meta', property='og:description')
            if meta:
                content = meta['content']
                parts = content.split(' - ')
                if len(parts) > 0:
                    followers = parts[0].split(' ')[0]
                    posts = parts[1].split(' ')[0]
                    info['followers'] = followers
                    info['posts'] = posts
            name_tag = soup.find('title')
            if name_tag: info['name'] = name_tag.text.split('•')[0].strip()
        
        elif platform == 'twitter':
            name_tag = soup.find('div', {'data-testid': 'UserName'})
            if name_tag: info['name'] = name_tag.text.strip()
            
            bio_tag = soup.find('div', {'data-testid': 'UserDescription'})
            if bio_tag: info['bio'] = bio_tag.text.strip()
            
            stats = soup.find_all('span', {'data-testid': 'app-text-transition-container'})
            if stats:
                if len(stats) > 0: info['posts'] = stats[0].text.strip()
                if len(stats) > 1: info['followers'] = stats[1].text.strip()
        
        elif platform == 'youtube':
            name_tag = soup.find('meta', property='og:title')
            if name_tag: info['name'] = name_tag['content']
            
            subs_tag = soup.find('meta', itemprop='subscriberCount')
            if subs_tag: info['followers'] = f"{subs_tag['content']} подписчиков"
        
        return info
    
    except Exception as e:
        return {'error': str(e), 'platform': platform, 'url': url}

def check_username(username):
    """Проверка и сбор информации о профилях"""
    platforms = {
        'vk': f'https://vk.com/{username}',
        'instagram': f'https://www.instagram.com/{username}/',
        'twitter': f'https://twitter.com/{username}',
        'youtube': f'https://www.youtube.com/{username}',
        'tiktok': f'https://www.tiktok.com/@{username}',
        'github': f'https://github.com/{username}',
        'habr': f'https://habr.com/ru/users/{username}/',
        'pikabu': f'https://pikabu.ru/@{username}',
        'telegram': f'https://t.me/{username}',
        'ok': f'https://ok.ru/{username}'
    }
    
    results = {}
    
    for platform, url in platforms.items():
        try:
            response = requests.head(url, timeout=5)
            if response.status_code == 200:
                print(f"Анализируем {platform}...")
                info = get_account_info(url, platform)
                results[platform] = info
            else:
                results[platform] = {'status': 'Не найден'}
        except Exception as e:
            results[platform] = {'error': str(e)}
    
    return results

def display_results(results):
    """Вывод результатов с форматированием"""
    print("\nРезультаты поиска:")
    for platform, data in results.items():
        print(f"\n▬▬▬ {platform.upper()} ▬▬▬")
        
        if 'status' in data:
            print("Профиль не найден")
            continue
            
        if 'error' in data:
            print(f"Ошибка: {data['error']}")
            continue
            
        print(f"Ссылка: {data['url']}")
        print(f"Имя: {data.get('name', 'Нет данных')}")
        print(f"Описание: {data.get('bio', 'Нет данных')}")
        print(f"Публикации: {data.get('posts', 'Нет данных')}")
        print(f"Подписчики: {data.get('followers', 'Нет данных')}")

def main():
    username = input("Введите никнейм для поиска: ")
    results = check_username(username)
    display_results(results)

if __name__ == "__main__":
    main()

Тест DeepSeek

Создание сетевого сканера

Сканирование сети

Результат идентичен Perplexity, но добавился ненужный параметр ввода маски, когда её можно просто прописать через /.

Сканирование устройств на открытые порты и версии доступных сервисов

Порты, сервисы и их версии отображаются правильно. В положительную сторону можно отметить наличие параметра для выбора диапазона портов. Сканирование выполнено быстро.

Поиск CVE по сервисам и их версиям

Нейросеть попыталась реализовать поиск средствами API сайтов: cve.circl.lu и www.exploit-db.com, но данная функция не была реализована до конца.

import argparse
from scapy.all import ARP, Ether, srp
import ipaddress
import nmap
import requests
import json
from datetime import datetime

# Конфигурация API для проверки уязвимостей
CVE_API_URL = "https://cve.circl.lu/api/search"
EXPLOIT_DB_API = "https://www.exploit-db.com/search"

def scan_network(subnet, mask):
    """Сканирует подсеть и возвращает активные хосты."""
    network = f"{subnet}/{mask}"
    try:
        ip_network = ipaddress.ip_network(network, strict=False)
    except ValueError as e:
        print(f"Ошибка в подсети или маске: {e}")
        return []
    
    arp_request = ARP(pdst=str(ip_network))
    ether_frame = Ether(dst="ff:ff:ff:ff:ff:ff")
    packet = ether_frame / arp_request
    result = srp(packet, timeout=3, verbose=0)[0]
    
    return [{'ip': received.psrc, 'mac': received.hwsrc} for sent, received in result]

def scan_ports(host, ports="1-1000"):
    """Сканирует порты и возвращает информацию о сервисах."""
    nm = nmap.PortScanner()
    nm.scan(hosts=host, ports=ports, arguments='-sV --version-intensity 3')
    
    open_ports = []
    for proto in nm[host].all_protocols():
        for port, info in nm[host][proto].items():
            if info['state'] == 'open':
                open_ports.append({
                    'port': port,
                    'service': info['name'],
                    'version': info.get('version', 'не определена'),
                    'product': info.get('product', 'не определен')
                })
    return open_ports

def check_cve(service, version):
    """Проверяет уязвимости через CVE API."""
    try:
        params = {'product': service, 'version': version}
        response = requests.get(CVE_API_URL, params=params)
        if response.status_code == 200:
            return response.json().get('results', [])
    except Exception as e:
        print(f"Ошибка при запросе CVE: {e}")
    return []

def check_exploits(service, version):
    """Проверяет эксплойты для сервиса (заглушка, нужен реальный API Exploit-DB)."""
    # В реальном коде здесь должен быть запрос к Exploit-DB или Vulners
    return []

def check_common_vulns(service, version, port):
    """Проверяет известные уязвимости для популярных сервисов."""
    vulns = []
    if service == 'http':
        if 'Apache' in version and '2.4.49' in version:
            vulns.append('CVE-2021-41773 (Path Traversal in Apache 2.4.49)')
    elif service == 'smb' and 'Samba' in version:
        vulns.append('CVE-2017-7494 (Samba RCE)')
    elif service == 'ssh' and 'OpenSSH' in version and '7.9' in version:
        vulns.append('CVE-2021-41617 (OpenSSH 7.9 уязвимость)')
    return vulns

def get_vulnerabilities(host_info):
    """Анализирует сервис на уязвимости."""
    service = host_info['service']
    version = host_info['version']
    port = host_info['port']
    
    vulns = []
    
    # Проверка CVE
    cve_list = check_cve(service, version)
    for cve in cve_list:
        vulns.append(f"{cve.get('id', 'CVE-XXXX')}: {cve.get('summary', 'Уязвимость обнаружена')}")
    
    # Проверка общих уязвимостей
    vulns.extend(check_common_vulns(service, version, port))
    
    return vulns if vulns else ["Уязвимости не найдены"]

def main():
    parser = argparse.ArgumentParser(description="Сетевой сканер с поиском уязвимостей")
    parser.add_argument("--subnet", required=True, help="Подсеть (например, 192.168.1.0)")
    parser.add_argument("--mask", required=True, help="Маска (например, 24)")
    parser.add_argument("--ports", default="1-1000", help="Порты (например, 80,443)")
    args = parser.parse_args()

    print(f"[*] Сканирование {args.subnet}/{args.mask}...")
    hosts = scan_network(args.subnet, args.mask)
    
    if not hosts:
        print("[!] Активные хосты не найдены.")
        return
    
    print("\n[+] Активные хосты:")
    for host in hosts:
        print(f"IP: {host['ip']}\tMAC: {host['mac']}")
        
        open_ports = scan_ports(host['ip'], args.ports)
        if not open_ports:
            print(f"  [!] Нет открытых портов.")
            continue
            
        for port_info in open_ports:
            print(f"\n  [Порт {port_info['port']}] {port_info['service']} ({port_info['product']} {port_info['version']})")
            
            # Поиск уязвимостей
            vulns = get_vulnerabilities({
                'service': port_info['service'],
                'version': port_info['version'],
                'port': port_info['port']
            })
            
            print("  [Уязвимости]:")
            for vuln in vulns:
                print(f"    - {vuln}")

if __name__ == "__main__":
    main()

Создание скрипта для поиска никнеймов

Проверка наличия на популярных соц.сетях и интернет-ресурсах в странах СНГ

Результат практически совпадает с ответом ChatGPT. К количеству ресурсов претензий нет. Появился статус "Ручная проверка", но отсутствуют ссылки на профили.

Выдача краткой информации по каждой найденной учётной записи

Как и в случае с ChatGPT, нейросеть заметно сократила список ресурсов. Но с поставленной задачей справилась, при помощи проверки конкретных элементов на страницах.

import requests
from bs4 import BeautifulSoup
import time
import json

# Обновленный словарь с корректными проверками
SITES = {
    "VK": {
        "url": "https://vk.com/{}",
        "check": lambda response, soup: response.status_code == 200 and not soup.find("div", class_="profile_deleted"),
        "info": lambda soup: {
            "Имя": soup.find("h1", class_="page_name").get_text(strip=True) if soup.find("h1", class_="page_name") else "Не указано",
            "Статус": soup.find("div", class_="page_current_info").get_text(strip=True) if soup.find("div", class_="page_current_info") else "Нет статуса",
        }
    },
    "Telegram": {
        "url": "https://t.me/{}",
        "check": lambda response, _: response.status_code == 200 and response.url == response.request.url,
        "info": lambda soup: {
            "Имя": soup.find("div", class_="tgme_page_title").get_text(strip=True) if soup.find("div", class_="tgme_page_title") else "Не указано",
            "Описание": soup.find("div", class_="tgme_page_description").get_text(strip=True) if soup.find("div", class_="tgme_page_description") else "Нет описания",
        }
    },
    "Odnoklassniki": {
        "url": "https://ok.ru/{}",
        "check": lambda response, _: response.status_code == 200,
        "info": lambda soup: {
            "Имя": soup.find("h1", class_="profile-user-name").get_text(strip=True) if soup.find("h1", class_="profile-user-name") else "Не указано",
        }
    },
    "GitHub": {
        "url": "https://api.github.com/users/{}",
        "check": lambda response, _: response.status_code == 200,
        "info": lambda data: {
            "Имя": data.get("name", "Не указано"),
            "Репозитории": data.get("public_repos", 0),
            "Подписчики": data.get("followers", 0),
        }
    },
}

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}

def get_account_info(nickname, site_name, site_data):
    """Получает информацию об аккаунте на конкретной платформе."""
    url = site_data["url"].format(nickname)
    try:
        response = requests.get(url, headers=HEADERS, timeout=10)
        
        if "api.github.com" in url:
            if site_data["check"](response, None):
                return site_data["info"](response.json())
        else:
            soup = BeautifulSoup(response.text, 'html.parser')
            if site_data["check"](response, soup):
                return site_data["info"](soup)
                
    except Exception as e:
        return {"Ошибка": f"{type(e).__name__}: {str(e)}"}
    return None

def check_nickname(nickname):
    """Проверяет никнейм на всех платформах и возвращает результаты."""
    results = {}
    for site_name, site_data in SITES.items():
        time.sleep(1)
        info = get_account_info(nickname, site_name, site_data)
        if info:
            results[site_name] = {"status": "✅ Занят", "info": info}
        else:
            results[site_name] = {"status": "❌ Свободен или ошибка"}
    return results

def print_results(nickname, results):
    """Выводит результаты в читаемом формате."""
    print(f"\n🔍 Результаты поиска для '{nickname}':")
    for site, data in results.items():
        print(f"\n{site}: {data['status']}")
        if "info" in data:
            for key, value in data["info"].items():
                print(f"  {key}: {value}")

def main():
    nickname = input("Введите никнейм для поиска: ").strip()
    results = check_nickname(nickname)
    print_results(nickname, results)

if __name__ == "__main__":
    main()

Тест Together.ai

Создание сетевого сканера

Результат идентичен Perplexity и DeepSeek.

Сканирование устройств на открытые порты и версии доступных сервисов

Также совпадает с Perplexity и DeepSeek.

Поиск CVE по сервисам и их версиям

Наконец появилась первая нейросеть, которая действительно впечатлила нас отображением CVE для сервисов! Для этого используется API vulners.com. Чтобы запустить код, нужно прописать свой API-ключ в соответствующую переменную.

import argparse
import requests
import subprocess
from scapy.all import ARP, Ether, srp
import xml.etree.ElementTree as ET

VULNERS_API_KEY = "YOUR_API_KEY"
VULNERS_URL = "https://vulners.com/api/v3/search/lucene/"

def get_vulnerabilities(service, version):
    """Получение уязвимостей через Vulners API"""
    headers = {'Content-Type': 'application/json'}
    query = f'type:cve AND affectedSoftware.name:"{service}" AND affectedSoftware.version:"{version}"'
    
    try:
        response = requests.get(
            VULNERS_URL,
            headers=headers,
            params={
                'query': query,
                'apiKey': VULNERS_API_KEY
            }
        )
        return response.json().get('data', {}).get('search', [])
    except Exception as e:
        return [f"Ошибка запроса: {str(import ipaddress
from scapy.all import ARP, Ether, srp
import nmap
import requests

def network_scanner(ip_range):
    """
    Сканирует сеть и возвращает список активных хостов.

    :param ip_range: Диапазон IP-адресов в формате "192.168.1.0/24"
    :return: Список активных хостов
    """
    # Создаем объект ipaddress.ip_network для работы с диапазоном IP-адресов
    network = ipaddress.ip_network(ip_range, strict=False)

    # Создаем пакет ARP-запроса
    arp = ARP(pdst=str(network))
    ether = Ether(dst="ff:ff:ff:ff:ff:ff")
    packet = ether/arp

    # Отправляем пакет и получаем ответ
    result = srp(packet, timeout=3, verbose=0)[0]

    # Анализируем ответ и формируем список активных хостов
    active_hosts = []
    for sent, received in result:
        active_hosts.append({'ip': received.psrc, 'mac': received.hwsrc})

    return active_hosts

def port_scanner(host):
    """
    Сканирует порты хоста и возвращает информацию о сервисах.

    :param host: IP-адрес хоста
    :return: Информация о сервисах
    """
    # Создаем объект nmap.PortScanner для сканирования портов
    nm = nmap.PortScanner()

    # Сканируем порты
    nm.scan(host, arguments='-sV')

    # Анализируем результаты сканирования
    services = []
    for proto in nm[host].all_protocols():
        lport = sorted(nm[host][proto].keys())
        for port in lport:
            service = nm[host][proto][port]
            services.append({
                'port': port,
                'protocol': proto,
                'service': service['name'],
                'version': service['product'] + ' ' + service['version']
            })

    return services

def vulnerability_scanner(service):
    """
    Ищет уязвимости для сервиса.

    :param service: Информация о сервисе
    :return: Список уязвимостей
    """
    api_key = ""  # замените на свой API-ключ
    url = f"https://vulners.com/api/v3/search/lucene/?query={service['service']}%20{service['version']}&size=10"
    headers = {"Authorization": f"Bearer {api_key}"}

    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        data = response.json()
        vulnerabilities = []
        for result in data['data']['search']:
            vulnerability = {
                'id': result.get('_id', 'N/A'),
                'title': result.get('title', 'N/A'),
                'cvss': result.get('cvss', {}).get('score', 'N/A')
            }
            vulnerabilities.append(vulnerability)
        return vulnerabilities
    else:
        return []

def main():
    # Запрашиваем у пользователя маску подсети
    ip_range = input("Введите диапазон IP-адресов (например, 192.168.1.0/24): ")

    # Сканируем сеть
    active_hosts = network_scanner(ip_range)

    # Выводим результаты
    for host in active_hosts:
        print(f"Хост: {host['ip']} ({host['mac']})")
        services = port_scanner(host['ip'])
        if services:
            print("Сервисы:")
            for service in services:
                print(f"  {service['port']}/{service['protocol']}: {service['service']} ({service['version']})")
                vulnerabilities = vulnerability_scanner(service)
                if vulnerabilities:
                    print("    Уязвимости:")
                    for vulnerability in vulnerabilities:
                        print(f"      ID: {vulnerability['id']}, Заголовок: {vulnerability['title']}, CVSS: {vulnerability['cvss']}")
                else:
                    print("    Уязвимости не обнаружены.")
        else:
            print("Сервисы не обнаружены.")
        print()

if __name__ == "__main__":
    main()
e)}"]

def parse_nmap_xml(xml_output):
    """Парсинг вывода Nmap XML"""
    root = ET.fromstring(xml_output)
    results = []
    
    for host in root.findall('host'):
        ip = host.find('address').get('addr')
        for port in host.findall('ports/port'):
            if port.find('state').get('state') == 'open':
                service = port.find('service')
                service_name = service.get('name', 'unknown')
                product = service.get('product', '')
                version = service.get('version', '')
                
                results.append({
                    'ip': ip,
                    'port': port.get('portid'),
                    'service': f"{product} {version}".strip(),
                    'name': service_name
                })
    return results

def enhanced_service_scan(target, ports):
    """Улучшенное сканирование с XML-выводом"""
    try:
        ports_str = ','.join(map(str, ports))
        result = subprocess.run(
            ['nmap', '-sV', '-oX', '-', '-p', ports_str, target],
            capture_output=True,
            text=True,
            check=True
        )
        return parse_nmap_xml(result.stdout)
    except subprocess.CalledProcessError as e:
        return [f"Ошибка Nmap: {e.stderr}"]
    except FileNotFoundError:
        return ["Nmap не установлен"]

def main():
    parser = argparse.ArgumentParser(description='Сканер уязвимостей сетевых сервисов')
    parser.add_argument('-t', '--target', required=True, help='Целевой IP или подсеть')
    parser.add_argument('-p', '--ports', default='1-1024', 
                      help='Диапазон портов (по умолчанию: 1-1024)')
    args = parser.parse_args()

    ports = range(*map(int, args.ports.split('-')))
    services = enhanced_service_scan(args.target, ports)
    
    print(f"\nРезультаты сканирования {args.target}:")
    for service in services:
        print(f"\n{service['ip']}:{service['port']} - {service['service']}")
        
        if service['service'] != '':
            vulns = get_vulnerabilities(service['name'], service['service'])
            if vulns:
                print("Найденные уязвимости:")
                for vuln in vulns[:3]:  # Показываем топ-3 уязвимости
                    print(f"  - {vuln.get('_source', {}).get('title', 'Unknown')}")
                    print(f"    CVE: {vuln.get('_source', {}).get('cvelist', ['N/A'])[0]}")
                    print(f"    Ссылка: {vuln.get('_source', {}).get('href', 'N/A')}")
            else:
                print("Уязвимостей не обнаружено")

if __name__ == "__main__":
    main()

Создание скрипта для поиска никнеймов

Проверка наличия на популярных соц.сетях и интернет-ресурсах в странах СНГ

Список ресурсов значительно меньше, чем в скриптах других ИИ, зато есть ссылки и статусы.

Выдача краткой информации по каждой найденной учётной записи

К сожалению, скрипт не смог вывести никакой информации, несмотря на попытку реализовать отдельные функции для каждого ресурса и собрать данные по аналогии с методом DeepSeek, но в более упрощённом виде.

import requests
from bs4 import BeautifulSoup

def search_nickname(nickname):
    # Список ресурсов для поиска
    resources = [
        {"name": "ВКонтакте", "url": f"https://vk.com/{nickname}"},
        {"name": "Instagram", "url": f"https://www.instagram.com/{nickname}/"},
        {"name": "Telegram", "url": f"https://t.me/{nickname}"},
        {"name": "Twitter", "url": f"https://twitter.com/{nickname}"},
        {"name": "TikTok", "url": f"https://www.tiktok.com/@{nickname}"},
        {"name": "Reddit", "url": f"https://www.reddit.com/user/{nickname}"},
        {"name": "GitHub", "url": f"https://github.com/{nickname}"},
    ]

    # Поиск никнейма на ресурсах
    results = []
    for resource in resources:
        url = resource["url"].format(nickname=nickname)
        try:
            response = requests.get(url, timeout=5)
            if response.status_code == 200:
                soup = BeautifulSoup(response.text, 'html.parser')
                info = ''
                if resource['name'] == 'ВКонтакте':
                    info = get_vk_info(soup)
                elif resource['name'] == 'Instagram':
                    info = get_instagram_info(soup)
                elif resource['name'] == 'Twitter':
                    info = get_twitter_info(soup)
                results.append({"name": resource["name"], "url": url, "status": "Найден", "info": info})
            else:
                results.append({"name": resource["name"], "url": url, "status": "Не найден", "info": ''})
        except requests.exceptions.RequestException as e:
            results.append({"name": resource["name"], "url": url, "status": f"Ошибка: {e}", "info": ''})

    return results

def get_vk_info(soup):
    try:
        name = soup.find('h1', class_='page_name').text.strip()
        return f'Имя: {name}'
    except AttributeError:
        return ''

def get_instagram_info(soup):
    try:
        name = soup.find('meta', property='og:title')['content']
        return f'Имя: {name}'
    except (AttributeError, TypeError):
        return ''

def get_twitter_info(soup):
    try:
        name = soup.find('span', class_='ProfileHeaderCard-name').text.strip()
        return f'Имя: {name}'
    except AttributeError:
        return ''

def main():
    # Запрашиваем у пользователя никнейм
    nickname = input("Введите никнейм: ")

    # Ищем никнейм на ресурсах
    results = search_nickname(nickname)

    # Выводим результаты
    print("Результаты поиска:")
    for result in results:
        print(f"{result['name']}: {result['url']} ({result['status']})")
        if result['info']:
            print(f"  {result['info']}")

if __name__ == "__main__":
    main()

Анализ кода скриптов

Анализ скриптов для сканирования сети

Ошибки обработки сетевых запросов:

  • В скрипте от Together.ai нет обработки requests.exceptions.RequestException для API Vulners.

  • В скрипте от ChatGPT отсутствует проверка доступности хоста перед сканированием портов.

Проблемы производительности:

  • В скрипте от ChatGPT используется ThreadPoolExecutor(max_workers=100), это может привести к ненамеренной DoS сети или блокировке IP.

  • В скрипте от Perplexity сканирование портов синхронное и это может значительно замедлить работу.

Ненадежное определение сервисов:

  • В скрипте от ChatGPT функция identify_service использует простые строковые проверки (if "ftp" in banner) и данный метод проверки можно легко обмануть.

Анализ OSINT-скриптов

  • Устаревшие методы парсинга:

    • В скрипте от ChatGPT и от Perplexity используется BeautifulSoup для парсинга соцсетей, но структура HTML часто меняется.

  • Неполный охват ресурсов:

    • В скрипте от DeepSeek проверяются только VK, Telegram, OK и GitHub, а в Together.ai добавлен TikTok, но нет Одноклассников.

Заключение

Исходя из проведённых тестов, мы можем представить общий результат в виде таблицы:

Ещё больше познавательного контента в Telegram-канале — AI-шная

Полезные OSINT инструменты в телеграме (всегда рабочие ссылки) и отличный контент.

Теги:
Хабы:
+3
Комментарии4

Публикации