Нажмите ESC, чтобы закрыть

Фейковый майннет GIWA: технический разбор атаки и кражи 766 ETH

Разбор изощренной мошеннической схемы с поддельным мейннетом GIWA, в результате которой 27.09.2026 пользователи потеряли 766 ETH, а децентрализованная биржа DYORSWAP подверглась атаке из-за интеграции фейкового RPC. 

Изощренный обман: как подделывают блокчейн

Листаю ленту мониторинга безопасности и ... чуть чашку не выронил. Семьсот шестьдесят шесть эфиров. Просто в никуда. И ладно бы классический фишинг через поддельную либу или взлом контракта с флэш-лоунами — этого я навидался. Но тут схема куда изящнее. Мошенники подняли фальшивый майннет GIWA, прикрутили к нему чужой DEX и выпотрошили пользователей на пару миллионов долларов.

Давайте разберем этот инцидент детально, потому что архитектурно здесь есть на что посмотреть инженерным взглядом. Как специалист по ИБ и действующий CTO, я прямо-таки восхищаюсь дерзостью реализации, хотя ребятам из DYORSWAP, конечно, не позавидуешь.

Погодите, а как вообще можно "подделать" блокчейн уровня 2? Звучит дико для неподготовленного человека, но в мире EVM, сеть — это не магия, а набор конвенций и RPC-эндпоинтов.

Злоумышленники взяли опенсорсный стек (скорее всего, форкнули что-то вроде OP Stack) и развернули ноду. Но мало поднять сервер, нужно заставить кошельки и приложения верить, что это официальный продукт южнокорейской биржи Upbit, у которой этот самый GIWA еще даже официально не стартовал в мейннете.

Они жестко захардкодили в конфигурацию ноды официальный Chain ID — цифру 9134, которую команда GIWA заблаговременно зарегистрировала для своего будущего блокчейна. И вот тут кроется главная уязвимость всей экосистемы: кошельки вроде MetaMask проверяют сеть по строчкам конфигурации и по ID, а не по криптографическим корням доверия к создателям.

И вот тут мы подходим к моменту, где погорел DEX DYORSWAP. Они добавили этот фейковый RPC в свою инфраструктуру, решив первыми запрыгнуть на хайп новой сети.

Знаете, когда я сам еще гонял аудиты смарт-контрактов на коленке, мы всегда думали: ну окей, фронтенд могут подделать, RPC могут подменить, но смарт-контракт моста — это святое, там же код в блокчейне Ethereum! И вот тут кроется самая изящная ловушка этой атаки.

Почему пользователи не подозревали подвоха?

Пользователи не подозревали подвоха, потому что мост выглядел как родной интерфейс для перевода средств из Ethereum в L2-сеть GIWA. Люди подписывали транзакции в MetaMask, отправляя свои кровные ETH на депозитный смарт-контракт в мейннете.

Технически этот контракт был написан злоумышленниками так, чтобы имитировать работу стандартного локатора депозитов. Как только транзакция проходила валидацию в главной сети, мошенники получали контроль над средствами. А взамен пользователь получал фальшивые, ничем не подкрепленные фантики на баланс поддельного L2. Цифры на экране росли, создавая иллюзию успешного бриджа, а реальный эфир уже улетал на адреса организаторов схемы, испаряясь через миксеры. В итоге пострадали 1 335 уникальных адресов, оставив в капкане около 767.7 ETH. Причем вывели чисто около 766.3 ETH, сработав с минимальными издержками на газ.

Команда DYORSWAP поступила круто, выделив больше 200 ETH из своего кармана на компенсации. Уважаю такой подход к репутации, хотя архитектурную дыру в валидации внешних RPC-подключений придется заделывать кровь из носу.

А теперь давайте перейдем к практической части. Как не стать спонсором очередных аферистов, если вы любите первыми тестировать новые блокчейны? Набросал для вас скрипт-проверку на Python для верификации RPC-нод перед тем, как вообще думать о взаимодействии с ними через кошелек.

#!/usr/bin/env python3

import requests


