文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载本篇基於 ctf-wiki 的區塊鏈安全章節撰寫。ctf-wiki 近年來由社群小夥伴共同補齊了區塊鏈安全相關內容將整個領域梳理爲公鏈安全與智能合約安全兩大方向。本文以該章節的 總覽頁 爲骨架結合 公鏈弱點、Ethereum 概述、以太坊基礎、存儲佈局、Opcode 手冊 與 重入攻擊 等頁面完整梳理 CTF 中區塊鏈安全的知識版圖。讀完本文你將理解公鏈層面各類雙花攻擊的原理與防禦思路掌握以太坊賬戶、交易、Gas、存儲佈局與 EVM 指令集等基礎知識並能沿着 ctf-wiki 提供的題目列表與工具清單搭建起從理論到實戰的完整學習路徑。區塊鏈安全概述兩大方向區塊鏈安全在近幾年發展迅速但早期 wiki 上沒有相關內容因此 ctf-wiki 邀請了多位小夥伴共同撰寫了區塊鏈安全相關內容部分用詞可能不盡準確讀者可以透過提 issue 的方式促使 wiki 及時修正。整個區塊鏈章節將安全問題概述爲兩大方向公鏈安全針對公鏈共識機制、賬本結構等底層設計的攻擊與弱點分析智能合約安全主要介紹以Solidity這種主流程式語言編寫的 Ethereum 智能合約安全基礎知識。從 CTF 的實際出題情況看區塊鏈安全內容目前爲止涉及最多的便是 Ethereum 安全參見 Ethereum 概述因此本指南的主體篇幅將圍繞以太坊展開同時補齊公鏈層面的攻擊模型。公鏈安全公鏈的定義與安全前提公鏈安全概述 引用了維基百科的定義公鏈Public Blockchain完全沒有訪問限制任何能連接互聯網的人都可以向其發送交易也可以成爲驗證者即參與共識協議的執行。通常這類網絡會爲維護安全者提供經濟激勵並使用某種形式的權益證明Proof of Stake或工作量證明Proof of Work算法。最著名、規模最大的公鏈包括比特幣區塊鏈和以太坊區塊鏈。理解公鏈安全首先要理解其最核心的威脅——雙花Double-spending。雙花問題與確認機制雙花問題是電子現金系統中的一個潛在問題同一筆資金同時支付給兩個接收者。區塊鏈系統通過公開賬本的方式來避免雙花用戶廣播交易時交易不會立即被添加到區塊鏈中而是等待礦工通過挖礦將其打包進區塊接收者在確認合法交易已上鏈之後才能認定該交易有效。用戶通過等待確認來防範雙花欺詐——隨着確認數量的增加交易變得越來越不可逆轉。但區塊鏈系統並不能完全防止雙花。攻擊者可以憑藉龐大的哈希計算資源重新完成已確認區塊的工作量證明使自己所在的鏈成爲最長鏈從而逆轉交易針對某些未確認交易直接發起雙花攻擊。51% 攻擊51% 攻擊是指礦工試圖控制超過 50% 的哈希率挖礦算力來實現雙花。在此攻擊中攻擊者可以阻止新交易被確認也可以撤銷其控制網絡期間已經確認的交易。由於比特幣等 PoW 共識的區塊鏈遵循最長鏈原則當礦工發現全網存在一條更長的鏈時就會拋棄當前鏈把更長的鏈全部複製回來並在該鏈基礎上繼續挖礦而分叉出的短鏈會被丟棄。因此攻擊者的典型手法是與商家完成交易後從交易前的區塊開始分叉憑藉足夠多的算力持續挖出更長的鏈使包含交易的那條鏈被丟棄從而實現雙花。理論上無法通過技術手段完全防範 51% 攻擊只能通過經濟學原理來規避讓控制全網 51% 算力的成本極高且擁有如此強大算力的攻擊者進行正常挖礦比作惡收益更高。但對於小規模的山寨幣來說攻擊成本較低——例如 Ethereum Classic 網絡就曾多次遭受 51% 攻擊。在 CTF 題目中與該主題相關的經典題目是miniblockchain詳見下方題目章節附屬於 DDCTF 2018。Finney 攻擊芬尼攻擊Finney 攻擊由 Hal Finney 命名他是第一個描述扣塊攻擊的人。這是一種雙花攻擊的變種攻擊對象主要是接受 0 確認的商家。攻擊流程如下攻擊者將一筆給自己轉賬的交易預挖爲一個區塊但暫不廣播到網絡用同一筆代幣去接受 0 確認的商家處消費在獲得商家的交換物、且交易真正被確認前才廣播之前預挖的區塊使轉給自己的交易合法化比特幣網絡接受該有效區塊使對商家的交易失效最終實現雙花。所謂「0 確認」是指一筆交易已廣播到全網、即將被打包進區塊的狀態。由於區塊鏈出塊時間較慢交易確認需要等待較長時間部分商家爲節省時間接受 0 確認交易——即交易信息廣播到全網即可無需等待打包入區塊。Race 攻擊競爭攻擊Race 攻擊是攻擊者使用相同的資金連續廣播兩個衝突的交易但最終只有一個交易會得到確認。該攻擊主要通過控制礦工費來實現雙花同樣針對接受 0 確認的商家最終使發給自己的交易被打包確認而使另一筆支付交易失效。與 Finney 攻擊的區別在於對抗雙方的形態不同Finney 攻擊是「0 確認交易 vs 衝突區塊」Race 攻擊是「0 確認交易 vs 衝突交易」。Vector76 攻擊一次確認攻擊Vector76 攻擊也稱一次確認攻擊是 Race 攻擊與 Finney 攻擊的結合使得具有一個確認的交易仍然可以被撤銷。攻擊流程攻擊者礦工創建兩個節點一個連接到商家節點另一個連接到區塊鏈網絡中連接良好的節點使用相同的資金創建兩筆交易交易 1 發送給商家地址交易 2 發送給自己的錢包並設置較高的礦工費攻擊者不立即廣播這兩筆交易而是在交易 1 的分支上進行挖礦挖到區塊後向商家節點廣播交易 1向另一個節點廣播交易 2交易 2 被確認後攻擊者立即把自己之前在交易 1 分支上挖到的區塊廣播給商家——接受一次確認就支付的商家會確認交易成功由於交易 2 發送給了連接更多節點的節點礦工在該分支上挖出更長鏈的概率更大交易 1 會被回滾從而實現雙花。扣塊攻擊Block Withholding扣塊攻擊最簡單的形式是上述的 Finney 攻擊但同樣存在針對礦池的扣塊攻擊方式。礦池最常見的支付機制是 PPSPay-Per-Share礦工所貢獻的每一個「share股份」都會收到固定報酬。Share 是用來記錄礦工貢獻的哈希值它不是區塊鏈網絡中有效的哈希而只是礦池設置的匹配條件。由於單獨礦工找到符合 PoW 系統要求的解是極小概率事件礦池會給礦工設置一個合理的提交 Share 門檻以便衡量工作量。扣塊攻擊是指惡意礦工找到滿足礦池要求、但不滿足比特幣系統要求的結果時正常向礦池提交工作證明一旦得到滿足比特幣系統要求的結果即真正挖到區塊則私自扣下不提交。如此一來礦池便損失了對應的出塊獎勵。扣塊攻擊會使礦工和礦池雙方都受損失礦工只是得不到礦池分攤的 Share 獎勵而礦池則損失了整塊出塊獎勵。自私挖礦Selfish-Mining自私挖礦的流程攻擊者挖到新區塊後藏起來不公佈其他誠實礦工不知道新區塊的存在仍在舊區塊基礎上繼續挖礦等攻擊者挖到第二個區塊後同時公佈手中藏着的兩個區塊此時區塊鏈分叉出現只要攻擊者比誠實礦工多挖一個區塊攻擊者所在的分叉就是最長鏈誠實礦工所在的鏈因比攻擊者的分叉短而被作廢攻擊者憑藉兩個新區塊獲得相應收益誠實礦工的獎勵則被回滾。上述各類公鏈攻擊的完整細節可參閱 公鏈弱點。智能合約安全以太坊爲什麼 CTF 中區塊鏈 以太坊Ethereum 概述 明確指出CTF 中關於區塊鏈安全的內容目前爲止涉及到最多的便是 Ethereum 安全。以太坊是區塊鏈 2.0 的代表產物底層使用區塊鏈技術因此繼承了區塊鏈的各種特性其中最重要的一項是——代碼一旦上鍊便難以篡改或更改。正因如此我們需要格外關注它的安全。智能合約Smart Contract是以太坊中最爲重要的概念它允許在沒有第三方的情況下進行可信交易這些交易可追蹤且不可逆轉。CTF 中的以太坊安全題目相對而言比較簡單主要涉及的是 Solidity 安全。要上手這類題目需要具備以下基本能力對區塊鏈基本知識以及交易本質有所瞭解熟悉並掌握 Solidity 程式語言及以太坊虛擬機 EVM 運行機制熟悉各種測試鏈包括私鏈熟悉 Remix、MetaMask、web3.js、web3.py 等工具或庫的使用瞭解並掌握以太坊智能合約各種漏洞及其攻擊原理對底層 opcodes 理解透徹較強的程序理解和逆向分析能力。注以太坊智能合約大多數不公開源代碼而是隻公開字節碼所以逆向分析能力是必備的。基礎知識Solidity、工具與賬戶模型以太坊基礎 從工具鏈到賬戶、交易模型給出了完整的知識鋪墊。Solidity是一種用於編寫智能合約的高級語言語法類似 JavaScript。在以太坊平臺上Solidity 編寫的智能合約可以被編譯成字節碼在以太坊虛擬機 EVM 上運行。MetaMask是使用最廣泛的以太坊錢包小狐狸標識Chrome 提供其插件。它不僅可以管理外部賬戶還可便捷切換測試鏈網絡並支持自定義 RPC 網絡。一個外部賬戶通常由私鑰文件控制擁有私鑰即可使用對應地址賬戶中的 Ether我們通常把管理數字密鑰的軟件稱爲錢包所謂備份錢包其實就是備份賬戶的私鑰文件。Remix是基於瀏覽器的 Solidity 編譯器和集成開發環境提供交互式界面以及編譯、調用測試、發佈等一系列功能。以太坊中存在兩種類型的賬戶外部賬戶Externally Owned Account, EOA由人創建可以存儲以太幣由公鑰和私鑰控制。每個外部賬戶擁有一對公私鑰用於簽署交易地址由公鑰決定。外部賬戶不能包含 EVM 代碼其特性包括擁有一定的 Ether可以發送交易、通過私鑰控制沒有相關聯的代碼。合約賬戶由外部賬戶創建包含合約代碼地址由合約創建者的地址與該地址發出的交易共同計算得出。其特性包括擁有一定的 Ether有相關聯的代碼代碼通過交易或其他合約發送的調用來激活當合約被執行時只能操作合約賬戶擁有的特定存儲。關於私鑰、公鑰與地址的關係需要記住私鑰經過橢圓曲線算法ECDSA-secp256k1計算生成公鑰再計算公鑰的 Keccak-256 哈希值取最後 160 位二進制通常表現爲 40 位的十六進制字符串形成地址。公鑰和地址都可以公開而私鑰必須妥善保管——丟失或泄露都會導致資產損失。以太坊中這兩種賬戶統稱爲「狀態對象」存儲狀態。一個以太坊賬戶包含 4 個部分字段含義nonce已執行交易總數標示該賬戶發出的交易數量balance賬戶持幣數量記錄以太幣餘額storageRoot存儲區的哈希值指向智能合約賬戶的存儲數據區codeHash代碼區的哈希值指向智能合約賬戶存儲的合約代碼兩個外部賬戶之間的交易只是價值轉移而從外部賬戶到合約賬戶的交易會激活合約代碼允許它執行各種操作轉移 Token、寫入內部存儲、創建新 Token、執行計算、創建新合約等。與外部賬戶不同合約賬戶不能自行發起新交易只能觸發交易以響應其他交易。交易模型與 Gas 機制以太坊的交易是指一條外部賬戶發送到鏈上另一賬戶的消息的簽名數據包包含發送者簽名、接收者地址以及轉移的以太幣數量等內容。每筆交易都需要支付費用用於支付執行所需的計算開銷。計算開銷不以以太幣直接計價而是引入Gas作爲執行開銷的基本單位通過 GasPrice 與以太幣換算。GasPrice 根據市場波動調整避免以太幣價值受市場價格影響。交易費用涉及三個概念Gas衡量一筆交易所消耗的計算資源的基本單位Gas Price一單位 Gas 所需的手續費EtherGas Limit交易發送者願意爲這筆交易執行所支付的最大 Gas 數量。注如果交易實際消耗的 GasGas Used小於 Gas Limit礦工只收取實際計算開銷對應的手續費Gas Used × Gas Price如果 Gas Used 大於 Gas Limit礦工執行中會發現 Gas 耗盡而交易未執行完成此時礦工回滾到執行前的狀態並收取 Gas Limit 對應的手續費GasPrice × Gas Limit。換句話說GasPrice × Gas Limit表示用戶願意爲一筆交易支付的最高金額。一條交易包含以下內容from發送者地址必填、to接收者地址爲空則表示創建合約、value轉移的以太幣數量、data數據字段存在則表示創建或調用合約、Gas Limit、GasPrice、nonce區分同一賬戶發出的不同交易、hash由以上信息生成的散列值、r、s、v交易簽名的三個部分由私鑰對交易 hash 簽名生成。以太坊交易有三種類型轉賬交易——最簡單從一個賬戶向另一個賬戶發送 Ether只需指定發送者、接收者、轉移數量Gas、nonce、hash、簽名可按默認方式生成web3.eth.sendTransaction({ from: 0x88D3052D12527F1FbE3a6E1444EA72c4DdB396c2, to: 0x75e65F3C1BB334ab927168Bd49F5C44fbB4D480f, value: 1000 })創建合約的交易——將合約部署上鍊to字段爲空字符串data字段爲合約編譯後的二進制代碼web3.eth.sendTransaction({ from: 0x88D3052D12527F1FbE3a6E1444EA72c4DdB396c2, data: contract binary code })執行合約的交易——to字段爲要調用的智能合約地址data字段指定要調用的方法簽名哈希及編碼後的參數web3.eth.sendTransaction({ from: 0x88D3052D12527F1FbE3a6E1444EA72c4DdB396c2, to: 0x75e65F3C1BB334ab927168Bd49F5C44fbB4D480f, data: hash of the invoked method signature and encoded parameters })提示根據to、data字段內容也可以反過來判斷交易類型進而繼續分析。與合約交互除了通過 Remix 手動操作外還可以使用 Python 的 web3.py 庫、Node.js 的 web3.js 庫或通過 Infura 提供的 RPC API 進行自動化交互。Infura 支持 Mainnet、Ropsten、Rinkeby、Kovan、Görli 等網絡的 JSON-RPC over HTTPs / WebSockets 訪問點URL 中的YOUR-PROJECT-ID需替換爲 Infura 儀表盤中的項目 ID。下面是一個使用 web3.py 與 Infura 調用合約函數選擇器爲0x00774360的函數的例子from web3 import Web3, HTTPProvider w3 Web3(Web3.HTTPProvider(https://rinkeby.infura.io/v3/YOUR-PROJECT-ID)) contract_address 0x31c883a9aa588d3f890c26c7844062d99444b5d6 private your private key public 0x75e65F3C1BB334ab927168Bd49F5C44fbB4D480f def deploy(public): txn { from: Web3.toChecksumAddress(public), to: Web3.toChecksumAddress(contract_address), gasPrice: w3.eth.gasPrice, gas: 3000000, nonce: w3.eth.getTransactionCount(Web3.toChecksumAddress(public)), value: Web3.toWei(0, ether), data: 0x007743600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a6100016100016100016100016100016100650361000161fbfbf1000000000000, } signed_txn w3.eth.account.signTransaction(txn, private) txn_hash w3.eth.sendRawTransaction(signed_txn.rawTransaction).hex() txn_receipt w3.eth.waitForTransactionReceipt(txn_hash) print(txn_hash, txn_hash) return txn_receipt print(deploy(public))tx.origin 與 msg.sender 的區別msg.sender是函數的直接調用方在用戶手動調用時是發起交易的賬戶地址但也可以是調用該函數的另一個智能合約地址。tx.origin必然是這個交易的原始發起方無論中間有多少次合約內/跨合約調用而且一定是賬戶地址而不是合約地址。給定場景用戶通過合約 A 調用合約 B對於合約 Atx.origin和msg.sender都是用戶對於合約 Btx.origin是用戶msg.sender是合約 A。這一區別是很多合約漏洞如釣魚式 delegatecall 攻擊的根源在分析題目時需要時刻留意。存儲佈局插槽、映射與動態數組以太坊存儲 是分析智能合約漏洞的必修課。以太坊爲合約的每項數據指定一個可計算的存儲位置存放在一個容量爲 2^256 的超級數組中數組中每個元素稱爲插槽slot初始值爲 0。雖然數組容量上限極高但實際存儲是稀疏的只有非零數據纔會被真正寫入存儲。值類型定長整型int/uint、地址address、定長字節數組bytes1-bytes32等數據長度已知編譯時按字段聲明順序從位置 0 開始連續存放。如果可能小於 32 字節的多個變量會被打包到一個插槽中數據超過 32 字節則佔用多個連續插槽data.length / 32。規則如下存儲插槽的第一項以低位對齊右對齊方式存儲基本類型僅使用存儲它們所需的字節如果插槽剩餘空間不足以存儲一個基本類型則它被移入下一個插槽結構體和數組數據總會佔用一整個新插槽但內部的各項仍按上述規則打包。例如以下合約pragma solidity ^0.4.0; contract C { address a; // 0 uint8 b; // 0 uint256 c; // 1 bytes24 d; // 2 }其存儲佈局爲slot 0 從低位到高位依次存放a (20 字節)、b (1 字節)、剩餘 11 字節未使用slot 1 存放c (32 字節)slot 2 存放d (24 字節)、剩餘 8 字節未使用。映射mapping無法按順序存儲。對於mapping(address uint) a;它佔據位置p處的一個插槽該插槽不會被真正使用鍵k對應的值位於keccak256(k . p).爲連接符如果該值是非基本類型則以keccak256(k . p)作爲偏移量進一步定位。動態數組如uint[] b;佔用位置p處的插槽存放數組長度數組真實起始點位於keccak256(p)處第i個元素位於keccak256(p) i。字節數組與字符串存在特例如果數據長度 ≤ 31 字節則數據與長度一起存儲在同一插槽——數據存儲在高位字節左對齊最低位字節存儲length * 2如果數據長度 31 字節主插槽存儲length * 2 1數據存儲在keccak256(slot)中。可見性與私有數據洩露由於以太坊上所有信息都是公開的即使變量聲明爲private仍能讀到具體值。利用 web3 的web3.eth.getStorageAt()方法可以讀取指定地址指定位置的存儲內容。只要計算出變量對應的插槽位置就能拿到變量的值// web3.eth.getStorageAt(address, position [, defaultBlock] [, callback]) web3.eth.getStorageAt(0x407d73d8a49eeb85d32cf465507dd71d507100c1, 0) .then(console.log); 0x033456732123ffff2342342dd12342434324234234fd234fd23fd4f23d4234參數含義address爲要讀取的地址position爲存儲中的索引編號defaultBlock可選用於覆蓋web3.eth.defaultBlock屬性值callback爲可選回調函數第一個參數是錯誤對象第二個參數是結果。以 Balsn CTF 2019 的 Bank 一題爲例題目合約包含owner、randomNumber、SafeBox[] safeboxes與mapping(address FailedAttempt[]) failedLogs其插槽佈局如下----------------------------------------------------- || unused (12) | owner (20) | - slot 0 ----------------------------------------------------- || randomNumber (32) | - slot 1 ----------------------------------------------------- || safeboxes.length (32) | - slot 2 ----------------------------------------------------- || occupied by failedLogs but unused (32) | - slot 3 -----------------------------------------------------其中safeboxes的元素起始於keccak256(2)每個元素佔 2 個插槽failedLogs需要先通過keccak256(addr . 3)定位特定地址對應數組的長度插槽數組真實起始點位於keccak256(keccak256(addr . 3))每個元素佔 3 個插槽。分析時可藉助如下輔助函數計算位置function read_slot(uint k) public view returns (bytes32 res) { assembly { res : sload(k) } } function cal_addr(uint k, uint p) public pure returns(bytes32 res) { res keccak256(abi.encodePacked(k, p)); } function cal_addr(uint p) public pure returns(bytes32 res) { res keccak256(abi.encodePacked(p)); }與存儲相關的攻擊一般分爲兩類一是利用「存儲本質公開」的特性任意讀取private變量二是結合任意寫漏洞覆蓋特定位置的存儲。EVM 與 Opcodes以太坊的 opcodes 共有 142 種常見部分如下完整列表可查閱 Ethereum OpcodesUint8MnemonicStack InputStack OutputExpression00STOP--STOP()01ADD| a | b || a b |a b02MUL| a | b || a * b |a * b03SUB| a | b || a - b |a - b04DIV| a | b || a // b |a // b51MLOAD| offset || value |value memory[offset:offset32]52MSTORE| offset | value |-memory[offset:offset32] value54SLOAD| key || value |value storage[key]55SSTORE| key | value |-storage[key] value56JUMP| destination |-$pc destination5BJUMPDEST---F3RETURN| offset | length |-return memory[offset:offsetlength]FDREVERT| offset | length |-revert(memory[offset:offsetlength])注意JUMPDEST 是跳轉指令的目標跳轉指令不能跳轉到沒有 JUMPDEST 的地方。以 starCTF 2021 的 StArNDBOX 一題爲例題目合約部署時傳入 100 wei目標是清空合約 balance。StArNDBoX函數可以獲取任意地址的合約並檢測其每個字節是否爲質數require(res.isPrime() true)通過檢查後用delegatecall調用目標合約。但題目中的isPrime並非完整質數檢查函數00和01也能通過檢查因此可以構造如下字節碼// 0x6100016100016100016100016100016100650361000161fbfbf1 61 00 01 | PUSH2 0x0001 61 00 01 | PUSH2 0x0001 61 00 01 | PUSH2 0x0001 61 00 01 | PUSH2 0x0001 61 00 01 | PUSH2 0x0001 61 00 65 | PUSH2 0x0065 03 | SUB 61 00 01 | PUSH2 0x0001 61 fb fb | PUSH2 0xfbfb f1 | CALL執行address(0x0001).call.gas(0xfbfb).value(0x0065 - 0x0001)即把題目合約的 balance 轉到0x1地址從而清空 balance 滿足拿 flag 的條件。經典漏洞重入攻擊重入攻擊 是智能合約中的經典攻擊以太坊 The DAO 項目遭受的重入攻擊直接導致了以太坊ETH和以太坊經典ETC的硬分叉。其原理是「先給錢後記賬」。假設銀行合約實現瞭如下取款功能contract Bank { mapping(address uint256) public balanceOf; ... function withdraw(uint256 amount) public { require(balanceOf[msg.sender] amount); msg.sender.call.value(amount)(); balanceOf[msg.sender] - amount; } }問題在於以太坊中合約的調用者可以是另一個智能合約轉賬時收款合約的 fallback 函數會被調用。若 fallback 函數內再次調用withdraw由於此時balanceOf尚未減少require 條件仍然滿足導致可重複取款。注意 fallback 函數需要限制重入次數否則會無限循環調用導致 gas 不足。假設攻擊合約存款 1 ether可如下取出 2 ethercontract Hacker { bool status false; Bank b; constructor(address addr) public { b Bank(addr); } function hack() public { b.withdraw(1 ether); } function() public payable { if (!status) { status true; b.withdraw(1 ether); } } }幾個關鍵注意點目標合約使用call發送以太幣時默認提供所有剩餘 gas若改用transfer或send發送只有 2300 gas 供攻擊合約使用不足以完成重入攻擊重入前需確認目標合約有足夠以太幣多次轉賬若目標合約沒有 payable 的 fallback 函數可新建合約通過selfdestruct自毀強制轉賬fallback 中先改寫status再重入如果反過來仍會無限循環調用。重入漏洞與整數下溢漏洞關聯密切上述攻擊後攻擊合約存款由 1 ether 變爲 -1 ether而 uint256 保存的負數實際是一個極大的正數後續可繼續利用這筆巨額存款。除重入攻擊外以太坊章節還整理了其他常見漏洞delegatecall 濫用delegatecall、CREATE2 地址預計算create2、整數溢位/下溢overflow-underflow、可預測隨機數randomness、短地址攻擊shortaddress、未初始化存儲指針uninitialized-storage-pointer、跳轉導向程式設計 JOPjump-oriented-programming、任意寫arbitrarywrite與空投獵取airdrop-hunting等。智能合約逆向智能合約逆向 指出智能合約大多數不公開源碼、只公開字節碼因此需要逆向工具或人工進行逆向分析。常用手段包括在線反編譯服務如 ethervm.io 的 decompile 功能但有時會莫名崩潰以及其他第三方逆向工具。安全工具與學習資源學習資源 頁面按類別整理了完整的工具生態可視化工具Solidity Visual AuditorVSCode 擴展提供安全導向的語法/語義高亮與類結構視圖、Sūrya合約結構可視化與函數調用圖查詢、Solgraph生成 DOT 圖展示函數控制流並標註潛在漏洞、EVM LabEVM 交互工具包、ethereum-graph-debugger圖形化 EVM 調試器、Piet合約架構可視化 Web 應用。靜態與動態分析MythX專業級雲服務基於符號分析與輸入模糊測試檢測常見漏洞、Mythril智能合約安全瑞士軍刀、SlitherPython 編寫的靜態分析框架具備污點與值跟蹤能力、Contract-Library已部署合約的反編譯與安全分析、Echidna以太坊模糊測試器基於屬性測試生成惡意輸入、Manticore支持 EVM 的動態二進制分析工具、Oyente基於學術論文實現的常見漏洞分析、Securify全自動在線靜態分析器、SmartCheckSolidity 源碼靜態分析、Octopus支持 EVM 與 eWASM 的區塊鏈智能合約安全分析、sFuzz受 AFL 啓發的高效模糊測試器、Vertigo智能合約變異測試。弱點分類與測試用例SWC-registrySWC 定義及大量精心構造與真實世界的漏洞合約樣例及發佈在 GitHub Pages 上的 SWC Pages。測試覆蓋solidity-coverageSolidity 測試代碼覆蓋。Linters 與格式化Ethlint、Solhint提供安全與風格雙重校驗、Prettier Solidity 插件強制基本風格約定。論文與書籍方面資源頁推薦了《以太坊技術詳解與實戰》等書籍以及智能合約、區塊鏈方向的學術論文集合。練習平臺與 CTF 題目題目收集 頁面整理了完整的練習資源。在線練習靶場/遊戲方面可以重點關注以下以太坊智能合約安全挑戰平臺EthernautOpenZeppelin 推出的以太坊智能合約安全闖關遊戲Capture The Ether以太坊智能合約安全挑戰集Security Innovation 的區塊鏈 CTF 挑戰Damn Vulnerable DeFiDeFi 漏洞利用系列挑戰Paradigm CTF 2021含官方題目與官方解題代碼。注CTF 中區塊鏈題目並不算多ctf-wiki 蒐集了絕大多數題目智能合約與公鏈相關按年份附上題目與 WP 鏈接題目列表會隨時更新同一年中比賽名稱與多篇 WP 均不區分順序。相關題目可前往 ctf-challenges 倉庫的 blockchain 目錄查找或在 ChainFlag 靶場在線練習。歷年 Ethereum 智能合約題目節選年份比賽代表性題目2021RealWorldRe: Montagy、EasyDefi2021*ctfStArNDBOX2020高校戰「疫」網絡安全分享賽OwnerMoney2020RCTFroiscoin2020第五空間CreativityPlus、SafeDelegatecall2020釣魚城杯StrictMathematician2020QWBIPFS、EasyAssembly、EasyFake、EasySandbox、EthGaMe、EBK2020BalsnElection、IdleGame2020華爲系列ethenc、boxgame、ContractGame2019RealWorld / Balsn / CISCNMontagy、Bank、Creativity、Daysbank2019QWB / ByteCTF / N1CTFbabybank、babybet、bet、hf、h4ck2019數字經濟 / RoarCTF / Hackergamecow、rise、jojo、CoinFlip、JCBank2019XCTF_final / D^3CTF / De1CTFHappy_DOuble_Eleven、bet2loss_v2、Easy EOS2018RealWorld / HCTF / BCTFAcoraida Monica、ethre、bet2loss、ez2win、Fake3d、EOSGAME2018WCTF / LCTF / *ctfBelluminarBank、easy little trick、ggbank、web-smart_contract2017dctfspock-lizard-alpha / beta / omega歷年公鏈Public Blockchain題目年份比賽題目2021RealWorldBillboard2018DDCTFmini blockchain對應「miniblockchain」題目用於練習 51% 攻擊等公鏈弱點其中 DDCTF 2018 的 mini blockchain 題目正是理解上述「51% 攻擊」等公鏈弱點的最佳實戰入口相關攻擊原理見公鏈弱點。結語一條從理論到實戰的學習路徑回顧 ctf-wiki 區塊鏈章節的整體脈絡可以歸納出一條清晰的學習路徑先修基礎掌握區塊鏈基本知識與交易本質賬戶、交易、Gas熟悉 Solidity 語言與 EVM 運行機制搭建工具鏈學會 MetaMask、Remix、web3.js / web3.py、Infura 的配置與交互方式能在測試鏈/私鏈上部署與調用合約吃透底層理解存儲佈局插槽、映射、動態數組與常見 opcodes這是逆向分析與構造攻擊載荷的根基逐個擊破漏洞沿着重入、delegatecall、整數溢位、隨機數、短地址、未初始化存儲指針等漏洞專頁理解每種攻擊的原理與利用代碼逆向與實戰針對只公開字節碼的題目運用反編譯工具和 opcode 閱讀能力還原邏輯最後在 Ethernaut、Capture The Ether、Damn Vulnerable DeFi 等靶場以及歷年 CTF 題目中反覆練習。需要說明的是以太坊與區塊鏈技術仍在快速演進ctf-wiki 中的公鏈安全等章節仍留有「待補充」空間讀者既可將其作爲入門地圖也可以通過提交 issue 與社群一起完善這份知識庫。赞分享文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载相关推荐A2UI Express 格式优化实录run_020 数据路径斜杠预处理如何让评测通过率稳定在 100%A2UI Express 格式优化实录run_020 数据路径斜杠预处理如何让评测通过率稳定在 100% 本篇以 A2UI 仓库中一次完整的迭代优化报告 ev文档网络安全教程JuiceFS 自动化部署:用 Ansible 批量安装客户端并通过 fstab 管理挂载JuiceFS 自动化部署:用 Ansible 批量安装客户端并通过 fstab 管理挂载 本文讲解如何编写 Ansible 剧本,在多台 Linux 主机上批文档网络安全教程Hindsight 0.9 配置体系详解从环境变量到分层 Bank 级覆盖的完整调优指南Hindsight 0.9 配置体系详解从环境变量到分层 Bank 级覆盖的完整调优指南 本文基于 Hindsight 官方文档中的 Configuratio文档网络安全教程上一篇3分钟快速上手Figma中文汉化插件完整使用指南下一篇大气层整合包Switch破解的终极解决方案与完整使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
大模型上下文工程深度解析:Codex 缓存友好设计实践与 TaoToken 配置骨架 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 11:42:38
Django Ninja 接口限流(Throttling)实战指南:全局、路由与单接口三级限流配置与自定义实现 后端API设计 【免费下载链接】django-ninja 💨 Fast, Async-ready, Openapi, type hints based framework for building APIs 项目地址: https://gitcode.com/gh_mirrors/dj/django-ninja 点击查看 免费下载 本文围绕 Django Ninja 的限流(T… · 2026/9/25 11:42:38
C++ 并发编程实战指南 C++ 并发编程实战指南
C++ 并发编程是现代 C++ 开发者必须掌握的核心技能之一。从 C++11 开始,标准库提供了丰富的并发支持。本文将从基础到实战,带你系统掌握 C++ 并发编程。 1. 基础:std::thread
#include <iostream>
#include <thread>
#include <vecto… · 2026/9/25 13:28:35
C++ 模板参数 详解 + 实例代码 C++ 模板参数 详解 + 实例代码
C++ 模板(Template) 是实现泛型编程的核心机制,允许代码在编译期根据参数类型生成具体代码,从而实现类型安全和高性能。
1. 模板参数的种类
模板参数主要有三类: 类型参数(Type Parameter)—— 最常用 非类型参数(Non-type Parameter)… · 2026/9/25 13:28:28
AI skills 配置 TaoToken:settings.json 骨架与验证动作 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 13:28:22
Android开发-教你玩转Android数据存储SQLite 如何加载SD卡数据库 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 13:28:04
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37