Pull to refresh

Защита и взлом БД на примере программы «Каталог запчастей»

Reading time 4 min
Views 17K
Если вы хотите защитить базу данных, которая используется в вашей программе, то эта информация окажется вам полезной. Возможно нужно улучшить защиту, например, шифруя значения базы данных и расшифровывая их при выводе.

Итак. Есть программа с папкой DATA, данные из которой очень хочется получить.

Есть несколько вариантов.
  • Превый вариант. Можно пойти сложным путем, снимая скриншоты и экспортируя заявки по одной в excel. Но это долгий способ и неинтересный.
  • Второй вариант. Подумать и раскодировать данные.

Для начала нужно узнать в каком формате хранятся данные в программе. Можно воспользоваться бесплатной программой TrID. Пробуем ...

image

Печаль. Что-то не известное. Похоже на какой-то собственный формат на основе ole datastore. Если это действительно так и разработчики решили заморачиваться и писать собсвенную СУБД то извлечь данные будет очень сложно и долго. Проще будет воспользоваться вариантом 1.

Но, все программисты ленивые и скорее всего это какой то известный формат. Например Access или Firebird. Я бы так сделал. Поискал в каталоге с программой, нет никаких библиотек.

Исследуем дальше. Скачиваем очень полезную бесплатную утилиту с Process explorer, которая показывает все обращения программы к реестру, файлам и всему что возможно.
Запускаем, настраиваем, чтобы моиторила только один процесс catalog.exe — главный исполняемый файл программы.

image

Запускаем программу и смотрим, куда она обращается.

image

О! Она использует ODBC источник данных. Скорее всего используемая бд это access! Ставим себе плюсик. Смотрим дальше. Есть интересный ключ в реестре TraceSQLMode. Погуглив выясняется, что все запросы можно писать в файл. Меняем ключик и ищем файл. Нашли:

image

Смотрим запросы:
SELECT

FROM spare LEFT JOIN photo ON photo.serial = spare.serial


Табличка называется spare, что в переводе означает запасная часть. Значит это не вспомогательня БД и там действительно хранятся наименования деталей. Отлично. Смотрим дальше.

image

Идет обращение к файлу БД не в каталоге с программой. Значит он временно туда копируется. Пробуем открыть в access — без результата, не понимает.

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

image

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

Значит нужно как-то приостановить выполнение программы до запроса, пока файл рабочий. Правильно, трассировкой в дебаггере. Скачиваем дебаггер, например, бесплатный OllyDbg весом 1.3МБ.

Запускаем в режиме администратора, если у вас windows vista и выше.
Присоединяемся к запущенному процессу (attach)

image

Выбираем наш процесс:

image

Возвращаемся в Process Explorer и смотрим стек вызова функции (в контекстном меню события):

image

Точку останова можно поставить на вызове закрытия файла CloseHandle в системном модуле kernel32.dll.

Переходим в этот модуль в дебаггере:

image

Находим нужную функцию:

image

Ставим точку остановки (Breakpoint) — F2.

image

Дальше запускаем выполнение программы, нажав F9. И делаем какое либо действие в подопытной программе. Программа остановится на брекпоинте.

Трассируем (F8) в дебаггрере, пока не появятся записи обращения к реестру перед выполнением запроса. Это будет означать, что файл БД модифицирован для подключения к нему и он пригоден для чтения.

После этого переходим к файлу и копируем его в другое место:

image

Смотрим, что за файл теперь:

image

100% mdb! Это файл MS Access. Переименовываем, открываем, убеждаемся, что все хорошо.

image

Мы успешно получили БД, пригодную для дальнейших модификаций или конвертирования в другой формат.

Раз уж начал писать, то выложу скрипт на groovy для конвертирования данных из MS Access в PostgreSQL БД.

вот он:
import groovy.sql.Sql
java.util.Properties prop = new java.util.Properties();
prop.put(“charSet”, “cp1251”);
sourceSql = Sql.newInstance(‘jdbc:odbc:catalog2’,prop)
targetSql = Sql.newInstance(“jdbc:postgresql://localhost:5432/catalog”,”catalog”,”catalog”, “org.postgresql.Driver”)
def images = targetSql.dataSet(“image”);
sourceSql.eachRow(‘select * from image’) {
def id = it.id
images.add(id:id,block:it.block);
def image=it.getProperty(“image”)
if (image) {
File f = new File(“D:/trid_w32/images/” + id + “.png”);
f.append(image);
}
}
def coords = targetSql.dataSet(“coord”);
sourceSql.eachRow(‘select * from coord’) {
coords.add(id:it.id,block:it.block,x:it.x,y:it.y,r:it.r);
}
def spares = targetSql.dataSet(“spare”);
sourceSql.eachRow(‘select * from spare’) {
spares.add(id:it.id,parent:it.parent,num:it.num,serial:it.serial,count:it.count,spec:it.spec,apply:it.apply,ru:it.ru,cn:it.cn);
}


Запускается интерпретатором:

groovy имя_скрипта.groovy

Выводы: Чтобы защитить базу нужно либо (самое надежное) писать данные в собственном формате, либо шифровать значения в базе данных и разархивировать непосредственно при отображении, а так же использовать вспомогательные методы защиты, например шифровать сам файл, менять сигнатуру файла, использовать встроенные средства шифрования бд.

P.S. Автор этой статьи — Александр Суровцев. Если материал вам понравился, помогите ему пожалуйста получить инвайт на Хабр. Свои инвайты я, к сожалению, все раздал. Адрес его электронной почты — surovtsev.alex на gmail.com, твиттер — mobal1 Большое спасибо!
Tags:
Hubs:
+83
Comments 30
Comments Comments 30

Articles