Как защитить ПО от несакционированного копирования?

Dronidze

Есть проблема :
Устанавливается специализированное ПО на чистую машину.
Машина отдается в чужие руки.
Существуют ли способы защиты от несанкцианированного копирования ПО на другие информационные носители ?

Ivan8209

Существуют.
Но слишком сложны, чтобы это делать просто так.
Если же делать простые способы, то они стольже просто и обходятся.
---
...Я работаю антинаучным аферистом...

Dronidze

Вопрос в том, как спрятать файлы, а линки к ним скрыть не нарушая возможность запуска ПО через линки (типа ярлыка)

rid2000

Если у тебя Линукс... то никаких затруднений... там через ТБит или Сбит - точно не помню...
В xp (и в 2к тожеть наверно)...
Если у тебя НТФС, то там есть на подобие, что и в Линухе, вроди...
Сделай ярлык...
Потом Проперти-- адвансед... (точно не помню )
Но Винду сломают... если захотят

Dronidze

ПО под Win 98. Есть какие-либо альтернативные методы? Пусть если даже необходимо написать лополнительную софтину, например, которая будет запускать ПО, но без нее нифига не будет работать ?

rid2000

такое видел - 100 пудов...
В кафеМаксе... Но там ...

rid2000

У тебя файловая система не защищенная (ФАТ)...
Я бы сказал - НИКАК...

evgen5555

HASP?

Nochka

Есть знакомые или люди умеющие делать такие фишки ?Заплачу!

rid2000

А это что за зверь?

evgen5555

www.hasp.com
Стандартная защита большого процента специального ПО.

rid2000

Я так и не понял как это устроено, но ...Ему легче НТФС поставить... ИМХО...

evgen5555

Locker для компьютерного клуба можно ещё какой-нибудь поставить.

rid2000

А если чел возмет и загрузиться с дискеты?

evgen5555

Вообще, человека с желанием взломать программу и соответствующими навыками никто не сможет остановить.

rid2000

Ну дык, чем сложнее тем менее вероятней взлом
А это совсем просто... даже ниче не надо, кроме дисковода... И то если не будет, можно подцепить

yolki

Эта штука работает так:
В программу встраивается некий код и программа будет работать только если присутствует USB-флешка с нужным файлом.
Флешку вскрыть или скопировать нельзя. это "ключ"
Даже если злоумышленник копирует ПО он не сможет его запустить без нужного ключа. А ключ остаётся торчать в исходной машине.
Этот вариант годится только для разработчиков - т.е. если ты имеешь возможность пересобирать защищаемое ПО.

Ivan8209

Умельцы ломают и их.
Но, пожалуй, это наиболее приемлемое решение.
---
...Я работаю...

Ivan8209

Программа _шифруется_ с тем ключом, который предоставляется в наиболее сложном для воспроизведении виде.
Делается привязка ключа к машине.
---
...Я работаю антинаучным аферистом...

margadon

А в ключ можно и часы встроить, или ещё что, чтобы он был поуникальней...

feliks28

Почему это флешку скопировать нельзя?

krishtaf

как например отучают последние 1с Предприятия от зависимости от HASP-ключа

yolki

А к ней доступ хитрый. это не совсем обычная флешка.

sergey_m

AFAIK, это вообще не флешка.

sergei1969

и что за это потом бывает...

krishtaf

но ведь до сих пор отучают

feliks28

Да имхо все равно пофиг - умельцы эту часть nop'ами забьют...

Ivan8209

А код ты чем будешь расшифровывать?
---
...Я работаю антинаучным аферистом...

rosali

Вообще, человека с желанием взломать программу и соответствующими навыками никто не сможет остановить.

Вообще этот человек может стоить дороже, чем эта программа!

0000

У меня на работе ключ Guardant воткнут в LPT-порт и на флешку как то мало смахивает (нахрена она вообще тама то? инфы то хранить совсем мало надо).

Ivan8209

Чем больше --- тем лучше.
Во-первых --- длина ключа, во-вторых --- привязка,
а в третьих --- что-нибудь, чтобы сбить с толку вероятного противника.
---
...Я работаю антинаучным аферистом...

Angelika_900

это с каких пор HASP стал флешкой?

feliks28

Я не буду, а люди, кажется, всегда дизассемблили...

rosali

дизассемблили...

Чего они дизассемблили если он зашифрован?

evgen5555

Hint: Процессор не может исполнять код в зашифрованном виде.

Ivan8209

Как насчёт связки Хафман --- Лемпел---Зив --- Райвест?
Если грамотно увязать, то просто так не продизассемблируешь.
---
...Я работаю антинаучным аферистом...

feliks28

А как насчет связки Программа_1 - Программа_2 - Прогоамма_3 ?
Может хватит уже транскриптить малоизвестный софт?

