Защищаем пароль в TeamViewer
TeamViewer, как и большинство программных продуктов, обладает опцией сохранения пароля от своего профиля (профиль используется для упорядоченного хранения перечня идентификаторов удаленных компьютеров с реквизитами доступа к ним). При включенной опции сохранения, пароль прозаично сохраняется в реестре по адресу HKCU\Software\TeamViewer\Version* в переменной BuddyLoginPWAES.
Как видно из названия переменной, да и непосредственно из реестра, перед сохранением пароль шифруется, однако это не является проблемой, т.к. ключи шифрования легко получить, а также никто не мешает просто скопировать содержимое переменной из реестра, перенести на другой компьютер и там успешно авторизоваться. Отсюда возникает некоторое опасение, так как всегда существует вероятность запустить очередной password stealer, который всё благополучно утащит.
Попробуем решить эту проблему костыльно-велосипедным способом. Для этого напишем небольшую библиотеку, которая будет перехватывать обращения к реестру и осуществлять дополнительное шифрование пароля, а также лаунчер для тимвьювера, который будет запускать его и заодно подгружать нашу библиотеку.
Библиотеку будем писать на MASM, ибо C и Detours быстро надоедают. Начнем как всегда сначала.
.486.model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\macros\macros.asm include \masm32\macros\windows.asm include \masm32\macros\inject.asm uselib kernel32, user32, masm32 validate proto value_name:DWORD, entry_type:DWORD, entry_buffer:DWORD JUMPNEAR STRUCT 1 opcd BYTE ? reladdr DWORD ? JUMPNEAR ENDS |
Стандартные неинтересные инклюды, за исключением inject.asm, старая структура, которая вместе с inject.asm была описана в этой статье, и прототип функции для проверки некоторых аргументов у перехватываемых в дальнейшем функций (RegSetValueExW, RegQueryValueExW).
Перейдем к секции данных
.data;Ключ шифрования ☺ enc_key db"I7JFTZgcZdk";Размер ключа enc_key_sz dd sizeof enc_key ;Имя ключа в реестре, который нас интересует (в Unicode) reg_key_name db'B',0,'u',0,'d',0,'d',0,'y',0,'L',0,'o',0,'g',0,'i',0,'n',0,'P',0,'W',0,'A',0,'E',0,'S',0,0,0;Переменная для хранения адреса RegSetValueExW reg_set_value dd0 |
Тут всё ещё более тривиально, поэтому перейдем к чуть менее тривиальному коду, который будет состоять из нескольких функций.
.code MyRegQueryValueExW:pushebpmovebp,esp;Вызовем оригинальную функцию HOOK_ORIGINAL_CALL RegQueryValueExW,6;Сохраним результат выполненияpusheax;Проверим параметры invoke validate,[ebp+4+4*2],[ebp+4+4*4],[ebp+4+4*5];Если меняется целевой параметр, то расшифруем его.if eax == 1moveax,[ebp+4+4*6]moveax,[eax] invoke XorData,[ebp+4+4*5],eax, offset enc_key, enc_key_sz .endif popeaxpopebp retn 4*6 MyRegSetValueExW:;Буфер для пролога оригинальной функции stolen_bytes db7 dup(90h) pushebpmovebp,esp;Компенсируем 2 x push из оригинального прологаaddebp,4*2 ;Получаем указатель на 4-й аргумент на стекеmoveax,ebpaddeax,4+4*4;Проверим параметры invoke validate,[ebp+4+4*2],eax,[ebp+4+4*5];Если меняется целевой параметр, то зашифруем его.if eax == 1moveax,[ebp+4+4*6] invoke XorData,[ebp+4+4*5],eax, offset enc_key, enc_key_sz .endif popebp;Вернемся в оригинальную функциюpush reg_set_value adddword ptr[esp],7 retn validate proc value_name:DWORD, entry_type:DWORD, entry_buffer:DWORD;Имя параметра, тип и буфер для результата не должны быть нулевыми.if value_name == NULL || entry_type == NULL || entry_buffer == NULL xoreax,eaxret.endif ;Тип параметра должен быть REG_BINARYmoveax, entry_type moveax,[eax].if eax != REG_BINARY xoreax,eaxret.endif ;Имя параметра должно соответствовать ожидаемому invoke lstrcmpW, value_name, offset reg_key_name .if eax != 0xoreax,eaxret.endif moveax,1ret validate endp |
Как видно из вышеописанного кода, мы используем тривиальный XOR для шифрования, его вполне достаточно для наших целей, вдобавок не меняется размер данных после шифрования-дешифрования. Также кому-то может быть не сразу понятно, что из себя представляют аргументы вида [ebp + 4 + 4 * x], тут всё просто - это обращение к N-ому аргументу stdcall функции (например, [ebp + 4 + 4 * 4] - это четвертый по счету аргумент функции RegQueryValueExW, то есть lpType), чуть подробнее всё это описывалось в вышеупомянутой статье про инжектор. Теперь рассмотрим LibMain:
LibMain proc instance:DWORD,reason:DWORD,reserved:DWORD local pr :dword local h :dword .if reason == DLL_PROCESS_ATTACH ;Ставим хук на RegQueryValueExW SET_HOOK advapi32.dll, RegQueryValueExW, MyRegQueryValueExW ;У RegSetValueExW нестандартный пролог (который не поддерживается макросами dx'а для инжекта), поэтому установим хук вручную;Получим адрес функцииmov h, FUNC(GetModuleHandle, chr$("Advapi32.dll"))mov reg_set_value, FUNC(GetProcAddress, h, chr$("RegSetValueExW")) ;Скопируем 7 байт нестандартного пролога и поместим их в нашу функцию invoke VirtualProtect, MyRegSetValueExW, sizeof stolen_bytes, PAGE_READWRITE, addr pr invoke MemCopy, reg_set_value, MyRegSetValueExW, sizeof stolen_bytes invoke VirtualProtect, MyRegSetValueExW, sizeof stolen_bytes, pr, addr pr invoke VirtualProtect, reg_set_value, sizeof JUMPNEAR, PAGE_READWRITE, addr pr ;Сформируем jmp на нашу функцию в начале RegSetValueExWmoveax, reg_set_value assume eax: ptr JUMPNEAR mov[eax].opcd,0E9hmovecx, offset MyRegSetValueExW subecx, reg_set_value subecx,5mov[eax].reladdr,ecx assume eax: nothing ;Занопим байты, оставшиеся от старых инструкцийaddeax, sizeof JUMPNEAR movbyte ptr[eax],90hmovbyte ptr[eax+1],90h invoke VirtualProtect, reg_set_value, sizeof JUMPNEAR, pr, addr pr moveax,1.elseif reason == DLL_PROCESS_DETACH REMOVE_HOOK RegQueryValueExW moveax,1.endif ret LibMain endp end LibMain |
В функции наблюдается смесь из макросов, которые можно использовать для Winapi-функций с обычным прологом и костыля для нестандартной RegSetValueExW. Подход не является хорошей практикой, т.к. корректнее было бы прикрутить дизассемблер длин и сделать всё как надо, но кому это нужно в данном контексте?
С библиотекой закончили, осталось её скомпилировать, для этого можно воспользоваться, например, этим набором, либо взять всё с "официального сайта.
Перейдем к элементарному лаунчеру. Тут я позволю себе воспользоваться ранее написанным классом. С его использованием код сокращается до пары десятков строк. Вот он:
#include <Windows.h>#include "injector.hpp" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ STARTUPINFO si ={0}; PROCESS_INFORMATION pi ={0};// Запустим процесс в приостановленном состоянииif(!CreateProcess(L"TeamViewer.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)){ MessageBox(HWND_DESKTOP, L"Failed to start TeamViewer", L"Error", MB_OK);return-1;}// Создадим инстанс класса-инжектора injector inj; inj.set_blocking(false);// Подгрузим библиотеку в процессtry{ inj.inject(pi.dwProcessId, L"lego.dll");}catch(const injector_exception &e){ MessageBox(HWND_DESKTOP, e.msg(), L"Error", MB_OK);}// Возобновим выполнение процесса и закроем ненужные хендлы ResumeThread(pi.hThread); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return0;} |
Остается только скопировать полученную библиотеку вместе с лаунчером в папку TeamViewer'a и наслаждаться результатом. Описанная методика применима для любой программы, которая хранит свои пароли в реестре.
Исходный код: скачать
Также рекомендую почитать
Обсудить на форуме
Источник: http://feedproxy.google.com/~r/kaimi/dev/~3/nJkOMxVpJAM/


Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2025-04-08 » Горшочек, рисуй: 10 бесплатных сервисов для генерации картинок
- 2025-04-08 » SEO-продвижение в 2025 году: 15 трендов, без которых ТОП не светит
- 2025-03-14 » SPF-запись
- 2025-03-07 » SEO на маркетплейсах: как оптимизировать карточку товара для поисковой выдачи
- 2025-02-18 » Топ-10 бесплатных нейросетей для генерации изображений: лучшие ии генераторы 2024 года
- 2025-02-11 » Критическая уязвимость в 1С-Битрикс
- 2025-02-11 » Google Search Console: руководство для начинающих вебмастеров
- 2025-02-11 » Методы измерения результативности рекламных кампаний: плюсы и минусы
- 2025-02-11 » Тренды SEO в 2025 году
- 2025-02-10 » Свой Google в локалке. Ищем иголку в стоге сена
- 2025-01-29 » SEO — это комплексная работа. Шесть главных факторов ранжирования сайтов
- 2025-01-29 » Гайд для главной страницы e-commerce сайта: как оформить, чтобы повысить конверсию
- 2025-01-20 » Krea AI выпустила бесплатную функцию преобразования изображений в 3D-объекты — их можно вращать и вписывать в фотографии
- 2025-01-19 » Отзывы на Яндекс Картах: как пройти модерацию
- 2025-01-15 » Топ-6 лучших российских нейросетей, в которых можно генерировать тексты и изображения бесплатно и без VPN
- 2025-01-14 » 15 бесплатных способов узнать, чем интересуется ваша аудитория
- 2025-01-11 » Бездепозитные бонусы в казино за регистрацию с выводом: особенности и возможности получения
- 2025-01-09 » Новая модель LAM способна выполнять задачи в Word
- 2024-12-26 » Универсальный промпт для нейросети: как выжать максимум из ChatGPT, YandexGPT, Gemini, Claude в 2025
- 2024-11-26 » Капитан грузового судна, или Как начать использовать Docker в своих проектах
- 2024-11-26 » Обеспечение безопасности ваших веб-приложений с помощью PHP OOP и PDO
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-15 » Перенос сайта на WordPress с одного домена на другой
- 2024-11-08 » OSPanel 6: быстрый старт
- 2024-11-08 » Как установить PhpMyAdmin в Open Server Panel
- 2024-09-30 » Как быстро запустить Laravel на Windows
- 2024-09-25 » Next.js
- 2024-09-05 » OpenAI рассказал, как запретить ChatGPT использовать содержимое сайта для обучения
- 2024-08-28 » Чек-лист: как увеличить конверсию интернет-магазина на примере спортпита
Человек - аристократ среди животных Гейне Генрих - (1797-1856) - немецкий поэт и публицист |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.
Или напишите нам в WhatsApp
Или напишите нам в WhatsApp