Гайд Нормальный клиент с привязкой по железу на питоне

Пользователь
Пользователь
Статус
Оффлайн
Регистрация
21 Апр 2017
Сообщения
74
Реакции
32
Увидев одну из тем, я понял что этот мир уже не спасти от наплывающих питонистов, поэтому решил показать как надо делать.

Так как у нас будет нормальный код и шифрование данных, мы будем использовать алгоритм RSA.
Нам нужно будет сгенерировать 2 пары, одна для сервер-клиент, вторая для клиент-сервер.
Вместо 1024 можно указать любой размер, чем больше, тем дольше будет работать генерация и алгоритм.
Python:
Expand Collapse Copy
pubkey, privkey = rsa.newkeys(1024)  # генерируем пару ключей
pickle.dump(privkey, open('key.key', 'wb+'))  # сохраняем ключ в файл
Теперь напишем клиент
Python:
Expand Collapse Copy
import requests
import datetime
import hashlib
import pickle
import uuid
import json
import rsa


def get_hwid() -> str:
    hwid = str(uuid.uuid1(uuid.getnode(), 0))[24:]

    hwid_hash = hashlib.sha256(hwid.encode('utf-8'))

    return hwid_hash.hexdigest()


def post(url: str, data: dict) -> dict:
    client_public_key = pickle.load(open('client_public.key', 'rb'))
    server_private_key = pickle.load(open('server_private.key', 'rb'))

    encoded = rsa.encrypt(json.dumps(data).encode('utf-8'), client_public_key).hex()
    data = {'data': encoded}

    response = requests.post(url, data=data)

    data = response.json()['data']
    decoded = rsa.decrypt(bytes.fromhex(data), server_private_key).decode('utf-8')

    return json.loads(decoded)


def get_license(hwid: str) -> bool:
    data = post('http://localhost:5000/get_license', {'hwid': hwid})
    lic = data['license']

    return datetime.datetime.fromtimestamp(lic) > datetime.datetime.now()


hwid = get_hwid()
lic = get_license(hwid)
А тут будет код сервера, я буду использовать sqlite3 для простоты, кому надо будет перепишет на норм субд
Python:
Expand Collapse Copy
from flask import Flask, request
import datetime
import sqlite3
import pickle
import json
import rsa

client_private_key = pickle.load(open('client_private.key', 'rb'))
server_public_key = pickle.load(open('server_public.key', 'rb'))


class Database:
    def __init__(self, db_name: str):
        self.db_name = db_name

        self.initialize()

    def initialize(self):
        connection = self.get_connection()
        cursor = connection.cursor()

        cursor.execute('CREATE TABLE IF NOT EXISTS users('
                       'id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,'
                       'hwid VARCHAR(64),'
                       'license REAL)')
        connection.commit()

        cursor.close()
        connection.close()

    def get_connection(self):
        return sqlite3.connect(self.db_name)

    def get_license(self, hwid: str) -> datetime.datetime:
        connection = self.get_connection()
        cursor = connection.cursor()

        cursor.execute(f"SELECT license FROM users WHERE hwid='{hwid}'")

        (result,) = cursor.fetchone()

        cursor.close()
        connection.close()

        return datetime.datetime.fromtimestamp(result)

    def update_license(self, hwid: str, date: datetime.datetime) -> None:
        connection = self.get_connection()
        cursor = connection.cursor()

        cursor.execute(f"UPDATE users SET license={date.timestamp()} WHERE hwid='{hwid}'")
        connection.commit()

        cursor.close()
        connection.close()

    def set_license(self, hwid: str, date: datetime.datetime) -> None:
        connection = self.get_connection()
        cursor = connection.cursor()

        cursor.execute(f"INSERT INTO users (hwid, license) VALUES ('{hwid}', {date.timestamp()}")
        connection.commit()

        cursor.close()
        connection.close()


db = Database('database.db')
app = Flask(__name__)


@app.route('/get_license', methods=['POST'])
def get_license():
    if request.method == 'POST':
        data = request.form['data']
        data = json.loads(rsa.decrypt(bytes.fromhex(data), client_private_key))

        hwid = data['hwid']
        lic = db.get_license(hwid).timestamp()

        response = rsa.encrypt(json.dumps({'license': lic}).encode('utf-8'), server_public_key).hex()

        return {'data': response}
    return '404'


app.run()

