Let’s Capture The Flag! Etheruem CTF Tutorial 從零開始破解智能合約漏洞!
本次 2019 Crosslink 特別準備了各種難度且有獎品的 CTF*,希望讓所有參與者都能體驗到智能合約 Smart Contracts 的漏洞安全問題。對於想追求挑戰的人,在最短時間內解出最多題就有機會得到冠軍獎品 HTC Exodus 區塊鏈手機一支;對於休閒性質參與者,相信這些試題能幫助各位對 Solidity 及智能合約有更深入的了解!為了避免這個遊戲只有會寫 code 的人在玩,本文將引導沒有程式背景的人一起輕鬆入門! For English readers, there are screenshots of every step to guide you through :)
Outline
1. 前置作業:安裝 Metamask
2. 開始遊玩:CTF 開打!
安裝 Metamask
若已安裝過 Metamask,可以直接進入到第二部分:CTF 開打!
Metamask 是用來和 Ethereum 互動的錢包 (wallet),我們要先下載才能開始遊玩 CTF !不知道 Ethereum 是什麼?快來台北以太坊社群瞭解!
一、點擊中央的 GET CHROME EXTENSION
二、點擊右上方 Add to Chrome
三、創建錢包 or 匯入錢包
若已經創建過錢包,可以選擇左邊的匯入;否則選擇右邊創建錢包
四、輸入密碼
五、助憶詞
除非有打算要存錢到 Metamask,否則忘掉了一個帳號重辦就好了XD
六、帳號建立成功後,點擊右上方切換到 “Ropsten 測試網路”
七、取得測試用 ether
為了玩 CTF,我們需要測試網路 Ropsten 上的測試 ether,可以由這個網站取得:點我。
點擊 request 1 ether from faucet 後就會彈出 Metamask 要和用戶的錢包訪問的請求。
點擊連線後,下方會出現交易的編號。
稍後片刻後,打開 Chrome 右上角的 Extension Metamask 小狐狸的圖示後,會看到測試幣入帳了,前置作業就完成啦~
CTF 開打!
一、進入 2019 Crosslink CTF (現移至 此處),點擊 Play now! 開始遊玩
接下來我們將照著每個步驟來示範第 0 題如何進行!第一個步驟 Set up MetaMask 已經完成了,所以可以進到第二步驟。
二、 Open the browser’s console: 右上角功能表 -> 工具 -> 開發者工具
此時就能看到右方所謂的 web console,這個區域可以讓我們查詢此頁面的一些資訊、進行簡單的互動。
依照文中的要求,我們試著在藍色的提示符號(>)右方輸入
player
還沒按下 Enter 之前,我們可以看到在 player 下方自動出現了淡紅色的提示訊息,這是非常貼心的功能,代表系統「預先告訴你如果輸入是 player,他會給你什麼樣的輸出/ feedback」。
按下 Enter 後,就會發現淡紅色的提示轉為普通紅色的輸出,而這串16進位的數值就是自己錢包的地址。
三、Use the console helpers: 試著和 console 互動
照著提示輸入
getBalance(player)
會出現小三角形 Promise{<pending>},按下小三角形。
展開三角形後,其中的 PromiseValue 顯示的 2 就是目前擁有的測試幣數量。
再輸入
help()
可以看到提示使用者可以輸入的關鍵字/指令。稍微看一下就會發現剛剛輸入的 player 及 getBalance(address) 也在其中。
四、五、六、 略
步驟四、五可以略過,不妨礙我們解題;步驟六我們已經做完了。
七、Getting a level instance: 取得此處要破解的 Smart contract 的 instance
instance 的中文翻譯是個難題,在此處我們可以理解為:為了破解現在第 0 題的智能合約 Smart contract,我們需要叫出這份合約的一個「實體」,並破解之。
依照文中的指示,拉到本頁最下方,點擊 Get new instance。
這次跳出的訊息似乎不同了?為了區別,我們可以看到紅色部分不同於之前只是 Metamask 要取得訪問帳戶的權限,這次 Metamask 要幫我們進行一筆交易,這是因為為了在以太坊進行交易,我們需要付出手續費。
此時我們有兩個選擇:確認、或是按黑色框內的 EDIT。此處我們會先直接選擇確認,而按 EDIT 會發生什麼事情我們留到後方解釋!
確認之後,就會發現右方多出了 Sent transaction。再稍待片刻後,螢幕上又出現了三筆新資訊:Mined transaction 代表交易成功;instance address;sumbit instance。此時,只要Get new instance 旁邊出現橘色的 Submit instance有出現,就代表我們終於可以開始解題了!
八、略
九、Interact with the contract to complete the level: 解題時間!
第八步驟要做的事情和第九差不多,就是繼續照著指示做,輸入
contract.info()
展開三角形後,會看到 PromiseValue 的欄位提示我們輸入 info1()。
然而,這邊要注意,照著提示是要輸入
正確: contract.info1()
錯誤: info1()
contract.函數 此形式代表使用 contract 這個 instance 本身內建的函數。因此,我們應呼叫的是 contract.info1()來和目前的 contract 互動。
這次則是叫我們嘗試 info2(),但要加入字串 “hello” 當作參數。因為 info2() 是個函數,所以我們要把 “hello” 這個參數 傳入 info2()。
contract.info2("hello") # 將字串傳入函數的時候,要加上雙引號""
這次要輸入
contract.infoNum()
此處要點開兩個三角形,可以看到一個存在 c 欄位的值 42,這個數值如同上一個 PromiseValue 中的提示:infoNum() 提示的值是下一個要呼叫的函數,因此我們嘗試函數 info “42”
contract.info42()
怎麼還沒結束…只好繼續聽話照做
contract.theMethodName()
心開始累了…
contract.method7123949()
這次終於看似來到了緊要關頭,提示問我們知不知道密碼?但是…目前都沒看哪裡有密碼啊???!!!
這邊為了讓所有參與者想想看密碼到底藏在哪裡…
……..
…….
……
…..
….
…
..
.
相信有人已經看到蛛絲馬跡了,而蛛絲馬跡其實是在於…
如果參與者們自己有試著輸入以上那些步驟,應該會發現輸入到
contract.
的時候,web console 會自動提示我們「能夠呼叫的函數有哪一些」。講得更清楚點,如同上方 contract.info1() 時提過的,web console 提示我們的是 contract 有哪一些內建的函數可以使用。因此,我們就能夠瀏覽除了上方用過的 info1(), info42(), method7123949(),還有哪些函數可以使用。
仔細看一下上面我們被提示能夠使用的函數…有沒有 p 開頭的啊…還真的有 password 啊!!!迫不及待的快輸入
contract.password()
我們會看到在 PromiseValue 中的答案。因此,接下來只要照著上方 method7123949() 中提到的:用 authenticate() 函數就能驗證了
contract.authenticate("密碼輸入在此") # 大家應該都知道密碼是什麼了吧
# 別忘了將字串傳入函數時要加上雙引號""
輸入後,一樣會跳出 Metamask 向我們確認交易的提示,這次我們可以試著按 EDIT,發現我們可以自訂要付多少手續費:付越多,這筆交易就越快被確認。因此,我們選擇最右邊「快」的方案,儲存後按確認。
這筆交易被確認了,我們就來到了最後步驟:Submit instance。
有跟隨筆者勞累奔波到這一步的人應該就會看到 console 中浮誇的恭喜以及左上角第 0 題的後方出現了勾勾,成功了!!!~~~
以上就是本次 CTF 第 0 題的完整教學,希望有成功地讓不具程式背景的讀者也破解一題、接觸到和 Smart contract 互動的實戰演練,甚至進而去思考如何破解其他題目,享受到工程師們平時解 code 的樂趣 (?)XD
*註:CTF是 Capture the flag 的縮寫,代表著一種類似古典flash密室逃脫小遊戲的競賽機制。在 Ethereum 的語境中,則是以「你能找出這份 smart contract 中有什麼漏洞嗎?」作為核心,讓參賽者找出合約中的問題,進而讓合約脫離正常的執行流程,取得所謂的”flag”。 — — Jerry Ho
如果想朝獎品邁進,可以搜尋 “Solidity”, “Smart contract” 等關鍵字;如果想多加了解區塊鏈,可以前往台北以太坊社群。
如果我的文章有幫助到你,可以看看我的其他文章,歡迎大家一起交流 :)