What's new
Runion

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Разработка парсера SEED-фраз в Telegram на Python

AGN

Light Weight
Депозит
$0
В данной статье мы рассмотрим код, который реализует функциональность для поиска SEED-фраз в текстовых сообщениях и изображениях в Telegram-чатах. Напоминаю, что это моя первая статья на этом форуме и направлена она для изучения материала новичками. Приму адекватную критику от коллег, а так же готов выслушать ваше мнение. Спасибо.

Введение:

1. Необходимые библиотеки и программы:

Мы будем использовать следующие Python-библиотеки:
  • Telethon — для взаимодействия с Telegram API.
  • Pytesseract — интерфейс для Tesseract OCR.
  • Pillow — для работы с изображениями (понадобится для обработки данных перед отправкой в OCR).
Установка необходимых библиотек:
Код: Скопировать в буфер обмена
pip install telethon pytesseract pillow

2. Установка Tesseract OCR
Для распознавания текста на изображениях необходимо установить Tesseract OCR:

1. Скачайте установщик с официальной страницы.
2. Установите программу и добавьте путь к tesseract.exe в переменную окружения PATH.

3. Настройка Telegram API
Для работы с Telegram API вам нужно зарегистрировать приложение на my.telegram.org. После регистрации вы получите:

• API ID
• API Hash

Эти значения понадобятся для авторизации через Telethon.

Начало:

1.
Для самого начала написания скрипта нам необходимо импортировать все необходимые нам библиотеки:
Python: Скопировать в буфер обмена
Code:
import os
import re
from telethon import TelegramClient, events
from telethon.tl.types import InputMessagesFilterPhotos, InputMessagesFilterDocument
from PIL import Image
import pytesseract
from io import BytesIO
  • os: Библиотека для работы с операционной системой.
  • re: Модуль для работы с регулярными выражениями, который позволяет искать шаблоны в строках.
  • telethon: Библиотека для работы с Telegram API, позволяющая взаимодействовать с Telegram через Python.
  • PIL (Pillow): Библиотека для работы с изображениями, позволяющая открывать, изменять и сохранять изображения.
  • pytesseract: Python-обертка для Tesseract OCR, которая позволяет распознавать текст на изображениях.
  • BytesIO: Класс для работы с байтовыми потоками, который позволяет работать с изображениями, загруженными в память
2. Настройки Telegram API
Далее, нам необходимо добавить функцию для аутентификации в Телеграмм:

Python: Скопировать в буфер обмена
Code:
API_ID = 'ВАШ_API_ID'
API_HASH = 'ВАШ_API_HASH'
SESSION_NAME = 'telegram_parser_session'
  • API_ID и API_HASH: Эти параметры необходимы для аутентификации в Telegram API.
  • SESSION_NAME: Имя сессии, которое используется для хранения данных аутентификации. Это позволяет избежать повторного ввода данных при последующих запусках скрипта.
3. Регулярное выражение для поиска SEED-фраз:
Python: Скопировать в буфер обмена
SEED_REGEX = r'\b(?:\w+\s){11,23}\w+\b'
  • SEED_REGEX: Регулярное выражение, которое ищет SEED-фразы, состоящие из 12 или 24 слов. Шаблон ищет последовательности слов, разделённых пробелами, что соответствует формату SEED-фраз, используемых в криптографии.
4. Инициализация клиента Telethon:
Python: Скопировать в буфер обмена
client = TelegramClient(SESSION_NAME, API_ID, API_HASH)
  • TelegramClient: Создание экземпляра клиента для работы с Telegram API. Он будет использовать указанные параметры для аутентификации и управления сессией.
5. Добавление функции для поиска SEED-фраз в тексте:
Python: Скопировать в буфер обмена
Code:
def find_seed_phrases(text):
 matches = re.findall(SEED_REGEX, text)
 return matches if matches else []
  • find_seed_phrases: Функция, которая принимает текст и ищет в нём SEED-фразы с использованием регулярного выражения. Если находки есть, они возвращаются в виде списка.