Ivan8209

Товарищи Хафман, Лемпел, Зив и Райвест настолько хорошо известны,
что не знать их можно только от безграмотности.
---
...Я работаю антинаучным аферистом...

smnikiforov

угу

rosali

Процессор не может исполнять код в зашифрованном виде.

Под отладчиком они что ли по нему ходят? Все равно не очень понятно чего дальше... И уж при чем тут
умельцы эту часть nop'ами забьют
ваще не ясно... Какую в таком случае часть? Можно удалить проверку какого-нибудь пароля, а тут?...

Chupa

Huffman, блиа
> А Райвест хрен знает как пишется
Rivest

rosali

Ну извините

evgen5555

Под отладчиком далеко ходить не надо, достаточно добраться до интерпретации самого LZH.

Ivan8209

До ЛЗХ ещё добраться надо.
---
...Я работаю антинаучным аферистом...

sobleb

А если взять серийные номера устройств, устрановленных на машине и прописать в проге в зашифрованном виде?

feliks28

Безусловный переход с начала проверки на ее успешный конец сведет на нет все твои старания...
Хоть в открытом виде серийники пиши...

sobleb

Да ведь по такому принципу всё и ломают...
Чем отличается наличие некого ключа на каком-нибудь устройстве? Только тем, что понадобится либо эмуляция, либо подобное устройство...

Ivan8209

Не "прописать," а зашифровать программу ключом, основанным на них.
Неужели до народа так и не доходит,
что простое хранение --- в любом виде! --- ни от чего не спасает?
---
...Я работаю антинаучным аферистом...

sobleb

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

feliks28

И как ты предлагаешь скрыть кусок проверки?

sobleb

Если я бы это знал, то не сидел под Виндой...

Ivan8209

Читай выше, как.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."

Dasar

Нединамическая шифрация - откручивается на раз.
Динамическая шифрация требует серьезного изменения кода.

Ivan8209

Верно.
Без проверки целостности защиты нет.
---
...Я работаю антинаучным аферистом...

Dasar

Самая серьезная защита - это вынос часть функционала программы в ключ

Ivan8209

Да, но всегда есть вопрос о защите ключа.
Тебе придётся выносить в ключ достаточно большой объём данных,
чтобы сложно было их восстановить, но тогда прощай, привязка.
---
...Я работаю антинаучным аферистом...

sania1974

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

Ivan8209

Совершенно ненадёжны --- откручиваются на раз.
---
...Я работаю антинаучным аферистом...

gopnik1994

Всегда есть такой участок кода, который не зашифрован.
Это код, который занимается расшифровкой, вот его-то и достаточно сломать - вставить "жучок", который будут все расшифрованные процедуры сохранять в надежное место, а потом слинковать эти процедуры...
Это, конечно, уже не так тривиально, но вполне автоматизируемо...

Ivan8209

Как насчёт Лампеля с Зивом?
А проверки целостности?
---
...Я работаю антинаучным аферистом...

Dasar

> проверки целостности?
Во-первых, целостность чего проверять? целостность exe-шника на диске? целостность функции в памяти?
во-вторых, проверку целостности можно тоже отключить.

freezer

NTFS + шифровка, прогу ставишь под админом, юзеру говоришь пароль обычного пользователя, которому файлы проги не доступны, саму прогу запускает служба, работающая под local system... сломать будет непросто.

Dasar

В этом случае пройдет атака на WM_TIMER, т.к. у тебя есть GUI запущенный под админскими правами.

freezer

что за атака такая?.. зачем мне вообще, WM_TIMER обрабатывать? Да и как устраивать атаку на прогу, если у тебя нет ее бинарника даже?

Dasar

> зачем мне вообще, WM_TIMER обрабатывать?
это сообщение будешь обрабатывать не ты, а система.
WM_TIMER
WPARAM wParam
LPARAM lParam;

Parameters
wParam
[in] Specifies the timer identifier.
lParam
[in] Pointer to an application-defined callback function that was passed to the SetTimer function when the timer was installed.
Обрати внимание на параметр lParam.
Грузишь в адресное пространство программы свой код, далее через SendMessage посылаешь программе сообщение WM_Timer, где в качестве lParam передается указатель на твой загруженный код.

freezer

Грузишь в адресное пространство программы свой код, далее через SendMessage посылаешь программе сообщение WM_Timer, где в качестве lParam передается указатель на твой загруженный код.

Гм... ну и как ты в мой процесс свой код загрузишь?.. Предположим, у юзера нет прав на запись в реестр и хук он поставить не сможет.
Наконец, никто мне не мешает запустить гуёвый поток под пониженными привилегиями

Dasar

Вводишь, например, специально подготовленную 300-метровую строку, далее быстренько ее локализуешь в памяти

