Теорія захисту програм від злому

Автор: gackt

На тему захисту Shareware-програм
написано вже чимало, і навряд чи ви знайдете що-небудь нове в цій статті.
Це лише нарис деяких методів, найбільш ефективних на мій погляд. Якщо
ви сподіваєтеся знайти тут конкретні приклади або исходники – я вас засмучу,
всі описи методів захисту зазначені в загальному вигляді, стаття містить лише
теорію.

Деякі способи захисту придумані
мною особисто (хоча напевно хтось вже додумався до них раніше мене).
Інші були взяті зі сторонніх джерел. Джерела я не вказую по
однієї простої причини – їх дуже багато, як вітчизняних, так і
зарубіжних, і кожен з них привласнює авторство собі. Так що визначити
справжнього автора того чи іншого способу неможливо. Стаття переслідує
лише освітні цілі, а реалізація методів передбачає знання
програмування, математики та наявність творчого мислення. Будь-яка захист
вимагає творчого підходу, і тільки працюючи своєю головою ви зможете
створити що-небудь унікальне, надійне і заслуговує на увагу.

Ключі реєстрації

Метод: Генерація
ключа
Для генерації ключів ні
в жодному разі не можна використовувати параметри, що вводяться користувачем (ім'я,
email і т.п.). Просто генеруйте ключ, який буде відповідати
деяким правилам. Багато розроблювачів для перевірки ключа використовують
реєстраційні дані (наприклад ім'я), генерують ключ у самій програмі,
і порівнюють значення – це велика помилка. Досить відловити
згенероване значення і захист зламаний. Краще використовуйте серійні
номери, відповідні набору правил, і не прив'язані явно до чого небудь.

Метод: Захист від кейгеном

Використовуйте асиметричну криптографію, а саме – цифрову
підпис (RSA, DSA, ECDSA … та ін.) Детальніше про ЕЦП можна знайти на тому ж
яндексе або Гуглі (yandex.ru, google.com).

Природно, якщо ваша програма
займає пару сотень кілобайт, і варто півпляшки пива, то вбудовувати
подібний захист не має сенсу – вийде Невловимий Джо, хоча можливо
це й на краще. До того ж час перевірки ЕЦП може займати до декількох
секунд, так що якщо ви писали не клон Photoshop або Corel, то
користувачеві це навряд чи сподобається.

Якщо ви далекі від криптографії і не
знаєте що таке електронний цифровий підпис – рекомендую все ж зайти на
google.com і пошукати (в інтернеті інформації по ЕЦП навалом).

Для тих хто в танку, тобто прочитав і
до цих пір не зрозумів як ЕЦП може допомогти – пояснюю:

Ви генеруєте 2 ключі – секретний
(Він буде для вас) і відкритий (прошиває його в програму, причому
бажано його зашифрувати). На секретному ключі будуть підписуватися всі
реєстраційні ключі, які ви надсилаєте користувачам, на відкритому ж
ключі буде проводиться перевірка справжності ключа – виписаний чи ключ вами
(Реєстратором), чи ні. Робіть перевірку підпису в першу чергу, якщо
підпис не збігається – відразу ж завершуйте процедуру перевірки ключа, тим
самим ви не дасте зломщикові навіть дізнатися правила перевірки ключів. Якщо все
ж зломщик отримав від вас реєстраційний код, підписаний на вашому
секретному ключі або, покопавшись з відладчиком, обійшов перевірку підпису і
дізнався правила перевірки реєстраційного коду, то для написання кейгена йому
знадобиться до декількох мільйонів років (приблизно стільки часу піде на
обчислення вашого секретного ключа з відкритого, при солідному модулі
перетворень в ЕЦП). Якщо ви сильні в криптографії та математики взагалі,
то можете розробити свій алгоритм ЕЦП. Це звичайно займе багато часу,
але воно того коштуватиме, навіть якщо алгоритм далекий від досконалості. Річ у
тому, що зломщик може підмінити ваш відкритий ключ на свій, якщо він знає
алгоритм використовуваної ЕЦП, але якщо ви використовували свій власний
алгоритм і не зрадили його розголосу, то йому доведеться ще розбирати ваші
праці, покроково, з відладчиком, що також може затягнутися на мільйони років,
все залежить лише від вашої фантазії.

Природно ніщо не заважає зрадити
реєстраційний код розголосу, підмінити відкритий ключ, або випустити патч –
але це вже інша історія.

Метод: Hash vs RSA
Нещодавно
мені потрапила на очі статися Володимира Каталова, де він описував, як
використовувати спрямоване шифрування для захисту програм. Суть його методу
полягала в наступному – він генерував кілька серійних номерів
випадковим чином, шифрував їх за алгоритмом RSА на відкритому ключі 128 біт,
і прошивав в програму у вигляді ресурсів. Для перевірки серійників, він
шифрував введені користувачем значення на тому самому відкритому ключі і
порівнював з прошитими зашифрованими значеннями. Автор хвалився, що не
потрібний навіть секретний ключ, тому що зашифровані ключі не потрібно дешифрувати.
Мені особисто незрозуміло – а навіщо тоді взагалі RSA? Простіше хешіровать ці
серійники і прошити в програму, а при введенні хешіровать введений ключ і
порівнювати з прошитими. До уваги – написання власного хешу займе не
більше дня, якщо є відповідні навички. Реалізація ж RSA вимагає
в кілька разів більше часу, а шифрування займає набагато більше
ресурсів системи, ніж хешування. Щоб не повторювати його помилок
використовуйте хеш функції, наприклад Haval або SHA.

Також не має сенсу використовувати
спрямоване шифрування для захисту виконуваного коду, як рекомендує
Володимир. Зокрема, він шифрував фрагменти коду (деякі функції,
які повинні працювати тільки в зареєстрованій копії "Advanced ZIP
Password Recovery ") тим же RSA, а для генерації ключа дешифрування
використав частину коду реєстрації, однакову для всіх користувачів. Чи не
повторюйте і цю помилку. З тим же успіхом можна використовувати будь-який блоковий
симетричний алгоритм, наприклад Twofish або AES, це набагато швидше і
ефективніше.

Якщо ви думаєте, що RSA надійніше –
ви глибоко помиляєтеся. Більш надійним може виявитися лише використання
еліптичних кривих з модулем більше 2 ^ 160 (що по стійкості рівносильно
RSA з модулем 2 ^ 1024), але на реалізацію піде купа часу, а складність
перетворень сильно позначиться на швидкодії. Факторизація ж ключа
RSA в 128 біт займає близько 143 млн. групових операцій, так що на будь-якому
домашньому комп'ютері секретний ключ дешифрування підбирається за кілька
хвилин.

Метод: Прив'язка до заліза
У
цьому немає нічого складного. Досить використовувати для генерації ключа
серійний номер вінчестера або проца. Але є одна заковика – апгрейд.
Користувач може змінити гвинт, проц, та все що завгодно. До того ж
вінчестер – це перше що виходить з ладу (з особистого досвіду).
Прив'язуватися ж до мітці томи просто нерозумно, користувач переставить
систему – і ключ буде недійсним. Хоча якщо ваш софт періодично
працює з мережею (гойдалка, поштовий клієнт і т.ін.), і ви можете забезпечити
доставку ключа протягом пари годин, то прив'язатися до залізці – ідеальний
варіант. Ви можете давати користувачеві можливість перезапросіть ключ
реєстрації, тобто він відсилає свої дані, ви передплачуєте йому новий ключ,
а старий ставите в базу недійсних.

Ще один варіант – використання
ключових залозок (дискет, дисків, HASP ключів і т.п.). Це дуже незручно
як для користувачів, так і для вас (реалізатора або розробника).
Користувачеві набридне щоразу при запуску програми вставляти дискету в
дисковод, або перевіряти, чи підключений HASP ключ. До того ж такий захист
вимагає початкових фінансових витрат з боку розробника. Якщо ви
плануєте продавати свою програму через Інтернет, то висилати кожному
користувачеві ключ або дискету може виявитися накладно. Як правило,
подібний захист використовується лише для вузькоспеціалізованої і дорогого
(Вартістю> 200 $) ПЗ.

Метод: Код
активації
Звичайно можуть знайтися розумники, які будуть нахабно
вимагати новий ключ кожен день, мотивуючи це апгрейдом, втратою ключа,
перевстановлення системи, вашої проги, або ще чим. Можуть і просто
використовувати ключ, викладений кимось на огляд. У такому випадку
рекомендую наступне: використовувати додатково код активації.
Прив'язуйте ключ до email адресою юзера, і висилайте код лише на нього.
Зайва захист не завадить, якщо ви розробляєте справді серйозний
продукт, розраховуючи отримати мільйонний прибуток. Зовсім не обов'язково
робити онлайнову перевірку ключа при кожному запуску програми. Просто
використовуйте додатковий ключ (код активації). Кожного разу при
реєстрації програми (введенні ключа), він може надсилатися на сервер,
що буде вже автоматом генерувати код, що відповідає деяким
правилам, і висилати його на email, відповідний введеному ключу. Це
допоможе уникнути таких неприємностей, як використання ключів
сторонніми. При кожному запиті коду активації перевіряйте ключ по базі, і
якщо цей ключ вже недійсний або не існує в базі – не висилайте
код. Для оффлайнових програм (наприклад файлових менеджерів, графічних
або текстових редакторів і т.п.), така система не підходить за цілком
зрозумілої причини – з Мережею вони працюють мало, або взагалі ставлення до неї
не мають.

Зберігання ключів
Зберігати
ключі реєстрації в якому-небудь файл або реєстрі ненадійно, тому що
відстежити і скопіювати такий ключ не становить труднощів. Для зберігання
краще використовувати деякий вільний кластер у файловій системі, і
забороняти доступ до нього за допомогою драйверів ФС, наприклад, позначивши його як
пошкоджений. Це не захистить на 100% від копіювання, але трохи утруднить
процес. Перед розробником виникають і інші труднощі, як визначення
типу ФС і складність роботи з різними драйверами.

Не зберігайте всякі "секретні"
значення, які визначають, чи зареєстрована програма. Зберігайте всі
дані реєстрації в тому вигляді, в якому користувач їх запровадив.

Захист від патчінга

Метод: CRC та інші
хеши
Для перевірки цілісності файлу можна використовувати різні
хеши і контрольні суми. Обійти цю перевірку досить просто, але зайва
обережність не завадить. Зберігайте результати хешування в розділах
ресурсів виконуваних файлів (бажано в зашифрованому вигляді), а перевірці
піддавайте або виконуваний код, або весь файл, виключаючи секцію, де
записаний хеш. Напишіть свою власну функцію хешування. Трохи
ускладнивши життя собі ви дуже сильно ускладните життя зломщикові. До того ж
написавши свою функцію хешування вам можливо вдасться знайти колізію,
таку, що хеш від всього файлу, буде дорівнює прошитому в файл значенням.

Всупереч поширеній думці
перевірка CRC в більшості випадків ніяк не захищає від вірусів. Тільки
якщо вірус підмінив частина коду в програмі. У більшості випадків вірус
просто дописує себе спочатку програми, і запустивши програму, ви в
першу чергу запустіть вірус, а вже потім саму програму, яка
перевірить свою CRC і благополучно загнеться.

Метод: Знову ЕЦП
Можна
використовувати ЕЦП для перевірки цілісності файлу, що виконується. Перевірка
здійснюється на відкритому ключі. До переваг цього методу можна
віднести те, що для підміни підпису необхідно вирахувати секретний ключ,
так що сам результат підпису можна зберігати у відкритому вигляді в будь-якому файлі.
Але не забувайте, що асиметрична криптографія забирає багато
ресурсів.

Метод: Вчимося на
помилках
Якщо раптом у вашій програмі
виявилася мааааленькая помилочка, наприклад, вискакує access violation
при збереженні файлу, але при цьому вона ніяк не впливає на працездатність
програми, а лише набридає користувачу – то залиште її у спокої до пори
до часу. Починайте відловлювати такі помилки лише після виходу
основного релізу.

Здавалося б, як це може захистити
від злому? Справа в тому, що зломщик навряд чи буде відловлювати таку
незначну помилку у вашій програмі, видаляти або змінювати коди
процедур тощо, це для нього зайве. Його основна мета – зняти захист
(Зліпити кейген або патч до програми). Для користувача ж основна мета –
отримати працездатний продукт, і рано чи пізно йому набридне бачити
десяток віконець з кодами помилок при кожному збереженні файлу. Ось на цьому ми
і зіграємо. Починайте діяти, коли на вашу поштову скриньку почнуть
приходити листи зі скаргами. Вилов і виправивши помилку не поспішайте
оновлювати реліз, а просто випустіть патч. Для застосування патча можна
перевіряти відразу купу параметрів, як розмір, дата файлу, CRC, і т.п. Тут
є 2 шляхи:



  • ви можете виправляти помилки тільки в
    файлі, згенерувати патч як різницю між файлом релізу з
    помилкою і файлом виправленого релізу,
  • снегеріть патч як різницю між зламаним
    виконуваним файлом і оригінальним з виправленою помилкою, тобто такий,
    який приведе програму назад до не зареєстрованому увазі.

Другий варіант не завжди підходить,
тому що кряків до програми може бути багато, і кінцевий результат від їх
дії може відрізнятися. Але сподіваюся ви вловили суть – користувач,
який зламав захист вашої програми або не зможе її пропатчити, або поверне
її до первозданного вигляду. І йому доведеться вибирати між економією нервів і
грошей. Зломщик ж навряд чи стане возитися ще й з патчами до вашої
програмі. Недолік – подібні помилки можуть просто відштовхувати
користувача.

Метод: Перевірка CRC з іншого
процесу
Паралельно запускається ще один процес, можливо як
окрема бібліотека всередині того ж winlogon, і з нього періодично
перевіряється хеш головного виконавчого файлу. Можна влаштувати і взаємну
перевірку з системного таймером, значно ускладнивши злом. Цей
виконуваний код можна зберігати в ресурсних розділах файлу, і запускати як
безфайловий процес. Пофантазуйте – може придумаєте щось
оригінальніше.

Метод: Пакувальники
Упакувавши
програму, ви зможете захистити її від дизассемблирования, але тільки якщо ви
використовували нестандартний пакувальник. Наприклад, написаний вами особисто. Той
ж UPX або ASPack серйозним захистом не є. І зрозуміло – знаючи
пакувальник можна розпакувати будь-яку програму. З іншого боку, використовуючи
стандартний пакувальник, ви можете підмінити заголовки, його назви і т.д.,
значно ускладнивши розпакування та дізасемблірованіе.

Метод:
Поліморфізм
Поліморфізм – це напевно один з найкращих способів
захисту, але за все доводиться платити. Справа в тому, що зміна самого
виконуваного коду (наприклад зміна адрес процедур випадковим чином
при кожному запуску) робить неможливим патчінг програми, але на реалізацію
такого захисту піде багато часу. Хоча можна обмежитися просто
дописуванням якого-небудь сміття в кінець програми при кожному її запуску
і / або інсталяції. Крім того, в інсталятор можна зберігати фрагменти
виконуваного коду в зашифрованому вигляді, при інсталяції їх
дешифрувати, і шифрувати знову на серійному номері гвинта, або ще
чого-небудь, а при запуску програми знову дешифрувати їх. Плюси –
прив'язка до заліза і складність для патчінга.

Ключі
шифрування
Прошивати в програму
ключі шифрування у відкритому вигляді (а в якому ж ще), м'яко кажучи,
ненадійно. При знанні ключа і алгоритму на розшифровку піде пару секнуд.
Тому багато розробників використовують динамічно одержувані значення,
наприклад – стандартні коди помилок системи або хеши системних файлів. Для
генерації ключа можна використовувати і деякий генератор – маленьку
функцію, що генерує заздалегідь певне значення. Можете використовувати
переповнення буффера у своїй програмі для запуску цієї функції. У
відладчику виглядає дуже ефектно:)

Захист від отладчиков

Метод: Функції
API
Перевірка результатів API функцій ядра типу IsDebuggerPresent.
Захистить від ламерів, котрі вважають себе крутими хакерами. Користі мало, але
зайва обережність не завадить.

Метод: Процесорний час

Перевіряються мітки часу і лічильника процесора при виконанні будь-
процедури. Якщо за хвилину-дві було виконано лише пару сотень команд – пора
бити тривогу. Точно так само можна ставити мітки спочатку і в кінці процедур.
Якщо простенька процедура виконувалася кілька хвилин – значить її
зупиняли. Як варіант – можна запускати самий звичайний таймер в
окремому потоці, і після потрібного часу перевіряти, завершена чи
процедура. Якщо ні – значить процедура зупинена. Відловлювати 2
незалежних потоку – це вам не одну процидурку колупати, багато зломщики
здаються на цьому етапі.

Метод: Пам'ять
Підрахунок
контрольної суми області пам'яті, де перебуває виконується код, і
порівняння його з заздалегідь прошитим значенням. Таким способом можна
виявити внесені в процесі налагодження виправлення, і повернути програму до
первозданного вигляду.

Метод: перекрути
Запуск
фрагмента коду на нульовому кільці (якщо таке допускає система) і вбивство
дебаггера або самої програми. Це лише ідея, але зате яка!
🙂

Метод: Ще більший
перекрути
Написавши свою власну
віртуальну машину, ви дуже сильно ускладните життя зломщикові. Можна
покласти завдання перевірки реєстрації на деякий псевдокод або скрипт,
що виконується у вашій віртуальній машині. Протрассировать подібний захист
дуже складно, і навіть для досвідчених зломщиків це може виявитися
непереборними труднощами, але не забувайте – немає нічого
неможливого.

Метод: Засоби
введення
Думаю ви вже здогадалися, про що
піде мова. Звичайно ж про блокування клавіатури і, бажано, миші. Але
не назавжди, а на час виконання процедури перевірки реєстраційного
ключа. Новачків подібні методи вводять в ступор – при попаданні на заздалегідь
поставлену точку зупину з'являється відчуття, що машина просто
напросто повисла, і врятує тільки reset. І тільки дизасемблювати або
протрасовано програму зломщик побачить, що блокується клавіатура. Від
дизассемблирования може захистити шифрування або навіть просто упаковка
програми. Для малобюджетних і несерйозних проектів цієї захисту цілком
достатньо.

Метод: Засоби
виведення
Якщо Ви писали серйозний продукт, наприклад, потужний 3D
редактор або солідну гру, то на час виконання перевірки
реєстраційного ключа можна блокувати висновок на екран. Це, звичайно ж,
може викликати дискомфорт у кінцевого користувача, але зломщик просто
задолбался відловлювати і правити цю частину захисту. У початківців кракерів
іноді викликає шок. 🙂

Метод: Контроль
переривань
Асемблер і ще раз
асемблер. Досвідчені зломщики знають його досконало, так що протистояти
їм, використовуючи мови високого рівня, просто марно.

Захист за допомогою контролю та підміни
переривань виглядає наступним чином: копіюється вміст вектора,
який потрібно викликати, новий вектор, а у вихідний поміщається випадкове
значення. Викликається ж новий вектор переривання, замість відомого
зломщикові вихідного. При цьому відстеження відомих вихідних векторів не
дасть зломщикові нічого, крім набору випадкових значень. А постійне
застосування команд дозволу і заборони переривань непомітно при
нормальній роботі програми, але дуже сильно утрудняє
налагодження.

Інші види захисту

Метод: Правова
захист
Встановлюючи програму, юзери зазвичай пропускають Ліцензійну
угоду. Ви і самі мабуть всього пару разів їх читали. Тому при
установці або першому запуску програми робіть таймаут на ліцензію, не
даючи пропустити її. Загалом дайте юзеру час прочитати і все обміркувати.
Робіть період таймауту рази на 1,5 коротше, ніж час, необхідне вам на
прочитання вашої ж ліцензії.

Якщо ви вирішили скласти ЛЗ
самостійно, то слідуйте такі правила:



  • Не намагайтеся що або вигадати самі, для
    початку почитайте ЛЗ відомих продуктів, вони зазвичай складаються
    грамотними фахівцями. Після чого відзначте для себе важливі деталі і
    скомбінуйте.
  • Не повторюйте в тексті ЛЗ по кілька
    однакові за змістом фрази.
  • Складайте ЛЗ так, щоб воно не нагадувало
    постанови кабміну. Робіть його зрозумілим навіть простому
    школяреві.
  • Не використовуйте пропозиції в сотню слів, як
    це роблять багато хто – розбийте його по пунктах.
  • Якщо є гроші і час краще звернутися до
    фахівцям.
  • Не давайте занадто багато гарантій, виходите
    суворо зі своїх можливостей.

Щоб користувачеві не доводилося читати ЛЗ щоразу
при перевстановлення проги, можете створити якусь мітку в реєстрі,
позначає, що на цій машині продукт вже встановлювався. Якщо ви
написали щось унікальне, наприклад архіватор зі ступенем стиснення
1:1000000000000 ….., і не хочете поширювати його забесплатно, то
звичайно ж, необхідно захистити свої авторські права, запатентувати
алгоритм, і завірити нотаріально всі документи.

Метод: Соціальна
інженерія
Краще відразу попередити користувача про наслідки
злому або нелегального використання програми. Крім того, можна і
залякати. Наприклад, що після злому прога не буде працювати як треба, або
взагалі може пошкодити систему. Для зломщика це звичайно не указ, але на
користувачів подіє. Хоча, якщо ви написали наприклад сканер диска
або який-небудь дефрагментатор, краще взагалі не згадувати про гарантії і,
тим більше, про можливі пошкодження, тому що якщо у юзера барахлить гвинт, то
він може звалити провину за пошкодження і втрату файлів на вас. Потім
доводь, хто правий. Подібні програми, навіть найвідоміші і
випускаються солідними фірмами, як правило поширюються за принципом
“As Is”.


Взагалі за допомогою ЗІ можна захистити програму не
гірше, ніж усіма вищенаведеними способами, якщо, звичайно, вашої метою не
є виклик хакеру або групі кракерів. Така практика зводиться не до
захисту від злому, а скоріше до більш успішному просуванню вашої програми
на ринку ПЗ. Користувачі охочіше купують програми, що гарантують
якісну і надійну роботу. Дуже високо цінується регулярна тих.
підтримка. Безкоштовна реєстрація нових версій також може подіяти.
Головне – не наобіцяти зайвого.

За допомогою ЗІ можна і зламувати
програми, хоча зломом це назвати дуже складно. Це більше схоже на
випрошування або вимагання ключів реєстрації. Жоден поважаючий себе
хакер до такого не опуститься, і не стане прикидатися бідним Васею
Пупкіним з Урюпінська, у якого P150 з битим вінчестером, а 100 рублів
на реєстрацію рівносильно місячного голодування всієї його родини. Це швидше
"Розлучення", і є долею кидав і приколістів. З іншого боку – така
ситуація може виявитися цілком реальною, і чи посилати цього Васю на три
байти – вирішувати вже вам самим. Як варіант – можуть бути і загрози, наприклад:
"… Ваша програма форматнул мені вінчестер, і якщо ви не дасте мені ключ,
то я подам на вас до суду …". Тут вже явно проглядається здирництво.
Якщо ви впевнені, що у вашій програмі немає і натяку на форматування
вінчестера, то сміливо рекомендуйте автору листа дислокуватися в
генітальної апроксимації. Бувають і пропозиції протестувати ПЗ в обмін
на реєстрацію. Як чинити в такій ситуації – вирішуйте самі. Звичайно,
надіслав таку пропозицію може виявитися гарним помічником у
налагодженні програми, але як показує практика – швидше за все він взагалі не
буде братися за тестування. У кращому випадку повідомить через місяць, що
все в порядку.

Висновок

Сподіваюся, що даний матеріал допоміг
вам розширити свої пізнання в області захисту програм від нелегального
копіювання, і застосувавши свої знання та вміння на практиці ви все ж таки
досягнете бажаного результату. Пам'ятайте, що найкращий варіант – коли
захист програми не прив'язана ні до якого стандарту, унікальна, і не
документована. Останній момент, звичайно, спірне, оскільки Open Sorce
дійсно є найкоротшим шляхом до вдосконалення, але в даному
випадку необізнаність зломщика тільки зіграє вам на руку. Я також не
рекомендую розробникам використовувати чужі компоненти для захисту,
бажано написати свою власну реалізацію з нуля. Але якщо мова йде
про шифри, хешах, або ЕЦП, то можна скористатися чужими працями, сильно
заощадивши собі час.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*