Код есть, но мамкины крякеры, никуда еще не делись, поэтому нам нужно будет защитить код клиента. Мы будем использовать для этого PyArmor, у него есть лишь один недостаток, для защиты большого проекта нужно купить лицензию, но нам сейчас хватит и бесплатной версии.
  • Устанавливаем pyarmor
  • Открываем терминал и переходим в папку нашего клиента
  • Пишем pyarmor pack -e " --onefile" client.py
  • Ждем пока закончится магия
  • В папке dist будет лежать exe файл нашего клиента

Для особо внимательных, кто заметил что наш клиент переродился в исполняемом файле: pyarmor использует pyinstaller для упаковки питонячего кода, но даже если супер-крякер777 доберется до распакованной временной папки нашего клиента и декомпилировав pyc файл, открыв исходник он, к его сожалению, увидит лишь это:
Python:
Expand Collapse Copy
from pytransform import pyarmor_runtime
pyarmor_runtime()
__pyarmor__(__name__, __file__, b'\x50\x59\x41\x52\x4d\x4f...', 2)

Что в итоге мы сделали?
  • Написали более менее человеческий код
  • Защитили исходник
  • Использовали СУБД!!!!
  • Написали сервер (wow)
 
Чел, это не говно код, удаляй тему !!! :roflanEbalo:
У нас, питонистов, только код какашка
 
  • Мне нравится
Реакции: hkon
а нуда,это же пайтон.Защитили... угу
Да, защитили. Если сомневаешься, можешь почитать доки\глянуть исходный код PyArmor и изучить принцип его работы\попробовать взломать его защиту. Иначе, твой комментарий не несет никакой смысловой нагрузки.
 
Да, защитили. Если сомневаешься, можешь почитать доки\глянуть исходный код PyArmor и изучить принцип его работы\попробовать взломать его защиту. Иначе, твой комментарий не несет никакой смысловой нагрузки.
забей, он всё ещё думает, что питон можно декомпилировать
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Вот это - server_private_key = pickle.load(open('server_private.key', 'rb')) убивает весь смысл шифровки.
 
Гайд вышел достаточно полезный, но есть пара моментов в коде, которые необходимо изменить. Начнем с того, что использование RSA шифрования в программе просто бесполезно. Взломщику достаточно подменить ответ сервера на данные уже авторизированного пользователя, не занимаясь расшифровкой. Это легко решается введением дополнительных проверок, например, по никнейму или времени ответа сервера.
Также хорошим решением стало бы использование сокетного соединения, вместо простых POST запросов. Это позволит скрыть трафик и значительно усложнить процесс подмены ответов.

Важные поправки для совсем новичков в Python:
1. Перед запуском вашего клиента и сервера необходимо установить все используемые модули с помощью pip. Пропишите pip install -r requirements.txt (файл приложен к сообщению).
2. Код файла с генерацией ключей RSA необходимо заменить на:
Python:
Expand Collapse Copy
import rsa
import pickle
pubkey, privkey = rsa.newkeys(1024)  # генерируем пару ключей
pickle.dump(privkey, open('client_private.key', 'wb+'))  # сохраняем ключ в файл
pickle.dump(pubkey, open('server_publickey', 'wb+'))  # сохраняем ключ в файл
3. Для работы упаковщика файлов при использовании PyArmor необходимо установить PyInstaller с помощью pip.

Хоть и не существует публичных деобфускаторов PyArmor, я все равно не рекомендую писать серьезные проекты на Python. Посмотрите в сторону C++, если нет желания или возможности проводить все важные проверки и операции на сервере.
 

Вложения

Гайд вышел достаточно полезный, но есть пара моментов в коде, которые необходимо изменить. Начнем с того, что использование RSA шифрования в программе просто бесполезно. Взломщику достаточно подменить ответ сервера на данные уже авторизированного пользователя, не занимаясь расшифровкой. Это легко решается введением дополнительных проверок, например, по никнейму или времени ответа сервера.
Также хорошим решением стало бы использование сокетного соединения, вместо простых POST запросов. Это позволит скрыть трафик и значительно усложнить процесс подмены ответов.

Важные поправки для совсем новичков в Python:
1. Перед запуском вашего клиента и сервера необходимо установить все используемые модули с помощью pip. Пропишите pip install -r requirements.txt (файл приложен к сообщению).
2. Код файла с генерацией ключей RSA необходимо заменить на:
Python:
Expand Collapse Copy
import rsa
import pickle
pubkey, privkey = rsa.newkeys(1024)  # генерируем пару ключей
pickle.dump(privkey, open('client_private.key', 'wb+'))  # сохраняем ключ в файл
pickle.dump(pubkey, open('server_publickey', 'wb+'))  # сохраняем ключ в файл
3. Для работы упаковщика файлов при использовании PyArmor необходимо установить PyInstaller с помощью pip.

Хоть и не существует публичных деобфускаторов PyArmor, я все равно не рекомендую писать серьезные проекты на Python. Посмотрите в сторону C++, если нет желания или возможности проводить все важные проверки и операции на сервере.
Полностью согласен с твоим постом, но гайд родился в голове после того как я заметил предыдущую подобную тему и лишь захотелось показать что можно более грамотно подойти к этой задаче. Код, конечно, не претендует на звание лучшего, но это всяко лучше того, что я видел до этого. Имхо, питон не предназначен для написания серьезного клиента, как ты сказал, для таких целей лучше использовать более низкоуровневые япы, а содержание моей темы я больше отношу к стебу. И в дополнение к твоему ответу хочу заметить что данные недостаточно подменить тк мы создаем уникальные пары ключей для расшифровки и твой код для генерации ключей неполный, всего их 4: приватный и публичный для клиента и сервера, соответственно.
Вот это - server_private_key = pickle.load(open('server_private.key', 'rb')) убивает весь смысл шифровки.
Верно заметил, но если более грамотно хранить ключи и немного усложнить алгоритм шифрования/расшифрованмя то смысл не умрет пока pyarmor остается неприступным для тех, кто крякает софты после уроков.
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Так приватный ключ можно вообще в программе не хранить, зачем ???
 
спс вроде норм, научился
 
это мак адрес как бы, а не хвид
Хвид - это индефикация компьютера, не имеет смысла каким алгоритмом. Хотя использовать его не стоит, банальный сброс сети - изменение его комбинаций.
@CzarAlex getnode(), то бишь Mac адрес можно поделать через реестр ?
 
Последнее редактирование:
Спасибо норм
 
а нуда,это же пайтон.Защитили... угу
Похоже что после того как ты декомпилировал скрипт на питоне, не одного сообщение от тебя не воспринимается в серьёз
 
Похоже что после того как ты декомпилировал скрипт на питоне, не одного сообщение от тебя не воспринимается в серьёз
Я не понимаю что за бред ты щас сказал.Походу ты вообще не понимаешь что питон язык легко декомириуемый и даже модераторы это доказывали.Твой pyarmor будет сломан легче чем кряк ксяоми.Мне жалко детей которым втерели дичь что теперь питон также защищён как и языки C
 
Я не понимаю что за бред ты щас сказал.Походу ты вообще не понимаешь что питон язык легко декомириуемый и даже модераторы это доказывали.Твой pyarmor будет сломан легче чем кряк ксяоми.Мне жалко детей которым втерели дичь что теперь питон также защищён как и языки C
новые версий питона на которых нет декомпиляторов так не думают
 
новые версий питона на которых нет декомпиляторов так не думают
Не обязательно же декомпилировать все .pyc файлы. И без этого их можно достаточно легко пропатчить.
 
новые версий питона на которых нет декомпиляторов так не думают
а ты думаешь будут декомпилировать одной кнопкой?
Это дело времени чел.Все это можно обойти в томже IDA и даже в Ollydbg и вырезать говяную защиту.
Об"ясняю работу питона
1624877336548.png

И на этапе интерпритатора подключаеться С,почему? Потому-что язык зделан на С.Питон високо-уровненвый язык и крякнуть его не так уж и сложно.
Когда твоё ПО кряшнеться питон даст полный отчёт почему,и считай тут будет встроенный дебагер.
Моё мнение что язык сделан для быстрого создания макета и повтора его потом на С.Даже большинство либ сделаны на С для скорости обработки.У языка уже прошло время хайпа
@hkon был слит по фактам и обиженый
 
  • Раздражает
Реакции: hkon
Я не понимаю что за бред ты щас сказал.Походу ты вообще не понимаешь что питон язык легко декомириуемый и даже модераторы это доказывали.Твой pyarmor будет сломан легче чем кряк ксяоми.Мне жалко детей которым втерели дичь что теперь питон также защищён как и языки C
Ты заебал меня конкретно.
Если питон так лего реверснуть, вот тебе
Пожалуйста, авторизуйтесь для просмотра ссылки.
, давай исходники exe, там всего 2 уровня защиты, любое твое "мне что, делать нечего?!" будет воспринято как слив.
И после этого можешь по теме питона вообще свой пиздак не открывать.
 
Назад
Сверху Снизу