СОДЕРЖАНИЕ
Лекція 1. Вступ. Категорії інформаційної безпеки. Захист програм.
Абстрактні моделі захисту інформації
Основні положення по розробці ПО
Помилки, що призводять до можливості атак на інформацію
Короткий огляд технології RAID
Переваги і недоліки основних рівнів RAID
1.3 Симетричні криптоалгоритмы
Загальні відомості про блокові шифри
Основи побудови захисту - крок за кроком
Крок 1. Відключення автоматичного запуску CD
Крок 2. Автоматичне оновлення системи
Крок 3. Відключення непотрібних сервісів
Крок 6. Теорія складання паролів
Як ввести реєстраційний код. Введення пароля або реєстраційного номера є відповідальною справою - хакер постарається відловити адресу пам'яті, в яку буде записаний пароль. Потім на звернення за цією адресою ставиться крапка останову (команда BPM в SoftICE), що дозволяє упіймати початок процедури перевірки реєстраційного коду. Якщо для введення використовуються стандартні елементи введення Windows, то алгоритм дій хакера можна формалізувати і виглядає він приблизно так:
Встановлює точку останову на прочитування тексту із стандартного елементу введення (функції GetWindowText, GetGlgItemText модуля KERNEL32)
При виклику цієї функції аналізуємо її параметри і таким чином визначаємо, за якою адресою буде розміщено прочитуване значення і ставимо звернення до цієї області пам'яті точку останову. А достовірності певної адреси легко переконатися - після виконання функції там з'явиться введений рядок
При спрацьовуванні цієї точки останову ми потрапляємо в аналізатор введеного значення і або робимо генератор реєстраційних ключів, або ламаємо процедуру перевірки. І те, і інше дуже просто зробити - досить тільки вивчити асемблер і API
Набір цих дій стандартний і мені не раз попадалося детальне керівництво типу "Злом Windows програм - крок за кроком", орієнтовані на просунутого користувача.
Розглянь декілька рішень, які можуть утруднити злом на цьому етапі.
Рада _0. Прагніть якомога менше застосовувати стандартні функції (особливо API -шные) і компоненти VCL. Отже Assembler, Assembler і ще раз Assembler ..
Суть цієї ради сподіваюся очевидна - сучасні дизасемблери уміють розпізнавати стандартні процедури високорівневих мов, а API - взагалі окрема розмова - SoftICE має дивовижну можливість - завантажувати символьні імена для будь-яких вказаних бібліотек (особливо для KERNEL32.DLL) - відладка різко спрощується, оскільки ми бачимо імена функцій, що викликаються, і можемо ставити точки останову на виклик функцій по їх імені.
Рада 1. Застосовуйте нестандартний спосіб введення пароля.
Наипростейший шлях - написати свій візуальний компонент для введення реєстраційного коду. Він звичайно повинен буде обробляти події від клавіатури, але момент прочитування коду не можна упіймати побитими методами. Це вже щось, але є другий спосіб злому, заснований на пошуку введеного коду в пам'яті. Для цього в SoftICE є зручна команда "S стартова адреса L довжина 'образец'", яка дозволяє знайти введене значення в пам'яті.
Рада 2. Не зберігаєте введений код в одному місці !
Якщо введений код або реєстраційний номер зберігати в одному місці, то досить легко встановити точку останову на эону пам'яті, в якій зазмещен введений код.
Рада 3. Не зберігаєте введений код відкритим текстом !
Отже, що ж слід зробити. Спершу необхідно завести в програмі 5-10 змінних типу STRING і після введення коду переписати введене значення в них. Робити це краще всього не в одному місці, а розподілити за програмою. Таким чином пошук дасть купу адрес, по яких знаходитиметься введений код. Я у такому разі поступаю так - по таймеру створюю в динамічній пам'яті нову строкову змінну, пишу в неї код. Потім на наступному спрацьовуванні таймера створюю нову змінну, переписую в неї код, а стару знищую. При певній навичці можна заполонити пам'ять значеннями введеного коду і зробити пошук майже даремним. Причому таке копіювання можна поєднати з перевіркою коду або емуляцією цієї перевірки. Потім з ці рядками непогано поробити які-небудь операції - порівняти з чим-небудь ..
Ради 3 і 1 можна об'єднати - створити свій компонент, який дозволить вводити код нестандартним способом з його одночасним шифруванням.
Аналіз реєстраційного коду. Отже, код введений і прийняті заходи для того, щоб його було непросто знайти (хоча знайти те його можна, але цей час, навичка ..). Тепер наступний крок - аналіз. Тому відразу рада:
Рада 4. Ні в якому разі не аналізуйте код відразу після його введення.
Чим далі введення коду від його аналізу, тим краще. Найрозумніше - після введення коду подякувати користувача за співпрацю і повідомити, що з часом буде виконана реєстрація програми. А аналіз коду виробити, наприклад, через 1-2 хвилини в абсолютно іншому місці програми.
Рада 5. Не перевіряйте код тільки в одному місці і не пишіть для перевірки функцію.
Досить знайти і відключити цю перевірку, і захист зламаний. Якщо перевірок декілька, вони різні і розподілені за програмою, то злом утруднюється.
Рада 6. Не перевіряйте пароль одним алгоритмом.
Рекомендується розробити 2-3 алгоритми перевірки, наприклад 1-2 цифри повинні ділитися на 3, а 3-7 накладених по якому-небудь алгоритму на ім'я користувача повинні дати в сумі 4. Ці дві перевірки здійснюємо в різних місцях з досить великим тимчасовим рознесенням - зламавши перший метод хакер не здогадуватиметься про існування ще декількох, які проявляться з часом.
Рада 7. Ні в якому разі не робіть ніяких дій після перевірки. З невідомої причини більшість програм виглядають приблизно так
IF NOT(SuperRegCodeCheck) then
Begin
ShowMessage('Невірний код, подальша робота неможлива');
halt;
end;
У прикладі деяка процедура перевіряє код і при неспівпаданні робить активні дії, які буквально кричать "ось вона де захист !"!. Найкращий крок, - почекати день-два (чи хоч би хвилин 15). Причому усі дії з перевірки слід якнайдалі віднести від видачі повідомлень і інших дій, що робляться при виявленні неправильного коду.
Рада 8. Відволікаючі маневри.
Окрім реальних функцій перевірки коду дуже непогано зробити пару бутафорських - вони викликатимуться після введення коду, проводитимуть активні маніпуляції з введеним значенням, видавати повідомлення про некоректність введеного коду .. - тобто відволікати увагу від реальної перевірки.
Рада 9. Не зберігаєте результатів перевірки в змінній і не використовуйте її для явного обмеження функцій незареєстрованої програми.
Класичний приклад порушення цього правила
IF NOT(LegalCopy) then
ShowMessage('Збереження працює тільки в зареєстрованій версії')
else
SaveFile;
Таким чином елементарний аналіз показує, що змінна LegalCopy зберігає результат перевірки і поставивши на неї точку останову можна виловити саму перевірку. Відредагувавши це значення в пам'яті можна тимчасово зробити копію "зареєстрованою", а установка точки останову на зміну цієї змінної виведе на місце її перевірки. Та і злом зводиться до того, що функція перевірки коду урізається до двох команд асемблера :
MOV [адреса LegalCopy], 1
RET
Рада 10. (витікає з 9) Не зберігаєте результатів перевірки на диску або в реєстрі.
Типова помилка - з'ясували, що копія зареєстрована і зробили де-небудь мітку. Відловити це досить просто (див. опис REGMON і FILEMON). Найкращий спосіб - зберегти пароль і ім'я користувача в тому виді, в якому він їх ввів. Потім при кожному запуску програми перевіряти коректність цього коду, але не забуваючи Раду _11. Нічого не перевіряйте відразу при запуску додатка або відразу після прочитування збереженого імені або коду. Пам'ятаєте, що прочитування коду і його введення у вікні реєстрації ідентичні по заходах захисту - дублювання в різних областях пам'яті, шифрування ..
Висновки: ми влаштуємо перевірку коду в декількох місцях програми, при цьому застосуємо декілька алгоритмів перевірки, не використовуватимемо API.Крім того, варто виконати декілька відволікаючих маневрів.
CRC - контрольні суми. Будь-який файл, рядок або блок даних можна захистити контрольною сумою, яку потім можна розрахувати і порівняти з еталоном. При порівнянні з еталоном звичайно слідує звістка обережно - см перші 11 рад. Отже, рада 12. Захищайте програми і дані контрольними сумами. Це допоможе не лише від злому, але і захистить програми від вірусу або впровадження Трої.
Застосовуйте шифрування програм і даних. Дуже непогано стискувати програму і дані. Я, наприклад, розробив свій власний архіватор - RAR -у і ZIP -у він конкуренції не складе, але стислі їм дані розтискати дуже непросто, доведеться неабияк повозитися. Та і змінити їх проблематично - доведеться розтискати, змінити і стискувати.
Вилов покрокової відладки програми. Існує багато способів, я свого часу провів ціле дослідження цього питання під DOS, назбирав і придумав не менше 20 методів, але вони мало прийнятні під Windows. Найпростіший і надійніший спосіб - таймер. При роботі програми періодично фіксуємо системний час і розраховуємо час роботи фрагментів коду між ними. І якщо 200-400 команд процесора працюють 2-3 хвилини, то тут є над чим замислитися.
Рада 13. Не визначайте дату і час стандартними способом !! Придумайте що-небудь оригінальне.
Рада 14.Не варто зберігати що-небудь секретне у файлах або реєстрі. Робота з файлами або реєстром може бути детально запротокольована і проаналізована, і усе таємне стане явним.
Рада 15.Не зберігаєте нічого важливого відкритим текстом, особливо повідомлення типу "Це незареєстрована версія ."., "Введений пароль не вірний .".Вони для хакера - як для бика червона ганчірка, і дійсно - знаходимо таке повідомлення, ставимо точку останову на звернення до ділянки пам'яті з цим повідомленням і дістаємо можливість упіймати момент видачі цього повідомлення.
Захист "обмеження часу роботи" полягає в тому, що програма яким чином фіксує момент свого першого запуску і працює встановлений час (звичайно 20-30 днів). Після закінчення цього терміну програма відмовляється запускатися. Як перевірити поточну дату я вже десь тут писав - нестандартним способом, наприклад по даті на файлах реєстру або новоствореному своєму файлі. Увесь фокус в іншому - як зафіксувати на комп'ютері дату першого запуску (природно так, щоб знищення програми і її повторна установка не давали ефекту). Використання "секретних" файлів в системних теках або зміни в існуючих файлах легко відловити за допомогою FILEMON. Реєстр те ж відпадає із-за REGMON. Інші методи (типу запису у ВООТ сектор ..) теж неприйнятні - не ті часи, по Windows усе це не пройде. Найоригінальніше (на мій погляд) прошити дату в саму програму і постійно оновлювати її на своєму сайті (природно, автоматично). Таким чином відлік неявно йде від моменту скачування програми з сайту. Є тут правда і мінус - після завершення терміну можна повторно викачати цю програму і отримати ще 15-20 днів .. . З іншого боку це оригінально - користувачеві рано чи пізно набридне викачувати цю програму і він або відмовиться від неї, або купить. Але при цьому варто пам'ятати, що програму можна викачати кілька разів і порівняти варіанти, виявивши, де лежить дата. Тому варто потурбуватися про те, щоб змінився майже увесь файл (наприклад, змінити пару опцій компілятора)
Формування кодів може вестися по наступних основних напрямах:
Жорстко фіксовані коди, прошиті в програму. Їх зазвичай небагато і їх розголос зводить захист до нуля.
Деякий алгоритм перевірки коду. Трохи краще першого, але лише небагато. Візьміть за приклад код Windows - його знає будь-який користувач
Алгоритм перевірки коду, що використовує ім'я користувача. Очевидно, що для кожного імені буде унікальний номер (чи номери - їх може бути декілька, залежно від алгоритму). Це вже краще, але нелегальне поширення тримається на егоїзмі зареєстрованих користувачів - ніщо не заважає їм зрадити ім'я/пароль розголосу, але тоді хоч би можна вичислити винуватця і заблокувати його код
Алгоритм перевірки коду, що використовує ім'я користувача і деякі унікальні або динамічно такі, що змінюються параметри, наприклад інформацію про комп'ютер. Це надійно, дає прив'язку до комп'ютера, але в наше століття постійних апгрейдов дуже незручний.
On - Line реєстрація. Полягає в тому, що програма в On - Line зв'язується з сайтом розробників (чи компанії, що здійснює продужу софтвера) і передає туди ревизиты користувача. У відповідь програмі передається реєстраційна інформація. Цей метод може і хороший для ряду програм, але на мій погляд не витримує ніякої критики з двох міркувань: 1. Ніхто не може гарантувати, що конкретно передасть програма в Инет. А передати вона може усе, що завгодно - параметри комп'ютера, паролі, будь-які дані і тому подібне2. Конкретний користувач може не мати доступу до Инет. Це особливо важливо для програм, робота яких не пов'язана безпосередньо з Мережею. І зареєструвати таку програму його практично ніхто до себе на комп'ютер не пустить (з міркувань п.п. 1)
Рекомендувати тут що-небудь даремне, але я наприклад використовую різновиди методу 3.
Що і як закривати
Якщо ви вирішили поширювати свій продукт як shareware, то напевно вже продумали відмінності між незареєстрованою і зареєстрованою версією. Якщо ще немає, то можу підказати: в принципі, можна використовувати три підходи - демо-версия, time limited -версия і обмежена версія (взагалі-то, можна ще робити упор на совість і просто просити прислати вам гроші, якщо програма сподобалася, але це, на жаль, працює далеко не завжди: по моєму досвіду, у користувача має бути стимул, спонукаючий до реєстрації, причому реальний, а не просто умови ліцензійної угоди).
З демо-версиями усе просто. Двома словами, принцип такий: ви сильно урізаєте можливості програми, просто "викидаючи" частини коду з початкового тексту, перекомпілюєте і викладаєте результат як демо-версию. (Тим же, хто виявляє бажання заохотити вас матеріально, ви просто посилаєте повну версію програми, або повідомляєте, де її можна узяти, - вказавши, наприклад, "приховане" посилання на вашій сторінці.) Обмовлюся відразу, що цей спосіб - гірший з усіх. По-перше, по демо-версии користувач не завжди може зрозуміти, наскільки програма йому підходить. По-друге, один з тих, що сплатили може підкласти вам свиню і розповісти іншим, де можна поживитися повною версією "на халяву" (чи просто почати роздавати її усім своїм знайомим), - все одно у вас немає способу дізнатися, хто ж зробив "добру" справу. А якщо ви посилатимете повну версію звичайною (чи навіть електронною) поштою, то у вас різко збільшаться накладні витрати.
Другий спосіб прийнятніший, але важче реалізовується (чому - поясню пізніше). Принцип полягає в тому, що ви надаєте користувачеві право тестувати ваше творіння "за повною програмою", але тільки протягом деякого обмеженого терміну: скажімо, тридцяти днів з моменту установки на комп'ютер або з моменту першого запуску. Чи як варіант: обмеження на число запусків. Після закінчення відведеного терміну (чи після заданого числа запусків) програма просто перестає працювати або переходить в демо-режим.
Третій, найпоширеніший спосіб: деякі функції у вашій програмі залишаються "закритими", поки вона не буде сплачена. Можна, наприклад, обмежити розмір файлів, з якими додаток може працювати (встановивши деяку "верхню планку"), або не давати зберігати результати роботи, або відключити деякі "просунуті" можливості - тут вже кому як подобається. Після оплати ви посилаєте користувачеві деякий пароль (ключ, реєстраційний номер і тому подібне), який, будучи введеним, розблоковує раніше недоступні функції.
Так, до речі, не перешкодить ще і така річ, як reminder (чи "nag screen", як завгодно). Це зовсім просто: при запуску програма визначає, зареєстрована вона або ні; у останньому випадку користувачеві ненав'язливо нагадують, що не погано б і честь знати, тобто заплатити.
Як це зробити
Можна, звичайно, скористатися послугами третіх фірм - просто купити програмний пакет, що забезпечує перехід від незареєстрованої версії до зареєстрованої після оплати і введення деякого пароля (см, наприклад, www.timelock.com/product/ або www.dataet.com/products/isr 2/). Проблема в тому, що якщо цю систему купило хоч би декілька розробників і захищені у такий спосіб продукти вже є, то можете бути упевнені, що в цьому захисті вже хто-небудь "длубався" і використовувані в ній трюки давно усім відомі. Отже доведеться вам потрудитися самому.
Демо-версії я розглядати тут не буду - і так усе ясно (см вищий). Можна, звичайно, поширювати і їх, але тільки як доповнення до "оцінної" версії, - наприклад, роздавати на виставках, домовитися про включення на різні CD - ROM і тому подібне - виключно в цілях реклами.
З обмеженням за часом трохи складніше. При інсталяції (чи при першому запуску) програма повинна десь запам'ятати поточну дату (чи проинициализировать лічильник запусків), а при наступних запусках - звіряти дати (чи не кінчився "випробувальний термін") або збільшувати лічильник і перевіряти його значення. Якщо ви дійсно знаєте це місце (куди писати дату/лічильник) - візьміть з полиці пиріжок (детальніше про ваші супертайники - див. нижче).
Частково працездатна версія - на мою думку, найбільш правильний вибір. Напевно у вашій програмі є можливості, які можна назвати "професійними" (для просунутих користувачів). Чи просто приємні дрібниці, які можна описати коротким і звучним словом "cool", тобто ті, жити без яких можна, але незручно. До речі, це ще і дуже хороший стимул до купівлі: хочеш зробити свою роботу приємнішою і легшою - купуй!