Dasar

> Наконец, никто мне не мешает запустить гуёвый поток под пониженными привилегиями
Скорее процесс, а не поток.
Да, это уже более надежное решение.

freezer

ха! как ты в мою прогу введешь 300-метровую строку?!

freezer

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

Dasar

с внешним миром твоя программа как-то общается?
Если общается, то, наверняка, есть строки, если есть строки, то значит можно туда забабахать длинную строку.

Ivan8209

Код в памяти.
Вообще, ерунду мы обсуждаем.
Утверждение: при грамотной защите время, затрачиваемое на слом,
сравнимо или превышает время, затрачиваемое на переписывание.
Вот из этого и надо исходить.
---
...Я работаю антинаучным аферистом...

freezer

в память моего процесса строка попадет, только если я сам на это соглашусь:


char buf[256];
GetWindowText(hWnd, buf, 255);


откуда тут в моей памяти возьмется 300 мегов?

Dasar

> Утверждение: при грамотной защите время, затрачиваемое на слом,
сравнимо или превышает время, затрачиваемое на переписывание.
Очень сильное утверждение, и имхо, неправильное.
Во-первых: ломать, не строить.
Во-вторых: программа - это белый ящик, а не черный, поэтому априори все действия программы доступны.
По опыту могу сказать, что при набитой руке довольно серьезные защиты снимаются за пару дней.

freezer

сегодня на работе классно повеселился: мы до этого NTLM-аутентификацию юзали, начальник решил что это работает слишком медленно и все переделал (в целях оптимизации ). Я сегодня глянул что он там наваял, оказалось что теперь клиентская прога передает имя юзера почти открытым текстом (раньше - токен передавался). Я не долго думая, заменил в коде System.Security.Principal.WindowsIdentity.GetCurrent.Name на строковую константу с его сетевым именем и оно сработало! Думаю, вот он завтра обрадуется

Dasar

например, вот так:


for (i = 0; i < MAX_FLOOD; ++i)
PostMessage(WM_FLOOD, ...);
PostMessage(WM_TIMER, ...);
PostMessage(WM_SETTEXT, big_string);

freezer

ну и?.. на каком месте я тут GetWindowText вызываю? и почему ко мне все 300 мегов придут?

Ivan8209

Правильнее условие должно бы звучать так:
стоимость разработки защиты не должна быть больше убытка при взломе.
"Серьёзные" --- это в каком смысле?
Помнишь, как ставится задача взлома шифра?
По неизвестному ключу и _известному_ алгоритму.
Целостность проверяется расшифровкой и расжиманием кода с
переписыванием старого.
Неверно сделал --- ошибка.
Не там разместил --- тоже ошибка.
Латать код на лету не настолько просто.
---
...Я работаю антинаучным аферистом...

Dasar

> и почему ко мне все 300 мегов придут?
в чьей очереди сообщений будут стоять все вышезапостенные сообщения?
и в чьем адресном пространстве располагается эта очередь?

Dasar

Еще раз повторю, что проверка на целостность убивается первой.

Ivan8209

Ты код не получишь верный, если её убьёшь.
Как прога работать будет?
---
...Я работаю антинаучным аферистом...

Dasar

> "Серьёзные" --- это в каком смысле?
те, которые использовали всякие полиморфные алгоритмы, динамическую шифрацию, проверку целостности, недокументированные команды, вставки убивающие дебагер и т.д.

Dasar

Зачем проге для нормальной работы (выполнения полезного функционала) код проверки целостности?
Правильно, совершенно не нужен.
Поэтому его можно безболезненно за-nop-ить, или поставить в начале проверки jmp

freezer

в чьей очереди сообщений будут стоять все вышезапостенные сообщения?

гуёвого потока.
и в чьем адресном пространстве располагается эта очередь?

моего процесса...
но ты уверен, что у этого процесса есть прямой доступ к очереди сообщений, не через GetMessage/PeekMessage etc?

Dasar

