Как мне удалось взломать приложение

    Здравствуй уважаемый %habrauser%. В данной статье я поделюсь с вами историей о том как я взломал приложение. Взломать сам EXE-шник приложения не получилось, но желаемый результат был получен другим способом. Чтобы сохранить конфиденциальность буду опускать некоторые моменты, сильно обрезать скрины. И так

    image

    Этот неживой и баснословный мир


    Все начиналось хорошо, ничто не предвещало беды. В один поздний вечер мне один хороший знакомый попросил об одной услуге выражаясь фразами типа «ну ты ж у нас программист». Писал он о просьбе взломать некое приложение. На что я ответил, что постараюсь, но о удачном взломе не гарантирую. На следующий день мы встретились, он мне дал диск и объяснил, что это за приложение.

    Начало


    Есть некая организация, которая занимается обучением людей для сдачи одного определенного экзамена. Чтобы получить это приложение надо пойти в эту организацию, записаться и оплатить курсы. В конце пройденного курса организация за дополнительную плату дает диск с установщиком программы с индивидуальным ключом активации. Приложение позволяет делать тесты, смотреть на результаты. Есть некий режим «На экзамене», который позволяет имитировать среду экзамена. Приложение выдает случайные тесты из разных разделов. Все хорошо и прекрасно.

    Первые шаги — экспериментируем


    Устанавливаем приложение запускаем его, чтобы посмотреть, что оно из себя представляет.
    Открывается такой сплэш экран, и приложение на несколько секунд зависает (данное зависание не спроста).

    Открывается сплэш экран, а за ним, через несколько секунд открывается такое окошко:

    image

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

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

    Лезу в папку уставленной программы:

    image

    Структура:

    1. Arial Narrow.ttf – шрифт

      Кеп
      image
    2. DataSource.data – файл БД в котором все тесты
    3. *************.exe – екзешник приложения
    4. MySql.Data.dll – бесплатная opensource библиотека от MySql

    Наличие библиотек MySql.Data.dll в папке с программой навела на мысль о том, что приложение скорее всего написано на языке C#. Ни для кого не секрет то, что не защищенные специальными утилитами приложения написанные на этом языке программирования легче всего поддаются декомпиляции. Обрадованный данным предположением, мой мозг автоматически дал мне сигнал запустить программу IlSpy, которая позволяет декомпилировать приложения написанные на C# и открыть приложение в нем.

    В итоге передо мной открылась такая картина

    image

    Как видно приложение действительно написано на C#, отображается информация о разработчике, используемой версии .NET. После открытия структуры приложения последовало разочарование.

    image

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

    Попробуем деобфусцировать и получаем такой результат:

    image

    Судя по сообщению приложение обфусцировано с помощью .NET Reactor, и декомпилировать его не представляется возможным. После долгих поисков метода деобфускации от защиты .Net Reactor найти так и не удалось.

    Тогда я, решил попробовать хотя бы открыть файл базы данных DataSource.data, в SQLite.

    image

    От нас требуется пароль от базы данных.

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

    Уважаемый вы здоровы?


    Иногда шаг вперед является результатом пинка в зад

    Прошло какое-то время. Когда я копался в файлах нашел эту программу и обратил внимание на файл MySql.Data.dll. А что если поменять MySql.Data.dll на модифицированный, чтобы он отображал строку подключения к бд. Для этих целей есть opensource программа — dnSpy. Она позволяет редактировать код .net приложений и библиотек. Загружаем dll файл в программе и находим класс MySqlConnection и редактируем функцию .ctor:

    image

    Добавим строку:

    System.Windows.Forms.MessageBox.Show(connectionString);


    image

    Нажимаем «Compile», сохраняем файл, заменяем с оригинальным и наконец запускаем приложение.

    Выйдет такое окно:

    image

    По названию сервера cloudapp.net можно сделать вывод, что база данных создана на Azure.
    Скачиваем любую бесплатную утилиту подключения к бд, скажем HeidiSQL. После ввода полученных данных подключения открылась БД. А вот и наши ключи активации:

    image

    У большинства ключей отсутствовали значения полей Name, CardId, Phone. Видимо эти ключи еще не продали. Добавил из себя 16 значный ключ, и зарегистрировал программу. В папке с установленной программой появился файл data.dat и приложение выдало сообщение об успешной регистрации. В таблице с ключами пропал созданный ранее ключ. После недолгих поисков этот ключ я нашел в таблице logs. Там был мой ключ с подробным описанием характеристик моего компьютера таких как модель, процессор, видеокарта и т.д. Эту строку я удалил, чтобы не оставить после себя следов.

    Итог


    Стоит отдать должное разработчику приложения, он позаботился о защите своего приложения. Он защитил БД, обфусцировал приложение, содержание data.dat файла тоже зашифровано, но о проверке хеша используемой библиотеки он позабыл.

    P.S.: Вред организации, взлом приложения не произвел. К тому времени, пока удалось взломать приложение, другу оно уже не было надобным. Активированная копия приложения была только у меня и третьим лицам передано не было. В связи с ненадобностью приложения у себя я тоже её удалил.

    Средняя зарплата в IT

    120 000 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 3 679 анкет, за 1-ое пол. 2021 года Узнать свою зарплату
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 46

      0
      «декомпилировать его ну удается возможным.»
      Вероятно имелось в виде «декомпилировать его не представляется возможным»
        0
        спасибо, подправил)
        +1

        Забавно, давно у Рихтера кажись было написано пару строк по поводу секурности дот нет не на серверах. Так вот секурности предполагалась за счёт недопущения получения сборок. То есть если ты влез на сервер но уже ничего не поможет. В связи с этим вопрос, строгие имена не гарантируют безопасность в случае со статьей. Мне на ум приходит только компиляция приложения в нативный код на клиентской машине и уже в таком виде проверять целостность и ТД. Какие ещё есть способы защиты?

          0
          В связи с этим вопрос, строгие имена не гарантируют безопасность в случае со статьей.

          Если это вопрос — то нет, не гарантируют, если ваша цель именно сломать приложение. Просто цепочка слегка удлиняется — потребуется перелопатить все сборки через dnSpy.

          Способы защиты, если уж мы считаем нормой лезть за активацией в сеть — просто чуть разумнее, чем в этом примере. Например идёте с ключём в сервис активации, он вам возвращает пароль к локальной базе. Непонятно зачем это делать напрямую конектом к базе, причем с такими роскошными правами. Если уж не хотелось заводить какой-то отдельный сервис — можно было права учётке ограничить на какую-нибудь хранимку которая вернула бы нужны данные.
          +1
          В интернете гуляет и мод de4dot с поддержкой .NET Reactor 5.0. Возможно, имело смысл попробовать.
            0
            значит плохо искал)
            +2
            Спасибо, достаточно интересная статья.

            Мне кажется тут плохая защита удаленной БД.
            Во-первых не было смысла давать прямой доступ к БД, проще было разместить простое веб-приложение.
            Во-вторых можно было ограничить права пользователя, только на одну конкретную операцию, а именно на проверку наличия ключа. К этому так же ограничит кол-во запросов в секунду.
            Хотя о чем тут можно говорить, если весь тест расположен в локальной базе.
              +1
              А ведь могло не оказаться прав на таблицу аудита…
                +1
                учитывая то, что приложение лезет в БД, и само же приложение там делает изменения (добавление логов активации в бд к примеру), то об ограниченных правах тут даже речи не может быть. там была таблица users, в которой были логины и хеши паролей. видимо есть админка управления. все храниться в этой бд и видимо пользователь один с максимальными правами)
                  +1

                  Вполне могли быть отдельные права на таблицы. Другое дело, что даже R/O-доступ к таблице пользователей — весьма серьёзная дыра в безопасности.

                +6
                Ну, тут даже взломом сложно назвать… Разрабы сами положили на клиент логин и пароль от базы данных. Такие косяки даже джунам в 2018-м не позволительны.
                Эх… Наберут по объявлению…
                  0

                  Именно. Можно было просто найти в коде вызовы к базе и выдернуть оттуда данные для подключения.


                  Обфускация обсускацией, а язык-то не меняется.

                    0
                    Обфускация обсускацией, а язык-то не меняется

                    язык то не меняется, но код абсолютно не читаемый
                      0
                      Обфускаторы ещё и строки шифруют, так что это не всегда возможно.
                        0
                        здесь строки были как раз таки зашифрованы. вряд ли что-то полезное можно было бы получить
                      0
                      Подскажите, а как быть если нужно подключаться к удаленной базе? Ограничить в правах подключаемого пользователя? Я джун, не кидайте камнями.
                        +3

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


                        Так что ответ — никак. Делать поверх базы api и отдавать только его.
                        Использовать прямой коннект к базе из клиентского приложения можно разве что в доверенной среде. Например, в рамках локальной сети организации, когда авторизация в базе делается по AD-учётке текущего пользователя.

                          0
                          Обязательно должен быть API между клиентом и базой.

                          Вообще, по хорошему, база должна быть доступна только под 127.0.0.1 (по дефолту так и есть), либо внутри сети приложения (если мы говорим про масштабирование), т.к. в СУБД тоже могут быть 0-day уязвимости.
                            –1
                            Под API, вы имеете в виду ORM?
                              +2
                              Под API я имею в виду API-сервер. Клиент должен отправлять запросы на сервер с авторизацией. Как реализовать сервер — дело каждого. Самое простое — HTTP с oAuth2.

                              А уже на сервере запросы к БД можно делать как угодно: ORM, голый SQL, да хоть через handlersocket…
                                –1
                                Веб-приложения также нужно реализовать?
                                  0
                                  А какая разница, кто у вас клиент — веб-страница, десктопное/мобильное приложение или чайник Xiaomi?
                                    0
                                    Но у веб-приложений, реализованных на паттерне mvc, контроллер служит в качестве серверной части приложения, зачем ему что-то еще?
                                      +2
                                      Ну, во-первых, контроллер служит не «для серверной части приложения», а для направления данных от пользователя к системе и наоборот. Бизнес-логика, например, описывается в компонентах, а не в контроллерах.

                                      Во-вторых, в современных веб-приложениях повсеместно отделяют фронтенд и бэкенд. И общаются они между собой по API-интерфейсу.
                                        0
                                        Но они же в mvc итак отделены
                                          +1
                                          Какая нафиг разница?) Вы не должны давать в клиентском коде прямой доступ к базе данных. Точка.
                                          Как вы будете это реализовывать, дело ваше.
                            0
                            Да просто засунуть строку подключения в webconfig/appconfig, оттуда их достать нельзя(как я знаю), другого выхода нет
                              0
                              По умолчанию app.config превращается в appname.exe.config и легко редактируется блокнотом чем угодно
                                0

                                Шифрование строк подключения производится ключом пользователя ОС. Если перенести этот файл на другой компьютер, расшифровать его приложение уже не сможет. Это защита только от удалённого доступа к файлам на серверах, локальный админ может расшифровать конфиги так же, как и зашифровал.

                                0
                                Одно из возможных решений, если мы остаемся в двухзвенке — доступ к данным только через хранимые процедуры. Тогда такой взломщик, даже зайдя в базу, получит не больше данных, чем мог бы получить в приложении. Все процедуры и таблицы у другого пользователя, а у приложения — только права на выполнение процедур.
                                  0

                                  Если ну никак нельзя сделать АПИ, то можно просто плотить view по мастер таблице с аккаунтами и давать каждому клиенту доступ к view. Но далее — надо правильно настроить сервер, чтобы клиент не запускал n-n-n-n… запросы, отъедая по 100% от ядер.

                                0
                                Интересно
                                  0

                                  А что бы ты делал, если данные в БД были зашифрованы, а ключ к расшифровке находится, где-нибудь на сервере(да, странно, но все все-таки)

                                    +1
                                    наверное уже сдался бы)
                                    0
                                    Материал весьма интересный, с удовольствием прочитал, порадовало как ларчик просто открывается. Но… Слишком много размазни на скринах. Неаккуратной, неопрятной размазни. Сплешскрин — зачем? Чтобы посмотреть на слова «Version» и «Copyright»? Замазать размер шрифта Arial — спешите видеть, раскрытие личности по размеру файла!
                                    Для Хабра можно было и постараться.
                                      –1
                                      Неаккуратной, неопрятной размазни

                                      следующий раз учту. даже не обраил на это внимания

                                      раскрытие личности по размеру файла!

                                      в условиях страны, которой я живу за такие деяния можно схлопотать не мало лет. поэтому замазал даже размеры файла
                                      0
                                      А без декомпилятора слабо? Ну там как в старые времена: Запустить Иду, найти функцию проверки активации, пропатчить nop-ами и т.д.?
                                        0

                                        Да помню эти старые добрые времена

                                          0
                                          к сожалению не разбираюсь в этой программе. хотелось бы научиться да вот руки все не доходят
                                            +4
                                            Сейчас бы .NET в иде патчить.
                                              0
                                              Как ни странно, я это делал, когда нужно было исправить ровно 1 байт, а не пересобирать всю DLL.

                                              Декомпилировал сборку в dotPeek, разобрал логику, нашёл нужный переход. Нашёл соответствующее место в IL-коде. Однако, по какому смещению находится в файле нужный байтик, ни один инструмент, кроме IDA, мне не подсказал.
                                              +2
                                              Не вижу смысла усложнять себе жизнь. Вот когда часть программы, к примеру шифрование, в нативной библиотеке лежит, тогда и IdaPro пригодится.
                                                0
                                                Для отладки .NET лучше использовать специализированный отладчик, допустим, ILSpector или dnSpy.
                                                0
                                                Когда-то тоже пытался взломать программку на c#. Сначала пытался посмотреть алгоритм создания файла для trial лицензии чтобы самому создать файл и получить бесконечный период. Но там был какой-то хитрый алгоритм с ключами шифрования. Потом хотел просто поменять код чтобы лицензия была валидна при любых аргументах. Но программа тянула не локальные dll, а с GAC. В итоге сдался.
                                                  0
                                                  интересно что делает разработчик когда нужно сменить пароль к бд
                                                    0
                                                    судя по тому как сделано приложение, он его вряд ли поменяет

                                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                  Самое читаемое