Solidity. Смарт контракты и аудит – Telegram
Solidity. Смарт контракты и аудит
2.62K subscribers
246 photos
7 videos
18 files
547 links
Обучение Solidity. Уроки, аудит, разбор кода и популярных сервисов
Download Telegram
Офигенная задача от Immunefi

Позавчера в Твиттере выложили задачу, которая заставила меня немного врасплох.

Посмотрите на скрин выше внимательно. Решение тут будет открыто изначально, так как пост скорее обучающий, а не для тренировки навыков.

На строчке owner.call{} я сразу понял, что может случиться gas griefing атака (если не в курсе, что это, то поищите посты по тегу), и побежал в комменты писать свой ответ.

И все бы ничего, если бы не два твита, которые поставили меня в некое замешательство. Вот первый и второй.

Они оба указывали на некую особенность исполнения контракта ERC721Enumerable от OpenZeppelin, о которой я слышал впервые. И мне захотелось поглубже копнуть, чтобы понять, о чем идет речь.

Для начала посмотрите вот это видео, объясняющее работу этого контракта.

Обратите особое внимание на то, как преобразуется массив во время transfer токена от одного пользователя другому.

Если потребуется, то напишу еще один пост про это, но, вроде как, на видео все предельно просто и понятно.

И вот, из-за особенностей формирования массива при изменении владельцев токена, в данной задаче один пользователь может дважды получить награду, а другой, тот чей индекс будет подвинут, вообще ничего не получит.

Надеюсь, вы сможете разобраться в этом.

Люблю задачи, в которых знание нюансов кода и логики может сыграть значительную роль!

#security #erc721 #enumerable #task #erc721enumerable
👍6
Тонкости с прокси переменными

Зацените еще одну классную задачу от Immunefi.

P.S. Эти ребята проводят свои bug bounty программы и аудиты контрактов, и умеют подмечать некоторые нюансы и уязвимости, которые сложно придумать просто так для задач или ctf. Обожаю их!

С первого взгляда все ок. Импортированные контракты от надежной компании, мало кода, и все выглядит хорошо. Опять же, если не знать "внутреннюю кухню".

Вы можете сами остановиться на этом моменте и взглянуть на скрин внимательно.

В общем, ошибка тут кроется в конфликте переменных в памяти. Да, ранее в постах я уже писал об этом баге, но в такой реализации встречаю впервые.

Какая же тут ошибка? Тут только одна переменная _IMPLEMENTATION_SLOT, в чем же тут конфликт?

А проблема в том, что контракт Implementation наследует от Ownable, а уже там, в первом слоте памяти, хранится другая переменная _owner.

Таким образом переменная в прокси будет перезаписываться при инициализации контракта Implementation.

Но тут есть еще один момент. Если мы обозначим _IMPLEMENTATION_SLOT как constant или immutable, то конфликта в памяти не возникнет.

Все потому, что constant и immutable не занимают слоты в памяти контракта. Если я правильно понял, то они зашиваются прямо в байткод контракта (constant - сразу, immutable - в момент работы конструктора).

Теперь мы начнем обращать внимание и на такие детали в контрактах. А казалось, про переменные я знаю все.

#proxy #security
Книга аудитора смарт контрактов

В последнюю неделю в чатах, группах и твиттере гуляла ссылка на файл, где собраны аудиты с разных проектов для bug bounties. Вот версия в pdf.

Очень большая! Более 3900 страниц.

Ну, и ссылка на проект для интересующихся.

#pdf #audit #book
👍1
Возможные скамы с токенами ERC20

Понравилась небольшая статья от Quill Audits, где они приводят примеры скамов с токенами (криптовалютой). К слову, они же делали подборку скамов с NFT.

Краткий перевод.

1. Установка максимальной комиссии на продажу токенов.
Некоторые мошенники прописывают в контрактах отдельную функцию, которой могут управлять только админы, на установку комиссии на продажу, которая может доходить до 100%. Так, если вы захотите продать токен за 100 $, то и комиссии придется заплатить столько же.