> у этого процесса
это у какого?
ps
напомню, что обсуждается тот случай, когда именно гуевый процесс запущен под админскими правами.
Если же программа написана, как честный клиент-сервер (сервер, не содержащий gui, запускается под админскими правами, а клиент запускается под правами пользователя то на такой вариант стандартной атаки нет.

Ivan8209

Например, для построения ключа к внутренней расшифровке.
Для хранения ещё каких-нибудь вспомогательных данных.
---
...Я работаю антинаучным аферистом...

Dasar

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

freezer

блин... всякие данные системных драйверов тоже находятся в адресном пространстве проги, запущенной простым пользователем VasjaPupkin, но это не означает что пользовательский код имеет к ним прямой доступ. С очередью сообщений, вроде бы, точно так же. Кроме того, в очередь сообщений можно передать только два DWORD'а + HWDN + код сообщения, никакого типа маршалинга PostMessage не делает, так что как ты в очередь положишь 300 мегов мне совершенно не понятно (учитывая, что по умолчанию там места только на 8 сообщений).

Dasar

> учитывая, что по умолчанию там места только на 8 сообщений
откуда такая информация?

rosali

char buf[256];

А что, этого не достаточно? В этих 256 байтах можно скажем передать управление в какой-нибудь dll?..

Dasar

> учитывая, что по умолчанию там места только на 8 сообщений


int _tmain
{
MSG msg;
PeekMessage(&msg, 0, 0, 0, 0);
for (int i = 0;;i++)
{
bool res = 0 != PostMessage(0, WM_UNDO, 0, 0);
if (!res)
{
Console::WriteLine("error: {0}", __box(GetLastError;
Console::WriteLine(__box(i;
break;
}
}
return 0;
}


вышеуказанная программа дохнет на числе 10000 на WinXp.

rosali

всякие данные системных драйверов тоже находятся в адресном пространстве проги, запущенной простым пользователем VasjaPupkin, но это не означает что пользовательский код имеет к ним прямой доступ

А какой смысл тогда их там располагать?

Dasar

> никакого типа маршалинга PostMessage не делает
Да, прокол вышел.
значит берем TextBox в атакуемой программе.
посылаем ему EM_LIMITTEXT 3000000
делаем copy/paste строки в данный текстбокс
строка попала в нужное адресное пространство

sergey_m

Я вообще плохо въезжаю в ваш разговор, поэтому извините за возможно тупой вопрос. Вот это:
значит берем TextBox в атакуемой программе.
посылаем ему EM_LIMITTEXT 3000000
делаем copy/paste строки в данный текстбокс
строка попала в нужное адресное пространство
означает, что в любой windows GUI программе есть переполнение?

Dasar

> означает, что в любой windows GUI программе есть переполнение?
что ты в данном случае понимаешь под словом "переполнение"?

sergey_m

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

Dasar

При правильном программирование - нет.
т. к. когда уже непосредственно код получает данную строку, используется функция: WM_GETTEXT (buffer, buffer_len).

rosali

Насколько я понял пока цель не засрать чужой код, а разместить свой хоть где-нибудь. Утверждается, что потом можно передать на него управление через WM_TIMER... Хотя пока не очень ясно как угадать его виртуальный адрес?..

Dasar

адрес угадывается банальным перебором, именно для этого большая строка и заталкивается, чтобы можно было быстрее нащупать переданную строку.

sergey_m

Хорошо, а куда эти 300Мб записываются? Под них же не аллоцируется память?

Dasar

> Под них же не аллоцируется память?
аллоцируется. Команда Paste аллоцирует память

rosali

адрес угадывается банальным перебором

Не понял... если не угадать с первого раза, то упадет же?..

Dasar

Дык, значит придется перезапустить прогу.

sergey_m

Тогда объясни доступно, чего ты добиваешься заливанием 300 Мб строки?

freezer

Команда Paste аллоцирует память

вопрос в том, где она аллоцируется Есть такое подозрение, что в адресное пространство моего процесса оно попадет только после того, как я GetWindowText вызову

freezer

ну идея тут такая: допустим, мне нужно впихнуть в другой процесс вредоносный код размером 100 байт и передать в него управление. Для этого я повторяю этот код 3 миллиона раз, впихиваю его в память процесса, потом делаю переход по случайному адресу. С большой вероятностью я попаду на мой код, но с каким-то смещением. Вероятность угадать смещение при попадании в блок - 1% (что довольно много). Потом останется добиться полного совпадения.

freezer

на 2k - тоже... похоже, у меня устаревшие сведения.
Кстати, если посылать через SendMessage, то почему-то отваливается на 1400

sergey_m

Понятно, то есть переполнения нет, но как делается переход по случайному адресу?

DiDiPi

SendMessage с _очередью_ не работает, а вызывает напрямую соответствующую обработку в оконной процедуре, тут этот пример не катит.
1400 это invalid window handle, значит и оконной процедуры вызвать не смог

rosali

переход по случайному адресу?

Если надыбать где-то hwnd и вызвать PostMessage(hwnd, WM_TIMER, wparam, lparam) и если в окне будет дефолтная обработка этого сообщения, то управление уйдет на lparam.
PS Кстати, это не очень устаревшие сведения? Может залепили давно, а мы тут изучаем?

DiDiPi

Дык вроде давно уж разобрались.
http://www.bugtraq.ru/rsn/archive/2002/12/11.html
http://support.microsoft.com/?kbid=328310
Подробностей не знаю, может быть, запретили обработку с "левым" wParam (левый идентификатор таймера).
Оставить комментарий
Имя или ник:
Комментарий: