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

18. Private Key Compromise.
Тут все просто, кража приватного ключа от адреса, где лежат все токены.

19. Unsafe ERC721 Operations. Стандартная библиотека Openzeppelin ERC721 считается стандартом, однако даже сама компания рекомендует использовать ее аналог ERC721Safe с безопасными функциями, которые делают дополнительные проверки.

20. Airdrop Exploits. Некоторые компании используют систему snapshot для Airdrop своего токена, чтобы отслеживать инвестиции пользователей. Однако из-за возможных ошибок в коде смарт контракта, мошенники могут манипулировать количество "инвестиций" с помощью флеш займа или других способов.

21. API Exploits. Не так страшны как другие уязвимости, но могут привести к задержкам при передачи и обновлении информации по токенам.

22. NFT Social Media Hacks. Кратко говоря, фишинг через соцсети.

23. Phishing Scams. Фишинг на сайтах, в ботах и скрытых транзакциях.

24. Frontend Attacks. Хакеры взламывают официальных маркеты и перенаправляют пользователей на свои проекты для кражи данных.

#nft #scam
Проблемный create2

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

Я ни разу не работал с подобными случаями, поэтому заинтересовался, как такое вообще возможно, чтобы один контракт подменят другой?

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

Первая статья с простым примером контрактов, и вторая - более подробная про опкод.

Я протестировал их в ремиксе и в goerly, и к моему удивлению, так делать действительно можно.

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

#create2 #security
👍4
Не принятый create3

А еще один из участников в сообществе ранее делился ссылкой на репо GitHub, где представлен способ создания контрактов с create3.

Как я понял, create3 был предложен в EIP-3171 и был призван обновить create2, убрав из него initCode адреса, на основе которого должен был создаваться новый контракт.

Однако предложение не прошло, и create3 был оставлен в качестве библиотеки. Вот ссылка на нее.

Кратко говоря, основные фичи create3 это:

- Создание контракта на основе msg.sender + salt;
- Один адрес для разных EVM сетей;
- Поддержка конструкторов;
- Возможность payable contract creation;

Однако использование этой библиотеки увеличивает затраты на газ, по сравнению с create2, примерно на 55к.

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

#create3
Офигенная задача от 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