Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
[Crypto in CTF] Blockchain Security
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
oalieno
October 31, 2020
Technology
440
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
[Crypto in CTF] Blockchain Security
https://github.com/oalieno/Crypto-Course/tree/master/Blockchain
oalieno
October 31, 2020
More Decks by oalieno
See All by oalieno
[Crypto in CTF] Classical Cipher
oalieno
0
490
[Crypto in CTF] Block Cipher Mode
oalieno
0
1.1k
[Crypto in CTF] HASH
oalieno
0
300
[Crypto in CTF] LFSR
oalieno
0
530
[Crypto in CTF] RSA
oalieno
0
760
[Crypto in CTF] Bleichenbacher RSA Signature Forgery
oalieno
0
640
滲透測試基本技巧與經驗分享
oalieno
2
1.2k
Other Decks in Technology
See All in Technology
AI 不只幫你寫 Code: 當專案從 300 暴增到 1500, 我們如何撐住 DevOps
appleboy
0
120
SteampipeとExcel Power QueryでAWS構成定義書の作成を自動化する
jhashimoto
0
170
20260619 私の日常業務での生成 AI 活用
masaruogura
1
240
ザ・データベース、MySQL ~ OSC 2026 Sendai ~
sakaik
0
170
千葉での単身赴任からAWSをやり続け、千葉に戻ってきた話
yama3133
1
100
ロボティクスの技術 / Robotics Technology
ks91
PRO
0
120
SONiCの統計情報を取得したい
sonic
0
270
秘密度ラベル初心者が第1歩でつまづかないための「設計・運用」ポイント
seafay
PRO
1
420
AI-DLCを “そのまま導入しなかった”話 ~組織に合わせてアジャストした 私たちの実践共有~
hiroramos4
PRO
1
370
AI時代のコスト管理を考えよう〜明日から使える実践AWSノウハウ~
yoshimi0227
0
750
Agile and AI Redmine Japan 2026
hiranabe
3
430
iOS アプリの「これって不具合ですか?」を AI に調べてもらう
miichan
0
130
Featured
See All Featured
AI: The stuff that nobody shows you
jnunemaker
PRO
8
730
Are puppies a ranking factor?
jonoalderson
1
3.6k
My Coaching Mixtape
mlcsv
0
150
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
270
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
It's Worth the Effort
3n
188
29k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.5k
A Soul's Torment
seathinner
6
3k
BBQ
matthewcrist
89
10k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.1k
For a Future-Friendly Web
brad_frost
183
10k
Leo the Paperboy
mayatellez
7
1.9k
Transcript
Blockchain Security oalieno
Introduction to Blockchain
Blockchain A → B $3 C → A $2 ⋮
• 去中⼼化的記帳本 • 去中⼼化:⼤家都有⼀份⼀模⼀樣的記帳本備份 • 記帳本:記錄誰給誰多少錢 A → B $3 C → A $2 ⋮ Alice Bob
Blockchain • Alice 要給 Bob 1 塊錢 • 記錄⼀筆交易,並廣播給其他所有⼈ A
→ B $3 C → A $2 ⋮ A → B $3 C → A $2 ⋮ Alice Bob A → B $1
Blockchain • Bob 可以偽造⼀筆交易,廣播給所有⼈ A → B $3 C →
A $2 ⋮ A → B $3 C → A $2 ⋮ Alice Bob A → B $100
Blockchain • 因此每⼀筆帳必須簽章 • 將錢從 A 轉出去的帳,要有 A 簽章才有效 A
→ B $3 C → A $2 ⋮ A → B $3 C → A $2 ⋮ Alice Bob A 簽章 C 簽章 C 簽章 A 簽章
Blockchain • 但是就算有簽章,Bob 可以輕易的複製同⼀份交易再廣播出去 A → B $3 C →
A $2 ⋮ A → B $3 C → A $2 ⋮ Alice Bob A 簽章 C 簽章 C 簽章 A 簽章 A → B $3 A 簽章
Blockchain • 所以簽章的內容必須包含⼀個 id 或 timestamp 之類的 TX 0 :
A → B $3 TX 5 : C → A $2 ⋮ TX 0 : A → B $3 TX 5 : C → A $2 ⋮ Alice Bob A 簽章 C 簽章 C 簽章 A 簽章
如何達成共識 • ⼤家都在廣播交易 • 怎麼決定誰先誰後,並保證⼤家的記帳本都長得⼀樣? TX 0 : A →
B $3 TX 5 : C → A $2 ⋮ TX 0 : A → B $3 TX 5 : C → A $2 ⋮ Alice Bob A 簽章 C 簽章 C 簽章 A 簽章 TX 6 : A → B $1 TX 6 : B → C $1 A 簽章 B 簽章
誰有記帳權 • ⼤家決定出⼀個⼈來記帳 • 每次會記好幾個交易的帳,稱為⼀個區塊 ( Block ),不會只記⼀個交易 • 先算出哪個
Nonce 會讓整個 Block 的 Hash 開頭是 0x00 的⼈記帳 TX 0 : A → B $3 TX 5 : C → A $2 ⋮ A 簽章 C 簽章 Nonce 0x1234 Hash 0x00abcd Alice
誰有記帳權 • 要 Hash 的東⻄包括前⼀個 Block 的 Hash,形成⼀連串的 Block Chain
• 並且記帳的⼈能獲得獎勵,所以⼤家都會搶著記帳 TX 0 : A → B $3 Reward A $10 ⋮ A 簽章 Nonce 0x1234 Hash 0x00abcd Hash of Previous Block Alice
Blockchain TX 0 : A → B A 簽章 TX
5 : C → A C 簽章 Hash of Block 0 ⋮ TX 0 : B → D B 簽章 TX 7 : A → C A 簽章 Hash of Block 1 ⋮ Hash Hash Block 1 Block 2 Nonce Nonce
分岔 ( fork ) • 剛好兩個⼈都算出正確的 Nonce 挖出區塊怎麼辦 • 看誰的鍊比較長誰就是主鏈
Block 2 Block 2 Block 3 Block 4 Block 1
51% 攻擊 • 當某個礦⼯有全網 51% 以上的算⼒,那他挖的那條鏈就會是最長鍊 • 他可以故意排除或竄改交易順序 • 但因為有簽章,所以他還是不能亂轉他沒有的錢,也不能憑空⽣錢
• 2018 年 5 ⽉,Bitcoin Gold ( BTG ) 就被 51% 攻擊了,損失 1800 萬美⾦
51% 攻擊 • 先轉帳 $1000 到⽬標交易所 • 等 10 個區塊
confirmation 後,交易所認可該筆交易 • 駭客便可以將錢從交易所領出來換成法幣 Block 2 Block 11 Block 1 ... Block 2 Block 11 ... Block 12 轉帳到交易所 沒有轉帳到交易所
51% 攻擊 • 同時間,駭客⽤他的 51% 算⼒偷偷算更長的⼀條鍊 • 該條鏈裡⾯沒有他轉帳到交易所的那筆交易 • 等他從交易所領出錢錢後,就把更長的鏈廣播給⼤家
• 這樣他的幣還在,同時⼜領了法幣出來,直接翻倍 Block 2 Block 11 Block 1 ... Block 2 Block 11 ... Block 12 轉帳到交易所 沒有轉帳到交易所
POW / POS / DPOS • ⽬前主流有三種不同的⽅式決定記帳權 • Proof of
Work ( PoW ) • 透過計算⼀個複雜的問題來獲得記帳權 • Bitcoin ( BTC ), Ethereum ( ETH ), … • Proof of Stake ( PoS ) • 持幣數量越多的越有機會獲得記帳權 • Delegated Proof of Stake ( DPoS ) • 所有節點選舉出幾個超級節點來記帳 • 還有很多變種的 PoS 機制...
Ethereum
錢包 • 冷錢包 ( 硬體錢包 ) : 要交易的時候再插進電腦裡 • Ledger,
Trezor 等 • 熱錢包 ( 軟體錢包 ) : 瀏覽器插件,或是 APP 之類的 • MetaMask, Trust Wallet 等
Ethereum Ropsten Network • 上課主要都是在 ropsten 測試網路中進⾏ • 不是真錢啊 •
要錢錢可以去下⾯幾個 faucet 領 • https://faucet.metamask.io/ • https://faucet.dimensions.network/ • https://faucet.ropsten.be/
Ethereum Address • Ethereum 的 Address 是把 public key 做
keccak256 之後再取後 20 bytes • 所以 private key 跟 address 是⼀對⼀的關係 • keccak256 就是 sha3 原本的名字,但是參數跟⽬前的 sha3 有點不同
Ethereum Virtual Machine ( EVM ) • 以太坊 ( Ethereum
) 除了存放交易們,還可以存放程式碼 • Ethereum Virtual Machine ( EVM ) • 去中⼼化的虛擬機 • 圖靈完備
智能合約 ( Smart Contract ) • ⼀個智能合約就像是⼀個物件導向中的 Class • 使⽤者可以創建智能合約,也就是存放程式碼到
Ethereum 上⾯ • 然後跟智能合約互動,也就是呼叫合約中的函式 • 智能合約的位址跟普通錢包的位址是在同⼀個空間 pragma solidity ^0.5.0; contract test { uint data; constructor () public payable { data = 1; } function money () public { msg.sender.transfer(1 ether); } }
Solidity • 存在 Ethereum 的其實是 bytecode,類似於 assembly code • Solidity
是⾼階的語⾔,透過編譯器編譯成 bytecode • 除了 Solidity 之外,還有另⼀種⾼階語⾔叫 Vyper • Solidity 語法類似 javascript,Vyper 語法類似 python
bytecode https://ethervm.io/ 0x608060405234801561001057600080fd5b5060043610610... PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1
ISZERO PUSH2 0x0010 JUMPI PUSH1 0x00 ...
Gas https://txstreet.com/ • 在 EVM 上⾯執⾏ bytecode 是要付費的 • 每個不同的
opcode 都會花費不同的 gas fee • 比如 ADD 會花費 3 gas • 那⼀個 gas 是多少錢?這是由交易發起⼈決定的 • 比如 gas price 設定成 10 gwei 的話,ADD 就會花費 30 gwei • Gas price 是給礦⼯的⼩費,給得越⾼你的交易能越快被驗證
單位 單位 價值多少 wei wei 1 kwei 1000 mwei 1000000
gwei 1000000000 twei 1000000000000 pwei 1000000000000000 ether 1000000000000000000 • 在 Ethereum 中最⼩單位是 wei
web3.js https://web3js.readthedocs.io/en/v1.3.0/ • Solidity 編譯成 bytecode 是放到 EVM 上執⾏的 •
可以看成後端 • 想要跟合約互動,我們在普通的電腦上⽤ web3.js • 可以看成前端 • 除了跟合約互動,web3.js 也可以查看 Ethereum Blockchain 上的資訊 • 也有 web3.py,就只是 python 版本的 • 還有另⼀個選擇是 ethers,號稱比 web3.js 更好⽤
Resources • Tutorial • cryptozombies • Online Judge • Ethernaut
• Security Innovation Smart Contract CTF • Vulnerabilities • DASP Top 10 • SWC Registry
Smart Contract
Visibility Modifier 名稱 外部 此合約 ⼦合約 public ✓ ✓ ✓
private ✓ internal ✓ ✓ external ✓
State Modifier 名稱 保證沒有寫入 storage 保證沒有讀取 storage view ✓ pure
✓ ✓
Custom Modifier contract Test { address private owner; modifier onlyOwner()
{ require(msg.sender == owner); _; } function setOwenr(address _owner) onlyOwner public { owner = _owner; } function getOne() pure { return 1; } function getOwner() view returns(address) { return owner; } }
Underflow / Overflow function withdraw(uint _amount) public { require(balances[msg.sender] -
_amount > 0); msg.sender.transfer(_amount); balances[msg.sender] -= _amount; } • uint 往下減會 underflow • uint 其實就是 uint256,256 bits = 32 bytes • uint 的 0 往下減會變成 2256 - 1
Safemath function withdraw(uint _amount) public { require(balances[msg.sender].sub(_amount) > 0); msg.sender.transfer(_amount);
balances[msg.sender] = balances[msg.sender].sub(_amount); } • 使⽤ OpenZeppelin 寫好的 SafeMath.sol 函式庫 • 幫你安全的處理 uint 的加減乘除
Random Number • 在 EVM 中基本上沒辦法產⽣安全的 random number • 能⽤的隨機來源只有
block.timestamp, block.difficulty , block.blockhash • 但是像下⾯這個例⼦,只要部署另⼀個合約,呼叫前計算⼀下,就可以 算出⼀樣的隨機數了,因為在同⼀個 block • ⽬前最好的⽅法還是呼叫外部的中⼼化伺服器來取得隨機數 function dice() public payable { if (block.timestamp % 2 == 1) { win = true; } }
呼叫合約函式 https://www.4byte.directory/ contract A { function test (uint value) public
{} } • 假設我們想要呼叫 A 合約的 test 函式 • 送⼀個交易給合約 A,data 欄位填該函式的 function siganture • function signature 是 keccak256('函式名稱(型態們)') 的前 4 bytes • 這個例⼦中就是 keccak256('test(uint)') 的前 4 bytes
Fallback / Receive contract Test { fallback () external payable
{} receive () external payable {} function normal_function () public {} } • fallback 和 receive 是兩個特殊的函式 • 有⼈呼叫合約,但 data 欄位是空的 • 就會執⾏ receive • 如果沒有 receive,就會執⾏ fallback • 如果 data 欄位提供的 function signature 沒有找到 match • 執⾏ fallback
Reentrancy Attack function withdraw(uint _amount) public payable { require(balances[msg.sender] >=
_amount); msg.sender.call{value: _amount}(""); balances[msg.sender] -= _amount; } • 當合約送錢給其他地址,該地址可能會是另⼀個合約 • 送錢給另⼀個合約,其實就是呼叫他的 receive / fallback • 那我們在 receive / fallback 裡⾯再去呼叫 withdraw ⼀次 • 因為 balances 還沒扣,所以第⼀⾏的 require 還是成立 • 就可以⼀直 transfer 把合約裡⾯的錢掏空
require / revert / assert • require, revert 會 refund
剩下的 gas fee • assert 會把剩下的 gas fee 都吃掉,不還你 modifier onlyOwner() { require(msg.sender == owner); _; } modifier onlyOwner() { if (msg.sender != owner) { revert(); } _; } modifier onlyOwner() { assert(msg.sender == owner); _; }
delegatecall https://swcregistry.io/docs/SWC-112#proxysol • delegatecall 跟 call ⼀樣可以呼叫另⼀個合約 • 但是他會使⽤原本合約的 storage
• 下⾯的例⼦中,callee 是惡意的話,可以接把 owner 改掉 contract Proxy { address owner; constructor() public { owner = msg.sender; } function forward(address callee, bytes _data) public { require(callee.delegatecall(_data)); } }
ERC20 https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol • ⼀個代幣的標準,只要 inheritance ERC20 合約,就可以發代幣 • 代幣是存在於合約上的 •
transfer 可以把⾃⼰的代幣轉給別⼈ • approve 可以授權別⼈花你的代幣 • transferFrom 可以花別⼈的代幣 function transfer(address _to, uint256 _value) returns (bool success) function transferFrom(address _from, address _to, uint256 _value) returns (bool success) function approve(address _spender, uint256 _value) returns (bool success)
ERC721 https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721 • 另⼀個代幣標準,也叫做 Non-Fungible Token ( NFT ) •
每個代幣都是獨⼀無⼆的,像是蒐集郵票⼀樣 • CryptoKitties 是 NFT 的⼀個著名的例⼦
None