2. Черный список пользователей. После того, как инвесторы или другие покупатели приобретают токены, админ вносит их в черный список, запрещая тем самым какие-либо действия с токеном.

3. Сжигание токенов. Владелец может изменить код в функции burn, что позволит ему сжигать токены пользователя при внешнем вызове. Например, после покупки такого токена, админ сразу сжигает их, чтобы взвинтить цену токена и опустошить пул.

4. Бесконечный минт токенов. Админ минтит токены, чем снижает цену и банкротит пользователей.

5. Токены нельзя продать после покупки. Например, пользователи покупают токены для какой-либо игры, надеясь сделать небольшой профит после. Однако оказывается, что они не могут продать его. Цена токена взлетает, и админ опустошает пул.

6. Вредный код в наследуемом/подключенном контракте. Админы могут прятать вредоносный исполняемый код в стороннем контракте, который подключается к токену, вводя в заблуждение пользователей одноименными функциями. 

Пара советов. Перед покупкой каких-либо токенов стоит заранее посмотреть его контракт и наследования на предмет возможного скама. Это могут подсказать функции, которые доступны только админам (увеличение комиссии, добавление в черный список, запрет на продажу и т.д.). Так или иначе, для начала можно купить крохотную сумму токена и попробовать его продать. Да и вообще, следует внимательнее изучать всю подноготную токенов перед инвестициями.

#security #erc20
👍1
Обход проверки на code size

В некоторых контрактах мы видели, что есть проверка на размер кода в require или условии. Напомню, что предполагается, если code size > 0, то это контракт, если меньше - пользователь.

Даже в одной из задач ранее порой требовалось обойти подобную проверку через конструктор.

Так вот, нашел интересный пример кода "призрачного" контракта, через который можно отправлять запросы в другие контракты, при этом проходя проверку на code size.

Вот этот контракт:

contract Ghost {
  function sendGhostTransaction(bytes calldata payload) public returns (bool) {
    assembly {
      calldatacopy(0x80, payload.offset, payload.length)

      let deployedAddress := create(0, 0x80, payload.length)

       if iszero(deployedAddress){
          mstore(0x00, false)
          return(0x00, 0x20)
        }

        mstore(0x00, true)
        return(0x00, 0x20)
    }
  }
}

В calldata подставляете вызов нужной функции в другом контракте.

#ghost #codesize #security
👍1
Что вернет low-level?

Еще одна задача на знание нюансов работы EVM и кода Solidity.

Функция, в целом, написана правильно и будет отрабатываться правильно. Даже слишком правильно.

Дело в том, что она вернет true даже в том случае, если такого контракта нет, или он был уничтожен с selfdestruct.

Поэтому, тут нужно делать дополнительную проверку на существование контракта токена.

Эта задача была также выставлена на Immunefi, а те, в свою очередь, взяли ее из отчета Trail of Bits (15 страница). Но ни там, ни там не упоминается, как сделать эту проверку.

Я поспрашивал в чатах, в которых состою, однако не уверен на 100% в предложенных вариантах проверки существования контракта.

1. Проверка code size контракта;
2. Использование сторонних библиотек, типа openzeppelin и  isContract();
3. Создание whitelist адресов в собственном контракте;

Если вы знаете какие-либо другие проверки, буду рад узнать о них!

#lowlevel #security
Сайт визитка, LinkedIn и польза для общества

В процессе общения на форумах, на собеседованиях, да и просто видел в нескольких видео от блогеров в web3 сфере рекомендации, которые могут помочь устроиться на работу. Все они сводились к нескольким пунктам:

1) Хорошее резюме;
2) Реализованные проекты;
3) Профиль на LinkedIn;
4) Личный сайт - визитка;
5) Общественная деятельность;

Эти пункты не столько повысят ваши шансы быть нанятыми на хорошую работу (ведь все равно будут присылать тестовые задания и изучать ваш опыт), сколько позволят помочь обратить на вас внимание.

Поэтому я хочу сегодня сделать небольшой сайт-визитку и обновить профиль на LinkedIn. Это займет некоторое время и посты на канале может выйдут под вечер, а может уже и завтра.

У меня пока по собеседованиям немного глухо. Были несколько отказов, несколько собеседований и несколько тестовых заданий. Напомню, что я подаюсь в крупные аудиторские компании. И работу начал искать две недели назад.

И с данными рекомендациями я хочу повысить свои шансы на то, чтобы быть замеченным в индустрии.

Поможет это или нет скоро увидим. Держу вас в курсе.
👍5
Поиск уязвимостей. Обучение. Первые итоги. Часть 1

В последнее время мне на глаза попадаются все более и более сложные задачи на поиск уязвимостей в контрактах: в одних нужно знать нюансы исполнения кода, в других иметь практику в конкретной области (типа defi), в третьих приводятся примеры реально найденных багов от топовых аудиторских компаний. В общем, перед тем как "топить" за новый круг своего обучения, хотелось бы подвести некоторые итоги текущего обучения.

Прежде всего скажу, что чем больше я вникаю в аудит и безопасность смарт контрактов, тем меньше мне самому хочется их писать. В самом деле, практически в каждом контракте можно найти пару ошибок. А если вы пишете большой проект, то его обязательно нужно отдавать на проверку, иначе взлом произойдет в самое неподходящее время.

За время своего обучение я прошел и разобрал задачи:

1) Damn Vulnerable Defi
2) Capture The Ether
3) Ethernaut
4) Spot the bug от Immunefi
5) 50+ примеров уязвимостей в defi (и еще прохожу)

Прочитал аудиторских отчетов:

1) 15+ от Code4Arena;
2) 6 от Quill Audits;
3) 10+ от Immunefi
;

А также пересмотрел кучу информации по скамам и последним взломам.

И знаете, как я сам ощущаю свой опыт в деле аудита и поиска уязвимостей?

Я едва достиг среднего уровня. Другими словами, я спокойно увижу явные уязвимости в контракте и с некоторым усердием пойму более сложные баги, но проблему вызовут контракты с логическими связками переводов токенов, сложного расчета их бонусов / комиссии, неявные reentrancy и исключения из правил. И это уже уровень уверенного сеньора.

В паре последующих постов я расскажу, как я просматриваю контракты на уязвимости, и, возможно, вы найдете для себя пару идей для своих аудитов.

Более того, поделюсь, как буду обучаться дальше.

#security #audit
👍2
Поиск уязвимостей. Обучение. Первые итоги. Часть 2

Итак, мы получили задачу или контракт, с чего же начать поиск багов? Опишу, как я это делаю и куда смотрю.

1) Pragma. Как не удивительно, но версия прагмы тоже играет роль. Пару раз я попадался, потому что думал, к примеру, что во всех контрактах последняя его версия и многих багов ранних версий уже нет. Напомню, что до 0.8 в расчетах возможен overflow / underflow.

Смотрим на прагму, в голове держим версию и баги, которые в ней возможны.

2) Импорты. В любом случае идем и проверяем контракты, которые подключаются. Если они от openzeppelin (или другой достойной компании, типа chainlink), то просматривает код, чтобы вспомнить его детали (например, когда и где даются апрувы и т.д.). Если "левые контракты", то в начале изучаем подробно их и ищем баги там. Очень важно разобраться в коде и понимать его "потоки".

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

4. Библиотеки. Пару раз видел самописную библиотеку safeMath, которая по названию очень похожа на openzeppelin. Кажется, что все ок, но там измененные расчеты.

Мы сделали небольшую подготовку и далее начинаем изучать сам контракт.    

#security #audit
👍2
Поиск уязвимостей. Обучение. Первые итоги. Часть 3

Еще раз проверяем наследования и их порядок в контракте.

5. Изучаем переменные, а именно: их порядок, тип данных, константы, видимость. Порядок крайне важен в прокси контракта, так как огромное количество уязвимостей связано с тем, что слоты хранения нарушены в обоих контрактах.

Константы также играют роль в слотах памяти. Их там просто нет.

Тип данных может быть полезен при оптимизации газа.

А через видимость порой можно заметить, что хотят скрыть пароль или другую важную информацию. Этого делать нельзя.

6. Структуры и маппинги. Смотрим, чтобы понимать что-откуда берется ниже в коде.

7. Конструктор. Учитываем, что он исполняет: какие токены подключает, кому дает права owner, создает ли новые контракты и записывает ли что-то в маппинги или массивы. Я не помню какие-либо задачи, где использовались бы уязвимости в конструкторе, однако важно понимать изначальные условия, с которыми придется разбираться дальше.

Далее переходим к функциям.

8. View и pure функции. Реже всего тут встречаются какие-либо ошибки, так как они не могут переводить деньги, минтить токены и делать другие "важные" вещи. При этом нужно обращать внимание на расчеты в этих функциях. Так как они могут использоваться в других функциях.

Вообще я оставляю их всегда на самый последний момент аудита.

Приступаем к самому соку! 

#security #audit
👍3
Поиск уязвимостей. Обучение. Первые итоги. Часть 4

Далее поговорим о функциях и их аудите. Напомню, что, возможно, для топового уровня аудита потребуются дополнительные нюансы, на которые следуют обращать внимание. А эти подойдут для начального и среднего уровня.

После следующей части обучения, скорее всего этот список будет расширен.

P.S. Я предполагаю, что перед прочтением последующих пунктов, вы уже будете знать о наиболее популярных атаках, типа reentrancy или dos.

9. Области видимости функций: public, external или internal. Если область не указана, то по умолчанию это public. Уже были много задач, да и взломов, когда в важной функции забывали указывать видимость, и она могла быть вызвана любым пользователем.

10. Модификаторы. Обращаем внимание: подключаются ли они из внешних контрактов (типа ownable от openzeppelin) или из данного контракта. Смотрим его условия и возможность обхода.

11. Доступы. Да, чаще всего доступы к исполнению функции прописываются в модификаторах, но иногда и в самой функции. Нужно проверить, кто из пользователей может ее вызывать: только админ, только модераторы, только владельцы токена, только другие функции по условиям (типа ДАО) или вообще все пользователи.

12. Require. Внутренние проверки функции. Можно или как-то обойти их?

13. Расчеты. Больная тема всех контрактов. Чаще всего уязвимость скрывается в неправильном определении долей / бонусов / наград, особенно, когда в них используются несколько контрактов.

14. Переводы. Обращаем внимание на функции типа transfer(), send() и другие, которые переводят токены или эфир. Есть ли проверка успешности выполнения? Возможен ли reentrancy? Когда обновляются маппинги и массивы?

15. Низкоуровневые вызовы. Call, delegatecall, callcode - особенно пристально смотрим на эти вызовы: есть ли проверка успешности вызова, куда идет ответ, что передается?

16. Аргументы функции. Я хотел поставить этот пункт вначале списка, но решил, что будет логичнее сделать его после low-level calls, и вот почему. Иногда в аргументы функции передают тип данных bytes. В байтах иногда шифруются функции и условия для низкоуровневых вызовов. И если такое есть в функции, то есть вероятность использовать байты для взлома.

17. Изменения переменных памяти. Проверяем, какие действия изменяют основные переменные, ведь это могут быть и права доступа владельца!

18. Валидация аргументов, адресов и токенов. Есть ли достаточная проверка всех данных, которые передает пользователь? Предусмотрены ли все случаи, когда пользователь может ввести нарочно некорректные данные.

Далее пара слов о defi.   

#security #audit
👍1
Поиск уязвимостей. Обучение. Первые итоги. Часть 5

С defi и dao, признаться честно, у меня получилась какая-то однообразная практика. По сути, все задачи, которые мне давались, преследовали следующие уязвимости:

19. Доступы к функциями по модификаторам. Чаще всего в коде была функция, которая выдавала права админа или модератора, который мог вносить предложения и исполнять их, так же как и имел доступ к выводу средств из пула.

20. Манипулирование оракулом. в случае этой уязвимости, можно было изменять данные в самом оракуле, что приводило к ошибкам в расчетах в самом контракте. Поэтому стоит обращать внимание, при каких условиях выдаются права к оракулам.

21. Ликвидность пула или манипулирование ценой одного из токенов в пуле. Тут все просто: можно ли с помощью займа изменить баланс в пуле и получить тем самым бонус в контракте.

22. Незащищенные mint или reward. Также порой в контрактах эти две функции могут быть вызваны любым пользователем, или при доступных условиях, например, если у вас достаточно токенов. Тут необходимы дополнительные проверки.

23. Доступ к proposal. Также возможна недостаточная защита функции, которая добавляет предложения в dao. Хакер может сделать свое предложение и забрать весь пул.

И пара слов в конце. 

#security #audit
👍1
Поиск уязвимостей. Обучение. Первые итоги. Часть 6

В конце своего аудита можно прогнать код через популярные программы, например Slither, чтобы убедиться, что вы просмотрели все, что только можно было. Далее пишем свои комментарии и отправляем заказчику.

Повторюсь, что для топового уровня нужно намного больше практики и знания нюансов, но предложенный мной план, поможет выявить большое количество возможных ошибок.

Что дальше в планах?

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

Далее я хочу научиться видеть и понимать "потоки" между контрактами, как функции взаимодействуют между собой в двух и более контрактах, как переводятся токены и какие действия при этом вызываются.

Это может звучать просто, пока не встретишь функцию в контракте, которая вызывает пару служебных, которые, в свою очередь, вызывают другие в сторонних контрактах, при этом передают данные, изменяют память и доступы.

Также интересно погружение в нюансы работы EVM и кода Solidity.

Думаю, до нового года я еще посижу с задачами, хочу поразбирать крутые задачи от Paradigm 2021/2022 годов, а уже после - приступить к bug bounties на популярных площадках Immunefi, code4arena и sherlock.

Пока как-то так. Буду рад, если предложите еще какие-нибудь варианты задач высокого уровня.

#security #audit
👍1
Разбор байткода, opcodes, деплой

У Ильи на канале вышел новый урок про дебаггинг кода. Я уже на канале описывал этот процесс, но у лектора это все прекрасно показано и описано, что поймет даже новичок!

Видео урок.

Для тех, кто любит "мясные" уроки, это прям один из них! Крайне рекомендую к просмотру!

#debug #opcode #remix
👍2
Повторение - мать учения

Очень часто в контрактах используются контракты от openzeppelin. Однако мы привыкли просто импортировать их, особо не задумываясь, какие функции и как они реализуют. Предлагаю сегодня, в свободное время, еще раз ка;дому просмотреть их контракты и вспомнить, как они работают.

В подборку я включил контракты, которые встречал в задачах и аудитах.  Сохраните себе или сделайте репост, чтобы не потерять.


Контракты ERC20

ERC20

IERC20

SafeERC20

ERC20Pausable

ERC20Burnable

ERC20Permit

ERC20Snapshot

IERC20Metadata

TokenTimelock


Контракты ERC721

ERC721

IERC721

IERC721Metadata

IERC721Receiver

ERC721Burnable

ERC721Enumerable

ERC721Pausable

ERC721Votes


Контракты ERC777

ERC777

IERC777

IERC777Recipient

IERC777Sender


Контракты ERC1155

ERC1155

IERC1155

IERC1155Receiver

ERC1155Burnable

ERC1155Pausable

IERC1155MetadataURI

ERC1155Receiver


Контракты контроля доступа

AccessControl

Ownable

Governor

Pausable

ReentrancyGuard


Прокси контракты

Proxy

BeaconProxy

UpgradeableBeacon

ProxyAdmin - transparent

TransparentUpgradeableProxy

Initializable

UUPSUpgradeable


Библиотеки

Address

Context

Counters

Create2

Strings

ECDSA

SafeMath

Этот пост просто, как напоминалка с быстрым доступом к контрактам. Не нужно искать в гугле или GitHub, кликните тут по ссылке и изучайте.