6. Добавление функции для поиска SEED-фраз на изображениях:
Python: Скопировать в буфер обмена
Code:
[CODE=python]def extract_text_from_image(image_bytes):
 image = Image.open(BytesIO(image_bytes))
 return pytesseract.image_to_string(image)
extract_text_from_image: Функция, которая принимает байты изображения, открывает его с помощью Pillow и использует pytesseract для извлечения текста. Это позволяет обрабатывать изображения, которые могут содержать SEED-фразы.

7. Добавление функции для поиска SEED-фраз в чатах:
Python: Скопировать в буфер обмена
Code:
async def process_chat(chat):
 async for message in client.iter_messages(chat):
  # Поиск SEED-фраз в тексте сообщения
  if message.text:
   seeds = find_seed_phrases(message.text)
   if seeds:
    print(f"[TEXT] Найдены SEED-фразы в чате {chat.title}: {seeds}")
  
  # Проверка на наличие фото и документов (картинок)
  if message.photo or message.document:
   media = message.photo or message.document
   if media:
    # Скачиваем изображение
    image_bytes = await client.download_media(media, bytes)
    if image_bytes:
     # Извлечение текста с помощью OCR
     extracted_text = extract_text_from_image(image_bytes)
     seeds = find_seed_phrases(extracted_text)
     if seeds:
      print(f"[IMAGE] Найдены SEED-фразы в чате {chat.title}: {seeds}")
[/CODE]
  • process_chat: Асинхронная функция для обработки сообщений в заданном чате. Она использует iter_messages для итерации по всем сообщениям в чате.
  • Внутри функции:
    • Сначала проверяется наличие текста в сообщении. Если текст найден, вызывается функция find_seed_phrases для поиска SEED-фраз.
    • Затем проверяется наличие фотографий или документов. Если таковые имеются, они загружаются с помощью download_media, и текст извлекается с помощью extract_text_from_image.
8. Реализация основной функции скрипта:
Python: Скопировать в буфер обмена
Code:
async def main():
 # Подключение к Telegram
 await client.start()


 # Получение всех чатов, включая Избранное (Saved Messages)
 dialogs = await client.get_dialogs()


 # Обход всех чатов
 for dialog in dialogs:
  print(f"Проверка чата: {dialog.title}")
  await process_chat(dialog)


 # Завершение работы клиента
 await client.disconnect()
  • main: Асинхронная функция, которая управляет основным потоком выполнения.
  • Внутри функции:
    • Сначала происходит подключение к Telegram с помощью client.start().
    • Затем с помощью get_dialogs() получаем все чаты, включая Избранное.
    • Для каждого чата вызывается функция process_chat, которая обрабатывает сообщения.
    • В конце работы клиента вызывается client.disconnect() для корректного завершения сессии.
9. Запуск скрипта:
Python: Скопировать в буфер обмена
Code:
with client:
 client.loop.run_until_complete(main())
  • Используется контекстный менеджер with, который гарантирует, что клиент будет корректно закрыт после завершения работы.
  • client.loop.run_until_complete(main()) запускает асинхронную функцию main, что инициирует весь процесс.
Заключение:

В данной статье мы подробно рассмотрели код, который позволяет автоматически искать SEED-фразы в текстовых сообщениях и изображениях Telegram-чатов. Используя библиотеки Telethon и pytesseract, мы создали эффективный инструмент для анализа сообщений, который может быть полезен в различных ситуациях, где в ручную заниматься поиском SEED-фраз совсем несуразно. Благодарю за прочтение моей первой статьи, если она понравилась вам - всегда можно поддержать автора лайком.

Автор: AGN
Специально для .is