def rpc_call(rpc_url, method, params=None):
    if params is None:
        params = []

    payload = {
        "jsonrpc": "2.0",
        "method": method,
        "params": params,
        "id": 1
    }

    response = requests.post(rpc_url, json=payload, timeout=10)
    response.raise_for_status()

    data = response.json()

    if "error" in data:
        raise RuntimeError(f"{method}: {data['error']}")

    return data.get("result")


def verify_evm_node(rpc_url, expected_chain_id):
    try:
        chain_id_hex = rpc_call(rpc_url, "eth_chainId")
        chain_id = int(chain_id_hex, 16)

        net_version = rpc_call(rpc_url, "net_version")
        client_version = rpc_call(rpc_url, "web3_clientVersion")

        block_number_hex = rpc_call(rpc_url, "eth_blockNumber")
        block_number = int(block_number_hex, 16)

        latest_block = rpc_call(
            rpc_url,
            "eth_getBlockByNumber",
            ["latest", False]
        )

        print("=" * 60)
        print(f"RPC URL          : {rpc_url}")
        print(f"Chain ID         : {chain_id}")
        print(f"Expected ChainID : {expected_chain_id}")
        print(f"Net Version      : {net_version}")
        print(f"Client Version   : {client_version}")
        print(f"Block Number     : {block_number}")

        if latest_block:
            print(f"Latest Block Hash: {latest_block.get('hash')}")
            print(f"Latest Block Num : {int(latest_block['number'], 16)}")
            print(f"Parent Hash      : {latest_block.get('parentHash')}")
            print(f"Timestamp        : {int(latest_block['timestamp'], 16)}")

        print("=" * 60)

        checks = []

        checks.append(chain_id == expected_chain_id)

        try:
            checks.append(int(net_version) == expected_chain_id)
        except Exception:
            checks.append(False)

        checks.append(block_number > 0)

        checks.append(
            latest_block is not None
            and latest_block.get("hash")
            and latest_block.get("parentHash")
            and latest_block.get("number")
        )

        if all(checks):
            print("VERIFICATION PASSED")
            return True

        print("VERIFICATION FAILED")
        return False

    except Exception as e:
        print(f"ERROR: {e}")
        return False


if __name__ == "__main__":
    verify_evm_node(
        "https://your-rpc-endpoint",
        9134
    )

Запомните главное правило: никогда не доверяйте спискам сетей из сомнительных твиттер-аккаунтов или непроверенных DEX, пока официальный проект в своих подтвержденных каналах (не в соцсетях, а в документации или на официальном сайте с SSL-сертификатами) не опубликует точные эндпоинты. Биржа Upbit прямо заявила, что их мейннет еще не запущен, а все текущие RPC — это пальцы в небо и чистый скам.

Сделать краткую выжимку этой статьи с помощью:

FAQ

Мошенники развернули вредоносную ноду Layer 2 на базе EVM с официальным невыпущенным Chain ID 9134 проекта GIWA, подключили фейковый смарт-контракт депозитного моста и обманом заставили владельцев 1 335 кошельков перевести реальный ETH в обмен на обесцененные балансы внутри их системы.

Децентрализованная биржа автоматизировала проверку подлинности сети исключительно по совпадению параметра Chain ID 9134, проигнорировав валидацию криптографического корня доверия и прямые анонсы команды биржи Upbit.

Разработчикам и пользователям необходимо перекрестно запрашивать параметры сети нативными методами вроде net_version, сверять непрерывность заголовков блоков через eth_getBlockByNumber и доверять только криптографически верифицированным источникам документации.
Oleg Filatov

As the Chief Technology Officer at EXMON Exchange, I focus on building secure, scalable crypto infrastructure and developing systems that protect user assets and privacy.

With over 15 years in cybersecurity, blockchain, and DevOps, I specialize in smart contract analysis, threat modeling, and secure system architecture.

At EXMON Academy, I share practical insights from real-world...

...

Поделитесь своим мнением

Ваш e-mail не будет опубликован. Обязательные поля отмечены *