devqp
Специалист
При обработке транзакций Ethereum некоторые платежные шлюзы уязвимы к эксплуатации через механизм мульти-отправок смарт-контрактов. Рассмотрим реальный кейс:
Описание инцидента:
На аукционной площадке пользователь внес депозит в $2 ETH, но получил кредит $11.3k. Причина: транзакция содержала один вход и три выхода:
- $300 на адрес X
- $2 на адрес площадки
- $11000 на адрес Y
API шлюза ошибочно интерпретировало общую сумму транзакции (total) как сумму депозита, хотя на адрес площадки поступило лишь $2.
Техническая уязвимость:
Хотя Ethereum нативно не поддерживает транзакции с несколькими выходами, смарт-контракты реализуют эту функциональность. Пример контракта для мульти-отправки:
Вектор атаки:
Для эксплуатации уязвимого шлюза:
1. Отправьте $1000 на адрес MultiSend-контракта
2. Контракт распределит средства в одной транзакции:
- $999 на ваш адрес возврата
- $1 на адрес платежного шлюза
3. Система шлюза, анализирующая только общую сумму транзакции ($1000), зачислит $1000, хотя фактически получен $1.
Важно: Уязвимость актуальна только для шлюзов, которые:
- Не проверяют происхождение транзакций (смарт-контракты)
- Используют общую сумму транзакции (total) вместо конкретного выхода
По оценкам, 90% современных шлюзов защищены от данной атаки.
Описание инцидента:
На аукционной площадке пользователь внес депозит в $2 ETH, но получил кредит $11.3k. Причина: транзакция содержала один вход и три выхода:
- $300 на адрес X
- $2 на адрес площадки
- $11000 на адрес Y
API шлюза ошибочно интерпретировало общую сумму транзакции (total) как сумму депозита, хотя на адрес площадки поступило лишь $2.
Техническая уязвимость:
Хотя Ethereum нативно не поддерживает транзакции с несколькими выходами, смарт-контракты реализуют эту функциональность. Пример контракта для мульти-отправки:
Код:
pragma solidity ^0.8.0;
contract MultiSend {
function multiSend(address[] memory recipients, uint256[] memory amounts) public payable {
require(recipients.length == amounts.length, "Arrays length mismatch");
for (uint256 i = 0; i < recipients.length; i++) {
payable(recipients[i]).transfer(amounts[i]);
}
}
receive() external payable {}
}
Вектор атаки:
Для эксплуатации уязвимого шлюза:
1. Отправьте $1000 на адрес MultiSend-контракта
2. Контракт распределит средства в одной транзакции:
- $999 на ваш адрес возврата
- $1 на адрес платежного шлюза
3. Система шлюза, анализирующая только общую сумму транзакции ($1000), зачислит $1000, хотя фактически получен $1.
Важно: Уязвимость актуальна только для шлюзов, которые:
- Не проверяют происхождение транзакций (смарт-контракты)
- Используют общую сумму транзакции (total) вместо конкретного выхода
По оценкам, 90% современных шлюзов защищены от данной атаки.