Советую прочитывать пару контрактов в день для повторения.

#openzeppelin #contract #lib
👍5
Проект для портфолио?

Я тут на днях подумывал, что было бы не плохо написать какой-нибудь небольшой проект сугубо для портфолио, чтобы показать потенциальным работодателям уровень знаний и наработок.

Хочу спросить у вас всех, хотел бы кто-нибудь присоединиться? По ролям я виду так:

1) Дизайнер
2) Фроентенд (react)
3) Фронтенд (ether.js)
4) Тестировщик ( с тестами coverage на 100%)
5) Разработчик смарт контрактов

Проект будет полностью бесплатным и не оплачиваемым, при этом качество кода должно быть хорошим на всех этапах. Повторю - исключительно для портфолио. Код зальем на GitHub к каждому участнику.

Домен и хостинг с меня.

Если никто не захочет, буду делать сам, это без проблем.

Что думаете?
👍3
Планы до НГ

Взял небольшой перерыв от обучения на три дня, так как казалось, что слегка "перезанимался и уже не лезет". Знаете, как это бывает: вот кажется, что уже начинаешь все учить по третьему разу, интерес пропадает и хочется заняться чем-то другим. Короче, мне нужно было немного посидеть, пообщаться с коллегами, оценить планы и т.д. И вот к чему пришел.

Прежде всего по проекту в web3. Я рад, что несколько человек захотели присоединиться ко мне в этой задумке. Хочу уточнить, что это не быстрое мероприятие, и занять это все может пару месяцев, так как я стараюсь делать все на хорошем уровне и с предварительными тестами. Поэтому подумайте, будете ли вы готовы заниматься им и оставаться на связи 3-4 месяца. Если все таки найдётся несколько участников, то начнем сразу после НГ праздников.

Далее по профессии аудитора. Я ниже прикрепил видео от лектора, который недавно нашел работу в качестве аудитора и рассказывает про свое резюме, что там должно быть и на что смотрят при собеседовании. Основной упор там сделан не столько на портфолио, сколько на результатах с популярных проектов bug bounties. Поэтому до НГ я планирую разбирать задачи и кейсы, а после - попробовать зайти на эти проекты по аудиту.

Также до НГ, возможно, получится написать небольшой пет-проект для новичков и середнячков в разработке смарт контрактов и их аудите. В том плане, чтобы разрабы выкладывали свои контракты на аудит кода, а вторые - тренировались бы находить там уязвимости. Типа как бесплатная bug bounty прокачка для новичков.

И немного сбавлю обороты в "поглощении" материала и обучения. Не хочу в один момент перегореть.

А пока смотрим видео.

Хорошей недели и легкого обучения!
👍1
Проблемы контракта USDT

Нашел ветку твитов от Pashov, прекрасного начинающего аудитора, который описал несколько неочевидных нюансов контракта USDT. Предлагаю их перевод.

А сам контракт можно посмотреть тут.

1. Во-первых, у USDT нет комиссии за перевод токенов. Однако это можно легко исправить, вызвав нужную функцию админами. Это может поломать некоторые dapp приложения, которые не предусмотрели этого.

2. Во-вторых, он имеет встроенную защиту approval race condition. Другими словами, если у вас есть ненулевое allowance и вы попробуете вызвать erc20:approve, то ваша транзакция откатится, что может привести к dos в вашем контракте.

3. Transfer, transferFrom and approve - не возвращают булево значение, что не соответствует стандартам erc20.

4. Decimals. В USDT их 6, что может приводить к некорректным расчетам в контрактах.

5. Черный список. Если в вашем контракте есть "push" функция, которая рассылает адресатам токены, и один из этих адресатов в черном списке, то возникнет dos.

#usdt #security
Подборка инструментов для web3

Прекрасная подборка от аудиторской компании Quill Audits включает в себя: Blockchain Explorers, декомпиляторы, раcширения для браузера, проверки на rug pull, визуализаторы транзакций и много чего еще.

Сохраните себе, чтобы не потерять.

#tools #toolbox
👍2