Безопасность в .NET. Часть I. Ломаем сборку
Безопасность в .NET. Часть I. Ломаем сборку
NeCoders не несут ответственности за любые случаи взлома программного обеспечения или отдельных файлов с помощью информации, предоставленной в данной статье.
1. Введение
Я всегда был уверен, что безопасность — это номер один при написании хорошего программного обеспечения. Во время проектирования она стоит для меня далеко не на последнем месте. Однако некоторые студенты сталкиваются с проблемами ввиду того, что никогда не считались с безопасностью. Они больше сконцентрированы на реализации возможностей системы или вылизывании графического интерфейса. Лекторы же, в свою очередь, едва уделяют ей внимание или же подталкивают студентов принять в своих проектах более действенные меры, что вовсе не правильно.
2. Почему мы должны считаться с безопасностью?
2.1. Ситуация первая
Компания, в которой я сейчас работаю, занимается смарт-картами. Информация, хранящаяся в нашем SDK, в большинстве своем строго конфиденциальна. И мы не хотим, чтобы этим SDK манипулировали наши конкуренты.
2.2. Ситуация вторая
Вам потребовался год на написание программы. Вы потратили много сил и энергии на ее разработку. Затем вы продаете свою программу и обнаруживаете, что вся ваша работа, проделанная в течение 12 месяцев, стала общедоступной. Таким образом, необходимо предпринять определенные меры, чтобы этого не случилось.
2.3. Ситуация третья
Однажды мой начальник пришел ко мне и спросил: "Насколько сборки .NET безопасны?" Я ответил: "Ничто не безопасно, но все, что мы можем сделать, — это постараться усложнить жизнь хакеру". На это он сказал: "Мы мигрировали на Microsoft .NET именно из-за того, что я считал его более безопасным". Начальник был полностью разочарован, когда я показал ему .NET Reflector, написанный Лютцем Ройдером. Эта утилита позволяет получить исходный код на С# из откомпилированной сборки. Вот как она выглядит.
![](kg44603a.jpg)
2.4. Ситуация четвертая
Еще в 90-х годах вы могли заметить, что некоторые условно бесплатные программы применяют следующую технологию проверки. Когда вы устанавливаете программное обеспечение, оно создает ключ в реестре Windows. Фактически программа сохраняет серийный номер или прямым текстом, или в зашифрованной форме. Да, я видел людей, которые прописывают ключи в реестре прямым текстом. Когда приложение стартует, оно проверяет существование конкретного ключа. Если ваш серийный ключ неверен или вообще отсутствует, программа выдаст ошибку. Прямо сейчас я попытаюсь шаг за шагом сэмулировать подобную технику проверки на подлинность в С#.
3. Тестовая машина
• Windows XP Professional Edition SP 1.
• Intel Pentium 4 2, 6 GHz.
• 256 Mb DDR RAM.
• Visual Studio .NET 2003 Professional Edition.
• Microsoft .NET Framework 1.1.
4. Приступаем к делу
1. Идем в Пуск -> Выполнить… Набираем regedit или regedit32.
![](kg44603b.jpg)
2. Ищем раздел HKEY_LOCAL_MACHINE\ Software. Щелкаем правой кнопкой по папочке и выбираем Создать… -> Раздел.
![](kg44603c.jpg)
3. Назовем раздел NeCoders. Теперь щелкаем правой кнопкой по вновь созданному разделу и выбираем Создать… -> Строковой параметр. Назовем его Serial.
![](kg44603d.jpg)
4. После двойного щелчка по ключу перед нами откроется диалоговое окно, где мы можем задать значение параметра. Вводим серийный номер 1111-1111-1111-1111.
5. Отлично. Сейчас запускайте свою Visual Studio .NET 2003.
![](kg44603e.jpg)
6. Создаем новое приложение C# по шаблону Windows Application. Назовем проект CrackingIL.
![](kg44603f.jpg)
7. Загрузится дизайнер, как на рисунке.
![](kg44603g.jpg)
8. Назовем контролы, как указано в таблице.
![](kg44603h.gif)
9. У вас должно получиться что-то вроде этого.
![](kg44603i.jpg)
10. После двойного щелчка по форме будет сгенерирована заготовка для события Load.
public void SecureAppForm_Load(object sender, System. EventArgs e)
{
}
11. В обработчике события пишем:
/// <summary>
/// Проверка реестра на наличие ключа
/// </summary>
public void SecureAppForm_Load(object sender, System. EventArgs e)
{
Registry key = Registry.LocalMachine.OpenSubKey (@"Software\NeCoders");
if(key == null) {
MessageBox.Show("Пожалуйста, получите лицензию для запуска программы!");
this.Dispose(true);
}
else {
string validSerial = "1111-1111-1111-1111";
if((string)key.GetValue("Serial") == validSerial) {
return;
}
else if(key.GetValue("Serial") == null) {
MessageBox.Show("Пожалуйста, получите лицензию для запуска программы!");
this.Dispose(true);
}
else {
MessageBox.Show("Неверный серийный номер!");
this.Dispose(true);
}
}
}
12. Запускаем проект по F5.
![](kg44603j.jpg)
13. Ничего необычного. Простая форма — что здесь особенного?
14. При запуске программа проверяет реестр на выполнение следующих условий:
• Наличие раздела HKLM\Software\NeCoders.
• Наличие ключа HKLM\Software\NeCoders\ Serial.
• Совпадение значения ключа в реестре с 1111-1111-1111-1111.
15. Теперь снова открываем regedit и меняем серийный номер на 1111-1111-1111-1112. В Visual Studio опять жмем F5, чтобы отладить программу.
![](kg44603k.jpg)
Не выполняется третье условие.
16. Далее удаляем сам параметр Serial и жмем F5.
![](kg44603l.jpg)
Не выполняется второе условие.
17. Наконец, удаляем раздел NeCoders. Жмем F5.
![](kg44603m.jpg)
Не выполняется третье условие.
18. Думаю, технологию проверки нарушить будет трудно. Эта часть самая забавная. Надеюсь, вам понравится. На данный момент не имеет никакого значения, как вы будете запускать программу — все равно будет выдаваться одна и та же ошибка: "Пожалуйста, получите лицензию для запуска программы!". Держите это в уме.
Примечание. Нет никакой разницы, что ломать: Debug- или Release-версию.
19. Идем в Пуск -> Все программы -> Microsoft Visual Studio .NET 2003 -> Visual Studio .NET Tools -> Visual Studio .NET 2003 Command Prompt.
20. Перемещаемся в директорию, где у нас лежит CrackingIL.exe.
21. Пишем ildasm CrackingIL.exe /out= CrackingIL.il.
![](kg44603n.jpg)
22. Обратите внимание: в исходную папку будет добавлено три файла.
![](kg44603o.jpg)
23. Открываем CrackingIL.il с помощью любого текстового редактора. Я использовал Блокнот.
24. Вы увидите код сборки. Это промежуточный язык. Классно, правда?
![](kg44603p.jpg)
25. Крутите вниз, пока не увидите это.
![](kg44603q.jpg)
Выделенный фрагмент — это как раз наш обработчик события SecureAppForm_Load, которое мы прежде создали в Visual Studio .NET 2003.
26. Хорошо. Все, что нам сейчас нужно сделать, — это удалить ненужный кусок кода, который осуществляет проверку реестра. Просто удалите весь код между IL_0000 и IL_0075. Вот где вы остановитесь.
![](kg44603r.jpg)
27. Снова идем в консоль и набираем ilasm CrackingIL.il.
![](kg44603s.jpg)
28. Как только вы готовы, запускайте CrackingIL.exe.
![](kg44603t.jpg)
Вы должны увидеть нашу форму. Если это так, то принимайте мои поздравления, т.к. вы успешно крякнули CrackingIL.exe.
5. Заключение
Я думаю, вам понравилась эта статья даже несмотря на то, что она очень простая. Ждите вторую часть.
6. Ссылки
.NET Reflector by Lutz Roeder: http://www.aisto.com/roeder/dotnet/ .
Chua Wen Ching. Перевод Алексея Нестерова
Оригинальную версию статьи можно найти по адресу: http://www.codeproject.com/dotnet/NeCoder01.asp
компьютерная газета
NeCoders не несут ответственности за любые случаи взлома программного обеспечения или отдельных файлов с помощью информации, предоставленной в данной статье.
1. Введение
Я всегда был уверен, что безопасность — это номер один при написании хорошего программного обеспечения. Во время проектирования она стоит для меня далеко не на последнем месте. Однако некоторые студенты сталкиваются с проблемами ввиду того, что никогда не считались с безопасностью. Они больше сконцентрированы на реализации возможностей системы или вылизывании графического интерфейса. Лекторы же, в свою очередь, едва уделяют ей внимание или же подталкивают студентов принять в своих проектах более действенные меры, что вовсе не правильно.
2. Почему мы должны считаться с безопасностью?
2.1. Ситуация первая
Компания, в которой я сейчас работаю, занимается смарт-картами. Информация, хранящаяся в нашем SDK, в большинстве своем строго конфиденциальна. И мы не хотим, чтобы этим SDK манипулировали наши конкуренты.
2.2. Ситуация вторая
Вам потребовался год на написание программы. Вы потратили много сил и энергии на ее разработку. Затем вы продаете свою программу и обнаруживаете, что вся ваша работа, проделанная в течение 12 месяцев, стала общедоступной. Таким образом, необходимо предпринять определенные меры, чтобы этого не случилось.
2.3. Ситуация третья
Однажды мой начальник пришел ко мне и спросил: "Насколько сборки .NET безопасны?" Я ответил: "Ничто не безопасно, но все, что мы можем сделать, — это постараться усложнить жизнь хакеру". На это он сказал: "Мы мигрировали на Microsoft .NET именно из-за того, что я считал его более безопасным". Начальник был полностью разочарован, когда я показал ему .NET Reflector, написанный Лютцем Ройдером. Эта утилита позволяет получить исходный код на С# из откомпилированной сборки. Вот как она выглядит.
![](kg44603a.jpg)
2.4. Ситуация четвертая
Еще в 90-х годах вы могли заметить, что некоторые условно бесплатные программы применяют следующую технологию проверки. Когда вы устанавливаете программное обеспечение, оно создает ключ в реестре Windows. Фактически программа сохраняет серийный номер или прямым текстом, или в зашифрованной форме. Да, я видел людей, которые прописывают ключи в реестре прямым текстом. Когда приложение стартует, оно проверяет существование конкретного ключа. Если ваш серийный ключ неверен или вообще отсутствует, программа выдаст ошибку. Прямо сейчас я попытаюсь шаг за шагом сэмулировать подобную технику проверки на подлинность в С#.
3. Тестовая машина
• Windows XP Professional Edition SP 1.
• Intel Pentium 4 2, 6 GHz.
• 256 Mb DDR RAM.
• Visual Studio .NET 2003 Professional Edition.
• Microsoft .NET Framework 1.1.
4. Приступаем к делу
1. Идем в Пуск -> Выполнить… Набираем regedit или regedit32.
![](kg44603b.jpg)
2. Ищем раздел HKEY_LOCAL_MACHINE\ Software. Щелкаем правой кнопкой по папочке и выбираем Создать… -> Раздел.
![](kg44603c.jpg)
3. Назовем раздел NeCoders. Теперь щелкаем правой кнопкой по вновь созданному разделу и выбираем Создать… -> Строковой параметр. Назовем его Serial.
![](kg44603d.jpg)
4. После двойного щелчка по ключу перед нами откроется диалоговое окно, где мы можем задать значение параметра. Вводим серийный номер 1111-1111-1111-1111.
5. Отлично. Сейчас запускайте свою Visual Studio .NET 2003.
![](kg44603e.jpg)
6. Создаем новое приложение C# по шаблону Windows Application. Назовем проект CrackingIL.
![](kg44603f.jpg)
7. Загрузится дизайнер, как на рисунке.
![](kg44603g.jpg)
8. Назовем контролы, как указано в таблице.
![](kg44603h.gif)
9. У вас должно получиться что-то вроде этого.
![](kg44603i.jpg)
10. После двойного щелчка по форме будет сгенерирована заготовка для события Load.
public void SecureAppForm_Load(object sender, System. EventArgs e)
{
}
11. В обработчике события пишем:
/// <summary>
/// Проверка реестра на наличие ключа
/// </summary>
public void SecureAppForm_Load(object sender, System. EventArgs e)
{
Registry key = Registry.LocalMachine.OpenSubKey (@"Software\NeCoders");
if(key == null) {
MessageBox.Show("Пожалуйста, получите лицензию для запуска программы!");
this.Dispose(true);
}
else {
string validSerial = "1111-1111-1111-1111";
if((string)key.GetValue("Serial") == validSerial) {
return;
}
else if(key.GetValue("Serial") == null) {
MessageBox.Show("Пожалуйста, получите лицензию для запуска программы!");
this.Dispose(true);
}
else {
MessageBox.Show("Неверный серийный номер!");
this.Dispose(true);
}
}
}
12. Запускаем проект по F5.
![](kg44603j.jpg)
13. Ничего необычного. Простая форма — что здесь особенного?
14. При запуске программа проверяет реестр на выполнение следующих условий:
• Наличие раздела HKLM\Software\NeCoders.
• Наличие ключа HKLM\Software\NeCoders\ Serial.
• Совпадение значения ключа в реестре с 1111-1111-1111-1111.
15. Теперь снова открываем regedit и меняем серийный номер на 1111-1111-1111-1112. В Visual Studio опять жмем F5, чтобы отладить программу.
![](kg44603k.jpg)
Не выполняется третье условие.
16. Далее удаляем сам параметр Serial и жмем F5.
![](kg44603l.jpg)
Не выполняется второе условие.
17. Наконец, удаляем раздел NeCoders. Жмем F5.
![](kg44603m.jpg)
Не выполняется третье условие.
18. Думаю, технологию проверки нарушить будет трудно. Эта часть самая забавная. Надеюсь, вам понравится. На данный момент не имеет никакого значения, как вы будете запускать программу — все равно будет выдаваться одна и та же ошибка: "Пожалуйста, получите лицензию для запуска программы!". Держите это в уме.
Примечание. Нет никакой разницы, что ломать: Debug- или Release-версию.
19. Идем в Пуск -> Все программы -> Microsoft Visual Studio .NET 2003 -> Visual Studio .NET Tools -> Visual Studio .NET 2003 Command Prompt.
20. Перемещаемся в директорию, где у нас лежит CrackingIL.exe.
21. Пишем ildasm CrackingIL.exe /out= CrackingIL.il.
![](kg44603n.jpg)
22. Обратите внимание: в исходную папку будет добавлено три файла.
![](kg44603o.jpg)
23. Открываем CrackingIL.il с помощью любого текстового редактора. Я использовал Блокнот.
24. Вы увидите код сборки. Это промежуточный язык. Классно, правда?
![](kg44603p.jpg)
25. Крутите вниз, пока не увидите это.
![](kg44603q.jpg)
Выделенный фрагмент — это как раз наш обработчик события SecureAppForm_Load, которое мы прежде создали в Visual Studio .NET 2003.
26. Хорошо. Все, что нам сейчас нужно сделать, — это удалить ненужный кусок кода, который осуществляет проверку реестра. Просто удалите весь код между IL_0000 и IL_0075. Вот где вы остановитесь.
![](kg44603r.jpg)
27. Снова идем в консоль и набираем ilasm CrackingIL.il.
![](kg44603s.jpg)
28. Как только вы готовы, запускайте CrackingIL.exe.
![](kg44603t.jpg)
Вы должны увидеть нашу форму. Если это так, то принимайте мои поздравления, т.к. вы успешно крякнули CrackingIL.exe.
5. Заключение
Я думаю, вам понравилась эта статья даже несмотря на то, что она очень простая. Ждите вторую часть.
6. Ссылки
.NET Reflector by Lutz Roeder: http://www.aisto.com/roeder/dotnet/ .
Chua Wen Ching. Перевод Алексея Нестерова
Оригинальную версию статьи можно найти по адресу: http://www.codeproject.com/dotnet/NeCoder01.asp
компьютерная газета
Компьютерная газета. Статья была опубликована в номере 46 за 2004 год в рубрике программирование :: разное