Спойлер: Готовый код
Python: Скопировать в буфер обмена
Code:
import os
import re
from telethon import TelegramClient, events
from telethon.tl.types import InputMessagesFilterPhotos, InputMessagesFilterDocument
from PIL import Image
import pytesseract
from io import BytesIO


API_ID = 'ВАШ_API_ID'
API_HASH = 'ВАШ_API_HASH'
SESSION_NAME = 'telegram_parser_session'


SEED_REGEX = r'\b(?:\w+\s){11,23}\w+\b'


client = TelegramClient(SESSION_NAME, API_ID, API_HASH)


def find_seed_phrases(text):
 matches = re.findall(SEED_REGEX, text)
 return matches if matches else []


def extract_text_from_image(image_bytes):
 image = Image.open(BytesIO(image_bytes))
 return pytesseract.image_to_string(image)


async def process_chat(chat):
 async for message in client.iter_messages(chat):
  if message.text:
   seeds = find_seed_phrases(message.text)
   if seeds:
    print(f"[TEXT] Найдены SEED-фразы в чате {chat.title}: {seeds}")
  
  if message.photo or message.document:
   media = message.photo or message.document
   if media:
    image_bytes = await client.download_media(media, bytes)
    if image_bytes:
     extracted_text = extract_text_from_image(image_bytes)
     seeds = find_seed_phrases(extracted_text)
     if seeds:
      print(f"[IMAGE] Найдены SEED-фразы в чате {chat.title}: {seeds}")


async def main():
 await client.start()


 dialogs = await client.get_dialogs()

 for dialog in dialogs:
  print(f"Проверка чата: {dialog.title}")
  await process_chat(dialog)


 await client.disconnect()


with client:
 client.loop.run_until_complete(main())
 
Зачем столько сложностей?


AGN сказал(а):
r'\b(?:\w+\s){11,23}\w+\b'
Нажмите, чтобы раскрыть...
парсить оно будет все подряд идущие слова, а не только те из которых может состоять сидка


Вот мой код на си, сами разберетесь как использовать


C: Скопировать в буфер обмена
Code:
CVector* WordsContentToVector(char* words_content, DWORD content_length)
{
 CVector* cvector = CVectorInit(2048);
 if(!cvector) return 0;

 // cvector->reserved[0] = words_content;

 // CVectorPushElement(cvector, words_content);

 int idx = 0;
 // int

 for(int i = 0; i < content_length; i++)
 {
  if(!words_content[i]) break;

  if(words_content[i] == '\n')
  {
   words_content[i] = '\0';

   if(words_content[i + 1])
   {
    CVectorPushElement(cvector, &words_content[i + 1]);
   }
  }
 }


 // for(int i = 0; i < cvector->elem_count; i++)
 // {
 //  printf("%d, '%s'\n", i, CVectorGetElement(cvector, i));
 // }

 return cvector;
}


bool ischr(char c)
{
 return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) ? true : false;
}


bool IsValidWord(char* word, int word_length, CVector* words)
{
 if(!word || (word_length < 4) || (word_length > 9)) return false;

 for(int i = 0; i < words->elem_count; i++)
 {
  char* seed_word = CVectorGetElement(words, i);
  if(!memcmp(word, seed_word, word_length))
  {
   return true;
  }
 }

 return false;
}


char* _getseed(int word_count, int seed_length, char* text, int seed_start)
{
 if((word_count == 12) || (word_count == 18) || (word_count == 24))
 {
  //printf("found seed: '%.*s'\n", seed_length, text + seed_start);

  char* seed = malloc(seed_length + 1);
  if(seed)
  {
   memcpy(seed, text + seed_start, seed_length);

   seed[seed_length] = '\0';

   // printf("found seed: '%s'\n", seed);

   return seed;
  }
  else
  {
   printf("ERROR: malloc return 0 in _getseed\n");
  }

 }
 
 return 0;
}


CVector* GetSeedsFromText(char* text, int text_length, CVector* words)
{
 if(!text) return 0;

 int seed_start = -1;
 int seed_length = 0;
 int word_start = -1;
 int word_count = 0;
 char* seed = 0;
 char word[10];

 int ret = 0;

 CVector* found_seeds = CVectorInit(10);

 if(!found_seeds) return 0;

 for(int i = 0; i < text_length; i++)
 {
  // printf("%d|%c|, ", i, text[i]);

  if(ischr(text[i]))
  { 
   // printf("ischr!, ");
   if(i)
   {
    // printf("i != 0, ");

    if(!ischr(text[i - 1]))
    {
     // printf("text[i-1] = ' ', ");
     if(seed_start == -1)
     {
      // printf("seed_start = %d, ", i);
      seed_start = i;
     }

     if(word_start == -1)
     {
      // printf("word_start = %d, ", i);
      word_start = i;
     }
    }
    // else
    // {
    //  printf("skip");
    // }
   }
   else
   {
    // printf("i == 0, ");
    if(seed_start == -1)
    {
     // printf("seed_start = %d, ", i);
     seed_start = i;
    }

    if(word_start == -1)
    {
     // printf("word_start = %d, ", i);
     word_start = i;
    }
   }

   // printf("\n");
   

  }
  else
  {
   // printf("other symb!, ");

   if(seed_start == -1)
   {
    // printf("no seed start\n");
    continue;
   }
   
   if(word_start != -1)
   {
    int word_length = i - word_start;
    // printf("w_length = %d, ", word_length);

    if(word_length < 9)
    {
     memcpy(word, text + word_start, word_length);
     word[word_length] = '\0';
    }

    word_start = -1;
   

    if(IsValidWord(word, word_length + 1, words))
    {
     word_count++;

     // printf("word: '%s', word_c: %d\n", word, word_count);

    
     if(text[i] == ' ') continue;

     
     seed_length = i - seed_start;
    }
    else
    {
     // printf("noval word\n");
     seed_length = i - seed_start - word_length - 1;
    }

    seed = _getseed(word_count, seed_length, text, seed_start);
    if(seed)
    {
     ret = CVectorPushElement(found_seeds, seed);
     if(!ret)
     {
      free(seed);
     }
    }    
   }
   else
   {
    seed_length = i - seed_start;

    seed = _getseed(word_count, seed_length, text, seed_start);
    if(seed)
    {
     ret = CVectorPushElement(found_seeds, seed);
     if(!ret)
     {
      free(seed);
     }
    }
   }
   
   word_count = 0;
   seed_start = -1;
  }
 }

 if(!found_seeds->elem_count)
 {
  CVectorFree(found_seeds);
  return 0;
 }
 else
 {
  return found_seeds;
 }
}
 
malware_cryptor сказал(а):
Вот это интересная идея



У тебя воспринимает как сидку любые слова идующие подряд, а не только 2048 мнемонических

Вот мой код на си, сами разберетесь что там да и как

Код: Скопировать в буфер обмена
Code:
CVector* WordsContentToVector(char* words_content, DWORD content_length)
{
 CVector* cvector = CVectorInit(2048);
 if(!cvector) return 0;

 // cvector->reserved[0] = words_content;

 // CVectorPushElement(cvector, words_content);

 int idx = 0;
 // int

 for(int i = 0; i < content_length; i++)
 {
  if(!words_content[i]) break;

  if(words_content[i] == '\n')
  {
   words_content[i] = '\0';

   if(words_content[i + 1])
   {
    CVectorPushElement(cvector, &words_content[i + 1]);
   }
  }
 }


 // for(int i = 0; i < cvector->elem_count; i++)
 // {
 //  printf("%d, '%s'\n", i, CVectorGetElement(cvector, i));
 // }

 return cvector;
}


bool ischr(char c)
{
 return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) ? true : false;
}


bool IsValidWord(char* word, int word_length, CVector* words)
{
 if(!word || (word_length < 4) || (word_length > 9)) return false;

 for(int i = 0; i < words->elem_count; i++)
 {
  char* seed_word = CVectorGetElement(words, i);
  if(!memcmp(word, seed_word, word_length))
  {
   return true;
  }
 }

 return false;
}


char* _getseed(int word_count, int seed_length, char* text, int seed_start)
{
 if((word_count == 12) || (word_count == 18) || (word_count == 24))
 {
  //printf("found seed: '%.*s'\n", seed_length, text + seed_start);

  char* seed = malloc(seed_length + 1);
  if(seed)
  {
   memcpy(seed, text + seed_start, seed_length);

   seed[seed_length] = '\0';

   // printf("found seed: '%s'\n", seed);

   return seed;
  }
  else
  {
   printf("ERROR: malloc return 0 in _getseed\n");
  }

 }
 
 return 0;
}


CVector* GetSeedsFromText(char* text, int text_length, CVector* words)
{
 if(!text) return 0;

 int seed_start = -1;
 int seed_length = 0;
 int word_start = -1;
 int word_count = 0;
 char* seed = 0;
 char word[10];

 int ret = 0;

 CVector* found_seeds = CVectorInit(10);

 if(!found_seeds) return 0;

 for(int i = 0; i < text_length; i++)
 {
  // printf("%d|%c|, ", i, text[i]);

  if(ischr(text[i]))
  { 
   // printf("ischr!, ");
   if(i)
   {
    // printf("i != 0, ");

    if(!ischr(text[i - 1]))
    {
     // printf("text[i-1] = ' ', ");
     if(seed_start == -1)
     {
      // printf("seed_start = %d, ", i);
      seed_start = i;
     }

     if(word_start == -1)
     {
      // printf("word_start = %d, ", i);
      word_start = i;
     }
    }
    // else
    // {
    //  printf("skip");
    // }
   }
   else
   {
    // printf("i == 0, ");
    if(seed_start == -1)
    {
     // printf("seed_start = %d, ", i);
     seed_start = i;
    }

    if(word_start == -1)
    {
     // printf("word_start = %d, ", i);
     word_start = i;
    }
   }

   // printf("\n");
   

  }
  else
  {
   // printf("other symb!, ");

   if(seed_start == -1)
   {
    // printf("no seed start\n");
    continue;
   }
   
   if(word_start != -1)
   {
    int word_length = i - word_start;
    // printf("w_length = %d, ", word_length);

    if(word_length < 9)
    {
     memcpy(word, text + word_start, word_length);
     word[word_length] = '\0';
    }

    word_start = -1;
   

    if(IsValidWord(word, word_length + 1, words))
    {
     word_count++;

     // printf("word: '%s', word_c: %d\n", word, word_count);

    
     if(text[i] == ' ') continue;

     
     seed_length = i - seed_start;
    }
    else
    {
     // printf("noval word\n");
     seed_length = i - seed_start - word_length - 1;
    }

    seed = _getseed(word_count, seed_length, text, seed_start);
    if(seed)
    {
     ret = CVectorPushElement(found_seeds, seed);
     if(!ret)
     {
      free(seed);
     }
    }   
   }
   else
   {
    seed_length = i - seed_start;

    seed = _getseed(word_count, seed_length, text, seed_start);
    if(seed)
    {
     ret = CVectorPushElement(found_seeds, seed);
     if(!ret)
     {
      free(seed);
     }
    }
   }
   
   word_count = 0;
   seed_start = -1;
  }
 }

 if(!found_seeds->elem_count)
 {
  CVectorFree(found_seeds);
  return 0;
 }
 else
 {
  return found_seeds;
 }
}
Нажмите, чтобы раскрыть...
для пайтон тупо через mnemonic проверяешь соответствие фразе и при истине запись строки в лист, в котором нужно дубли отсеять, что в его коде не предусмотрено(чат GPT видимо рулит)
 
Top