Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Dismiss Notice
  2. Данный раздел создан исключительно для релизов! Вопросы по лаунчеру или обвязке задавайте ТОЛЬКО в соответсвующей теме автора. Любые другие темы будут удалены, а авторы понесут наказание.

Фикс Защита лаунчера [Переменная сессия]

Discussion in 'Веб-обвязки и лаунчеры' started by Dj Arktic, Feb 27, 2013.

  1. Автор темы
    Dj Arktic

    Dj Arktic Активный участник Пользователь

    Trophy Points:
    93
    Skype:
    dj_arktic
    Имя в Minecraft:
    Dj_Arktic
    Ни для кого не секрет, что предприимчивые пользователи давно поняли, что лаунчер на самом деле не защищает сервер от читов.
    Например:
    Что же, давайте усложним им их читерскую жизнь.
    В этой теме я выложу идею своей защиты. Она не идеальна, но для ее взлома понадобится написать мод для клиента как минимум.

    Нам понадобится:
    • Minecraft Coder Pack
    • Исходники любого лаунчера
    • Прямые руки
    • Базовые знания Java, PHP
    Небольшое отступление, объясняющее алгоритм авторизации.
    Для подключения к серверу с online-mode: true клиенту игры необходимо знать ник и сессию.
    Сессия - наш ключик, который нужно защитить от злобного WireShark (программы для просмотра траффика).
    Авторизация проходит следующим образом:
    1) лаунчер запрашивает сессию у loginserver.php (палит сессию для WireShark'a)
    2) лаунчер передает клиенту игры сессию
    3) при подключении к серверу клиент передает сессию на joinserver.php (палит сессию для WireShark'a), для того, чтобы joinserver установил нужный serverid и checkserver завершил авторизацию.
    Как мы видим, у нас аж две уязвимости. Давайте их фиксить.
    Т.к. loginserver палит нашу драгоценную сессию, нужно, чтобы он передавал лаунчеру не сессию, а ключ для получения этой самой сессии.

    Фикс первой дырки
    Идея проста:
    loginserver генерирует сессию, отдает ее клиенту, а в базу заносит md5($сессия.$key).
    Для loginserver.php:
    Заменяем строки
    Code:
    $sessid = generateSessionId();
    mysql_select_db($db_database,$connectmysql);
    mysql_query("UPDATE $db_table SET $db_columnSesId='$sessid' WHERE $db_columnUser = '$login'");
    На
    Code:
    $sessid = generateSessionId();
    $fsessid = md5($sessid."ваш_ключ");
    mysql_select_db($db_database,$connectmysql);
    mysql_query("UPDATE $db_table SET $db_columnSesId='$fsessid' WHERE $db_columnUser = '$login'");
    Далее, дело за лаунчером. Лаунчер получает сессию, а клиенту игры передает md5(сессия+ключ)
    В исходниках лаунчера, в LauncherFrame.java в конец добавляем:
    Code:
    public static String getHash(String str){
        MessageDigest m;
        try {
            m = MessageDigest.getInstance("MD5");
            m.reset();
            try {
                m.update(str.getBytes("utf-8"));
                String s2 = new BigInteger(1,m.digest()).toString(16);
                while(s2.length() < 32 ){
                    s2 = "0"+s2;
                }
                return s2;
            } catch (UnsupportedEncodingException e) {
            }
        } catch (NoSuchAlgorithmException e) {
        }
        return "";
    }
    Далее в этом же классе находим строку
    Code:
    launcher.customParameters.put("sessionId", values[3].trim());
    И заменяем ее на
    Code:
    launcher.customParameters.put("sessionId", getHash(values[3].trim()+"ваш_ключ"));
    Компилируем лаунчер, проверяем.
    Отлично, первая дырка залатана!
    Для того, чтобы запутать читера этого достаточно. Но юзер, имеющий мозги сразу поймет, что сессия, передающаяся loginserver'ом - невалидная, а joinserver передает валидную сессию.

    Фикс второй дырки
    Это сложнее, потребуется умение обращаться с MCP. Этому я учить не буду, гугл научит.
    Вы установили MCP, декомпилировали чистый клиент.
    Или же вы декомпилировали клиент в связке с Forge.
    Я буду приводить куски кода для второго случая, однако, и без Forge суть та же.
    Идея фикса:
    joinserver, при получении сессии, авторизует пользователя, однако, делает сессию невалидной, меняя ее на md5($сессия.$key);
    Клиент, после успешного запроса к joinserver обновляет свою сессию, чтобы она оставалась валидной, на md5(сессия+ключ);
    Для joinserver.php:
    Перед каждым
    Code:
    echo "ok";
    Добавляем
    Code:
    $fsessid = md5($sessionid."ваш_ключ");
    mysql_query("UPDATE $db_table SET $db_columnSesId='$fsessid' WHERE $db_columnUser = '$user'");
    Теперь клиент должен поддерживать валидность сессии:
    Отрываем эклипс с рабочим каталогом MCP
    Идем в net.minecraft.client.multiplayer.NetClientHandler
    И в конец добавляем
    Code:
      private void func198i (){
            String x0 = this.mc.session.sessionId;
            x0 = getHash(x0+"ваш_ключ");
            this.mc.session.sessionId = x0;
        }
     
        public static String getHash(String str){
            MessageDigest m;
            try {
                m = MessageDigest.getInstance("MD5");
                m.reset();
                try {
                    m.update(str.getBytes("utf-8"));
                    String s2 = new BigInteger(1,m.digest()).toString(16);
                    while(s2.length() < 32 ){
                        s2 = "0"+s2;
                    }
                    return s2;
                } catch (UnsupportedEncodingException e) {
                    return e.toString();
                }
            } catch (NoSuchAlgorithmException e) {
                return e.toString();
            }
        }
    Теперь находим строчку
    Code:
    URL var4 = new URL("http://session.minecraft.net/game/joinserver.jsp?user=" + urlEncode(par1Str) + "&sessionId=" + urlEncode(par2Str) + "&serverId=" + urlEncode(par3Str));
    И под ней добавляем
    Code:
    func198i();
    Сохраняем.
    Запускаем recompile.bat
    Затем reobf.bat
    идем в %MCP%/reobf/Minecraft
    Забираем класс, лежащий в ней (на версии 1.4.7 это ayh.class)
    С помощью InClassTranslator меняем в новом классе путь до joinserver
    Заливаем класс в ваш minecraft.jar
    Готово!
    Что имеем теперь:
    Перед WireShark loginserver палит невалидную сессию.
    joinserver палит валидную сессию, но после выполнения запроса она становится невалидной.
    ВАЖНО!!!
    Защита не идеальна, программист сможет ее обойти. Но ему придется потрудиться написать мод, и для каждого сервера нужно будет делать индивидуальный обход.
    Можно усложнить ему работу шифрованием классов лаунчера в jar2exe и антидеобфускаторскими штучками для minecraft.jar.
    Спасибо за внимание.
    Для серверов с Forge и на версии 1.4.7 выложу готовый ayh.class, замените ключ с помощью InClassTranslator (строка your_key).
     

    Attached Files:

    • ayh.zip
      File size:
      17.9 KB
      Views:
      289
    matvei7733, Evan, Yuri123456 and 52 others like this.
  2. Хостинг MineCraft
    <
  3. Автор темы
    Dj Arktic

    Dj Arktic Активный участник Пользователь

    Trophy Points:
    93
    Skype:
    dj_arktic
    Имя в Minecraft:
    Dj_Arktic
    Жду отзывы и критику :)
     
    Jack11398 and Alastar like this.
  4. Kseon73

    Kseon73 Старожил Пользователь

    Trophy Points:
    123
    В качестве ключа можно любое словочетание цифр и букв использовать?
     
    MrPon4ik likes this.
  5. Автор темы
    Dj Arktic

    Dj Arktic Активный участник Пользователь

    Trophy Points:
    93
    Skype:
    dj_arktic
    Имя в Minecraft:
    Dj_Arktic
    Да.
    В скриптах место для вставки ключа я указывал как "ваш_ключ".
    В ayh.class, выложенным мной, строка ключа "your_key"
     
  6. Qwixx

    Qwixx Активный участник

    Trophy Points:
    63
    Стиллер...
     
  7. Crazy_Flying_Monkey

    Crazy_Flying_Monkey Активный участник Пользователь

    Trophy Points:
    78
    Имя в Minecraft:
    Monkey
    Не идеально , но впечатляет. Наконец-то что-то стоящее.
     
    slavik123123123 and Romanz like this.
  8. Автор темы
    Dj Arktic

    Dj Arktic Активный участник Пользователь

    Trophy Points:
    93
    Skype:
    dj_arktic
    Имя в Minecraft:
    Dj_Arktic
    Подбрось идею для улучшения :)
    Скоро скину улучшение защиты с помощью ssl, это еще более осложнит задачу читерам.
    Так же выложу "антидеобфускаторские штучки".
     
  9. Crazy_Flying_Monkey

    Crazy_Flying_Monkey Активный участник Пользователь

    Trophy Points:
    78
    Имя в Minecraft:
    Monkey
    Гг, пиши свой лаунчер
     
  10. Автор темы
    Dj Arktic

    Dj Arktic Активный участник Пользователь

    Trophy Points:
    93
    Skype:
    dj_arktic
    Имя в Minecraft:
    Dj_Arktic
    у всех лаунчеров основные процедуры в LauncherFrame идентичны.
    Читайте и выполняйте пошагово.
     
  11. Автор темы
    Dj Arktic

    Dj Arktic Активный участник Пользователь

    Trophy Points:
    93
    Skype:
    dj_arktic
    Имя в Minecraft:
    Dj_Arktic
    Есть. В любом лаунчере. Тема для более менее разбирающихся.
    Пожалуйста, не флуди в ней.
     
  12. Serrrgio

    Serrrgio Старожил Пользователь

    Trophy Points:
    173
    Skype:
    nonecsa
    Имя в Minecraft:
    None
    а сертификаты тоже будешь выдавать?
     
  13. Автор темы
    Dj Arktic

    Dj Arktic Активный участник Пользователь

    Trophy Points:
    93
    Skype:
    dj_arktic
    Имя в Minecraft:
    Dj_Arktic
    Ну, я могу позволить себе ssl.
    Уверен, некоторые пользователи тоже.
    http://www.startssl.com/
    тут бесплатные.
     
  14. Автор темы
    Dj Arktic

    Dj Arktic Активный участник Пользователь

    Trophy Points:
    93
    Skype:
    dj_arktic
    Имя в Minecraft:
    Dj_Arktic
    UPD:
    Созрела идея для создания максимально прочной защиты.
    Проблема текущей защиты в том, что при умелой декомпиляции можно ее обойти.
    Если скинуть все критические функции в dll, прогнать ее через upx и таскать с лаунчером (а лучше выкачивать вместе с client.zip) можно получить достойную защиту, которую обойти будет практически не реально.
    Как только сделаю - залью исходники dll и код, необходимый для ее подключения.
     
  15. Феня

    Феня Старожил Пользователь

    Trophy Points:
    123
    Skype:
    vasilev_max
    Имя в Minecraft:
    eblan_tupoj
    ХЕХ. Ну вот и мою защиту ПОЧТИ вскрыли ^^ Додумались!
     
  16. mr.cloud

    mr.cloud Активный участник

    Trophy Points:
    88
    идея хорошая.
    у меня есть одна идея, по защите, позже в лс черкану
     
  17. qwertyqwerty

    qwertyqwerty Старожил Пользователь

    Trophy Points:
    103
    Помоему все параметры можно будет провалить в консольке ява. И ключ и сессию.
     
  18. qwertyYy2

    qwertyYy2 Старожил

    Trophy Points:
    103
    cкиньте пожалуйста под modloader
     
  19. Автор темы
    Dj Arktic

    Dj Arktic Активный участник Пользователь

    Trophy Points:
    93
    Skype:
    dj_arktic
    Имя в Minecraft:
    Dj_Arktic
    не можно. Попробуй :)
    Но единственный способ здесь - декомпиляция.
     
    Сникерсни and PiPmIg like this.
  20. qwertyYy2

    qwertyYy2 Старожил

    Trophy Points:
    103
    прошу под modloader 1.4.7 скинуть.
     
  21. Автор темы
    Dj Arktic

    Dj Arktic Активный участник Пользователь

    Trophy Points:
    93
    Skype:
    dj_arktic
    Имя в Minecraft:
    Dj_Arktic
    Сделай сам. :)
    Алгоритм получения класса на чистый клиент и на модлоадер написан в разделе "Фикс второй дырки".
     

Share This Page