ERC20短地址攻擊
今天重看USDT合約的代碼,在BasicToken里有如下代碼
modifier onlyPayloadSize(uint size) {
require(!(msg.data.length < size + 4));
_;
}
function transfer(address _to, uint _value) public onlyPayloadSize(2 * 32) {
// ......
}
}
modifier onlyPayloadSize是確保payload是68,意思是前4字節(jié)函數(shù)選擇器(函數(shù)簽名),后面兩個(gè)參數(shù)每個(gè)占32字節(jié),一共是4+32+32=68字節(jié),必須是滿足這個(gè)長度。詳見如下表:
| 部分 | 含義 | 長度(字節(jié)) |
|---|---|---|
| ① | 函數(shù)選擇器(keccak256("transfer(address,uint256)") 前4字節(jié)) |
4 |
| ② | _to 參數(shù)(address,占 32字節(jié)槽,右對齊,左補(bǔ)零) |
32 |
| ③ | _value 參數(shù)(uint256,占 32字節(jié)) |
32 |
| 合計(jì) | — | 68 字節(jié) |
然后,這個(gè)是為了預(yù)防所謂的短地址攻擊。
具體短地址攻擊手法:
1、攻擊者構(gòu)造了0x1111111111111111111111111111111111111100地址,并掌握私鑰。
2、攻擊者故意將0x11111111111111111111111111111111111111作為第一個(gè)參數(shù) _to,然后第二個(gè)參數(shù) _value正常傳個(gè)金額,比如00000000000000000000000000000000000000000006765c793fa10079d0000000
3、將上述三個(gè)部分組裝成 calldata傳給一個(gè) 有缺陷的服務(wù),這個(gè)服務(wù)提交給EVM執(zhí)行的時(shí)候,會按照如下方式進(jìn)行參數(shù)提取,前4字節(jié)不變,_to參數(shù)會提取0x1111111111111111111111111111111111111100,但是結(jié)尾的“00”實(shí)際上是截取的 _value參數(shù)的最開頭的“00”,然后提取 _value的時(shí)候因?yàn)榍斑叡唤厝×恕?0”會發(fā)現(xiàn)少了1個(gè)字節(jié),所以會在右側(cè)自動補(bǔ)齊“00”,最后 _value變成了000000000000000000000000000000000000000006765c793fa10079d000000000,相當(dāng)于16進(jìn)制左移了兩位,變大了256倍!
4、這樣攻擊者成功的提取了256倍的金額到0x1111111111111111111111111111111111111100地址!
浙公網(wǎng)安備 33010602011771號