以太坊智能合约安全入门了解一下(下) – omnispace的博客

By admin 2019年1月11日

作者:RickGray
作者视频博客:

(注:本文分为两分配。,第第一环节是在E中引入智能和约防护。 接上篇

3. Arithmetic Issues

算术?大抵。,在节目言语中,由算术惹起的漏出物发展变为。,完整的洋溢被分为洋溢和下溢。。完整的洋溢的规律实则很简略。,嗨以 8 无打手势完整的,8 位完整的可以用第一视野来表现[0, 255]255将一转眼内存的齐式内在内存中(左下):

8 位无打手势完整的 255 收回通告说话中肯 8bit 投资,授权添加 1 因搬运,总数特许市翻转。 0,终极理由原型。 8bit 表现的完整的变为 0.

授权是 8 位有打手势完整的,它可以在视野内表达。[-128, 127]127将一转眼内存的齐式内在内存中(左下):

嗨,因高位是打手势位。,当 127 附带阐明 1 时,因进位打手势位变为1(使无效),因打手势位已转为1,经过回复左右消极的,终极买到8有完整的完整的。-128

从一边至另一边两个是完整的洋溢的说教故事。,同完整的下溢(英)8)0-1=(英)8)255(int8)(-128)-1=(int8)127

在 撤回(尤指)应变量先经过。询问(过剩的) - _amount > 0)确保账户有十足的结平移动。,随后经过让(数额) 来移动 Ether,鞋楦同辈人化用户结平知。这段密码若是第一缺少无论什么防护编码发现的人来审计,密码的逻辑处置使泛滥如同看不到无论什么PR。,在另一方面,授权编码经验或防护学习人员看它。,显然有第一完整的洋溢反省漏出物。。

在 Solidity 中 uint默许是 256 位无打手势完整的,代表视野[0, 2**256-1],在上面的示例密码中,人们经过做出意见分歧来断定抵消。,授权进入_amount大于存款结平,则 balances[] - _amount它将大于完整的下溢。 0 环绕授权断定,鞋楦的移动大于用户的抵消。 Ether,同辈人化后的结平能够是十分大的数量。。

pragma solidity ^0.4.10;

contract MyToken {
    mapping (地址) => 尤因) balances;

    function balanceOf(地址) 用户) returns (尤因) { return 结平〔用户〕 }
    function deposit() payable { balances[] +=  }
    function 撤离 总计) {
        询问(过剩的) - _amount > 0);  // 在完整的洋溢
        让(数额);
        balances[] -= _amount;
    }
}

简易学术语演示:

把持由前述的密码惹起的完整的洋溢,授权断定可反倒询问(过剩的) > 总计),这将不获得算术运算的逻辑断定。,在必然程度上把持了完整的洋溢。。

Solidity 以及简略的算术运算外,还会产生完整的洋溢。,死气沉沉的内幕的的一部分编码详述的境遇必要睬。,细微洋溢能够理由完整的洋溢,理由终成泡影。:

  • 阻碍 length 为 256 位无打手势完整的,心细对  或许 巧妙地把持洋溢反省;
  • 公共流通变量for (var) i = 0; i < items.length; i++) ... 中,i 为 8 位无打手势完整的,当 items浓厚的大于 256 时,能够形成 i不克不及完整遍历值洋溢。;

和约完整的洋溢漏出物否认稀薄的。,您可以检查数个新近的完整的洋溢事情。:象征性的制定木瓜。,易趣网说话中肯六角形洋溢漏出物比狗多。,《Solidity合约说话中肯完整的防护成绩——SMT/BEC合约完整的洋溢解析》

阻止完整的洋溢,一方面,它可以在算术逻辑前后停止使有法律效力。,在另一方面,它可以坦率地应用。 OpenZeppelin 一套智能和约应变量库SAFEMATH处置算法。

4. Unchecked Return Values For Low Level Calls

不严格的断定不防护应变量理由的现场恢复值。,这种典型的软弱性性质上是罚款投合心意的。,在后面讲 Reentrancy 实际上,它也归结起来在BOT中理由现场恢复值的成绩。。鞋楦总结了SEV的现场恢复值和非常处置。,让我再看一遍。 3 根底理由call()delegatecall()callcode() 和 3 钱币转变应变量()()send()transfer()

- call()

call() 用于 Solidity 外国的大声喊,像,理由救济院内的盟约应变量

.call(bytes4(keccak("somefunc(params)"), 帕拉姆斯),救济院内的理由 call() 现场恢复第一 bool 值以命令救济院内的理由条件成。:

- delegatecall()

以及 delegatecall()救济院内的密码将坦率地受到和约语境的情绪反应。,剩余部分及call() 划一,同一的方法亦鞋底的方法。 bool 值以命令理由成寂静终成泡影(非常产生)。。

- callcode()

callcode() 实则是 delegatecall()先前的版本,二者都将救济院内的密码培养到涌现语境中停止获得。,在另一方面在  和 但标的目的上在意见分歧。。

像 Alice 经过 callcode() 理由了 Bob 同时在和约中delegatecall() 了 Wendy 和约说话中肯函数,它能够自然啦转移。,请看上面的密码。:

授权你依然完全不懂callcode() 与 delegatecall() 的分别,你可以把上面的密码放出来 remix-ide 救济院内的测量法。,注意两种呼叫方法。 和 上意见分歧。

- ()()

和约坦率地启动 TX 内幕的第一功用(相当双骰子游戏),

- send()

经过 send()应变量发送 Ether 坦率地现场恢复终成泡影 false;嗨要睬的一件事是,send() 的目的授权是合约账户,人们会尝试称之为。 fallbcak() 应变量,fallback() 应变量获得终成泡影,send()它只会靠背。 false。但它只会做准备。 2300 Gas 给 fallback() 应变量,因而可以防重入漏出物(歹意反复理由)。

- transfer()

transfer()它也可以启动。 Ether 买卖,但与send() 要求的的时,transfer()这是一种更防护的转变巧妙地把持。,当发送终成泡影时,个人财产将必然发生的回滚。,应变量理由不现场恢复值。。同一的,授权 transfer() 的目的是合约账户,和约也将被征引。 fallback() 应变量,它只会过来。 2300 Gas 用于 fallback() 应变量获得,可以阻止重行进入漏出物(歹意反复理由)。

上面是第一简略的先例来阐明严格的使有法律效力的显著。:

functionwithdraw(uint256_amount)public{require(balances[msg.sender]>=_amount);balances[msg.sender]-=_amount;etherLeft-=_amount;msg.sender.send(_amount);// 未使有法律效力 send() 现场恢复值,若  为合约账户 fallback() 理由终成泡影,则 send() 现场恢复 false}

前述的提到的钱币审核被应用。send()转账功用,因缺少使有法律效力。send() 现场恢复值,授权 为合约账户 fallback() 理由终成泡影,则 send() 现场恢复 false,终极,账户结平缩减了。,杜撰并缺少接收它。。

助动词=have这么的成绩,你可以对君主有第一详述的的知。 of the Ether。

5. Denial of Service - 拒绝服务

DoS 普遍存在,在 Solidity 李亦,这否认是第一拒绝服务的漏出物。 不成回复歹意巧妙地把持或受约束的无限的资源CONSUM。立刻,它是作包工乙醚专题讨论会。 DoS 袭击,能够理由 Ether 和 Gas 的浓厚的耗费,更严肃的的是,原始和约密码逻辑不起作用。。

上面是第一先例。 DASP 探察):

pragma solidity ^0.4.10;

contract PresidentOfCountry {
    address public president;
    uint256 price;

    function PresidentOfCountry(英)256 价钱) {
        询问(价钱) > 0);
        price = _price;
        president = ;
    }

    function becomePresident() payable {
        require( >= 价钱) // must pay the price to become president
        president.transfer(价钱)   // we pay the previous president
        president = ;      // we crown the new president
        price = price * 2;           // we double the price to become president
    }
}

第一简略的类比。 KingOfEther 的合约,范围和约的标准逻辑,无论什么牌价高于CU。price它可以变为新的。 president,原和约说话中肯押金将退还给上一人。 president,这亦在嗨应用的。transfer() 来停止 Ether 转账,看起来缺少成绩的逻辑,但别忘了。,在以太网中有两种典型的存款。,授权启动becomePresident() 理由的是个合约账户,成了。 president,授权其 fallback() 应变量歹意获得相像的人revert()积极分子停止逆巧妙地把持。,到这程度剩余部分账户将无法标准运转。 becomePresident 逻辑变为 president 了。

简略袭击密码列举如下:

contract Attack {
    function () { revert(); }

    function Attack(地址) 目的) payable {
        _target.()(bytes4(keccak256("becomePresident()")));
    }
}

应用 remix-ide 模仿袭击审核:

6. Bad Randomness - 可预测随机处置

伪随机成绩一向取决于同辈人计算系统中。,但在开断链,写随机数字为根底的处置逻辑自然啦不切实际。,因全世界都可以增长链上的通知。,和约中内存的通知可以在链上停止查询和剖析。。授权和约密码缺少严格的思索通知泄露成绩,它能够被袭击者歹意地应用。 “做手脚”。

摘自 DASP 的密码块:

uint256privateseed;functionplay()publicpayable{require(msg.value>=1ether);iteration++;uintrandomNumber=uint(keccak256(seed+iteration));if(randomNumber%2==0){msg.sender.transfer(this.balance);}}

嗨 seed变量被特征为公有变量。,不少于后面提到的,链上的通知都是公诸于众的。,seed意义可以经过扫描与和约相干。 TX 接收。获取 seed后值,同一的 iteration左右值亦可购得的的。,因而总数KECAK256(种子) + 迭代) 的值执意可预测的了。

就 DASP 外面提到的,死气沉沉的内幕的的一部分合约爱情用 (英) 闭塞数) returns (bytes32)获取随机散列。,但不要在嗨应用。也执意说,涌现块号。blockNumber 的值,因它很清晰度地写在公务的用纸覆盖中。:

(英) 闭塞数) returns (bytes32): hash of the given block - only works for 256 most recent blocks excluding current

意义是说 ()最好的应用近 256 接收块的块号。 Hash 值,它还重读涌现块以前的男朋友或女朋友在内。,授权应用涌现块计算()结出果实始终0x0000000.....

同一不克不及应用。now 这些可以由运煤船把持的值来获取随机数字。

一切的链上的通知都是公诸于众的,破旧的接收第一可靠的人的随机数字。,应用链上的通知如同相当英〉硬海滩。,嗨是第一孤独的记入项主词设计。 Smart Contract 与互联网网络合作,感兴趣的先生可以更多地知它。。(附件是本 Oraclize 随机数字的获取方法

7. Front Running - 超前买卖

“超前买卖”,实际上,在习得智能和约漏出物在前,我还不发生这种典型的漏出物或袭击方法(归根到底,我)。简略来说,“超前买卖”执意重要的人物提早获取到买卖者的详细买卖知(或许相干知),在买卖者使臻于完善巧妙地把持在前。,骑马队伍办法,通常进步出价,被用来使臻于完善T。。

都在以太专题讨论会。 TX 它们都必要身份证明才干完整记载着陆。,每一笔 TX 接受相干费都是需要的。,并且费的多多少少也决议了笔。 TX 运煤船含蓄的分清,高额经纪费 TX 将率先接收识别。,每一笔待身份证明的 TX 在播送到互联网网络过后,你可以主教权限买卖的详述的境遇。,使担忧和约理由的内幕的的一部分详述的方法和限制因素可以是。很明显。 Front-Running 有隐患。,示例密码不见得被破除。,蜿蜒(图像):

你可以主教权限它还缺少被证明。 TX,并可以检查相干通知。:

自然。,为了阻止明纸内存的知 TX 中,你可以编密码和署名通知。

8. Time Manipulation

工夫伪造(DASP) 供给的决定是十分转移的。 XD),显而易见,接受与工夫相干的漏出物都可以分级。 “Time Manipulation”。在 Solidity 中,(别号)now它由运煤船把持。,也执意说,内幕的的一部分和约依靠于这是被袭击和应用的双骰子游戏。,当袭击者有机会变为一名运煤船。 TX 身份证明时,鉴于  可以把持,内幕的的一部分依靠此际的和约密码是已知的结出果实。,袭击者可以选择第一一直的值来获得他的目的。。自然。 该值通常具有必然的值视野。,块步是有规则的。 XD)

我还缺少找到第一罚款的先例。,因而嗨缺少演示密码。。:)

  1. Short Address Attack - 短地址袭击 当我动手测量法和重现和约漏出物的典型时,我还没能处理短地址袭击。 remix-ide 实验成。,你为什么缺少成?。即使漏出物缺少接收回复,但我寂静主教权限了漏出物。,嗨详述的阐明了短地址的软弱性规律。。

率先,人们应用救济院内的理由。call() 为例,救济院内的理由 的境遇:

在 remix-ide 中心机构在和约上签名并叫来。callFunc() 时,您可以接收日记出口。 值:

0x4142c000000000000000000000000000000000000000000000000000000000000000001e

内幕的 0x4142c000救济院内的理由的应变量名的决定。 4 个八位位组(bytes4(keccak256("foo(英)32,乔治英国数学家和逻辑学家()),后方 32 八位位组是使分娩的限制因素值。, 全部地为 4 八位位组应变量署名加 32 八位位组限制因素值,总共 4+32 八位位组。

见以下和约密码:

pragma solidity ^0.4.10;

contract ICoin {
    address owner;
    mapping (地址) => uint256) public balances;

    modifier OwnerOnly() { require( == owner); _; }

    function ICoin() { owner = ; }
    function approve(地址) _to, uint256 总计) OwnerOnly { 结平〔至〕 += _amount; }
    function transfer(地址) _to, uint256 总计) {
        询问(过剩的) > 总计);
        balances[] -= _amount;
        结平〔至〕 += _amount;
    }
}

确定的象征性的功用和约 ICoin,当 A 会计师导向 B 转账到象征性的transfer() 应变量,像 A 账户(0x14723a09acff6d2a60dcdf7aa4aff308fddc160c)向 B 账户(0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db)转 8 个 ICoin,通知用于:

0xa9059cbb  -> bytes4(keccak256("transfer(地址),uint256)")) 应变量署名
0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db  -> B 存款地址(预添补) 0 补齐 32 八位位组)
0000000000000000000000000000000000000000000000000000000000000008  -> 0x8(预补苴) 0 补齐 32 八位位组)

这么,短地址袭击是健康状况如何做到这点的呢?,袭击者找到了一面之词。00 账户地址,推测为 0x4b0897b0513fdc7c541b6d9d7e929c4e5364d200,在标准境遇下,总数理由 一定为:

0xa9059cbb  -> bytes4(keccak256("transfer(地址),uint256)")) 应变量署名
0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d200  -> B 存款地址(正文完毕) 00)
0000000000000000000000000000000000000000000000000000000000000008  -> 0x8(预补苴) 0 补齐 32 八位位组)

在另一方面授权人们缺少的事 B 地址的 00 偷窃,不停止使分娩,也执意说,人们送更少。 1 八位位组多样4+31+32

0xa9059cbb  -> bytes4(keccak256("transfer(地址),uint256)")) 应变量署名
0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2  -> B 地址(31) 八位位组)
0000000000000000000000000000000000000000000000000000000000000008  -> 0x8(预补苴) 0 补齐 32 八位位组)

涌现述的通知进入 EVM 加工作时间,将织网蜘蛛整流限制因素注册的成绩。00 变为:

0xa9059cbb
0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d200
0000000000000000000000000000000000000000000000000000000000000800

也执意说,歹意坚信礼 经过 EVM 解析补码 0 巧妙地把持,理由本来 0x8 = 8 变为了 0x800 = 2048

前述的 EVM 畸变八位位组 停止补位巧妙地把持的行动实则执意短地址袭击的规律(但嗨我真的缺少复现成,我缺少第一成的先生会和我接触人。。

短地址袭击通常产生在体式逆的地址中。,如买卖所提币、金库转账,到这程度,以及写和约,人们还必要严格的反省CORR。,并且在 Off-Chain 事情功用还必要使有法律效力用户的输出地址体式。,阻止短地址袭击的产生。

同时,外人有绍介。 [剖析] the ERC20 Short Address Attack () 定冠词很有意义,值当我习得。。

- Unknown Unknowns - 剩余部分未知,:) 未知漏出物,没什么可说的。,为了尾随 DASP 要坚持不渝。

III. 单一的认真思考

前后消耗 2 周屡次看呀艾方智能知相干知,俗人无 0 到 1 这种感触又靠背了。。不多。,我一定变为AI和约防护和约的出发点。,近期也涌现了内幕的的一部分和约漏出物。,剖析和反复也使臻于完善了。 OK 的,软弱性学习的原始的缺少改观。,这只不过第一标的目的。。等待与更多的块链SCORI表明和习得。

1. 以太坊中合约账户的私钥在哪?可以不经过合约账户密码坦率地巧妙地把持合约账户说话中肯 Ether 吗?

StackExchange 使担忧成绩的答案是:在哪里? is the private key for a contract stored?”,但我终极缺少主教权限公务的的答案。。但你只发生,合约账户是由摆设时的合约密码把持的,不可靠条件有私钥可以坦率地把持合约停止 Ether 相干巧妙地把持(不一定做结论)。

2. 应用 keccak256() 应变量署名的坑? 限制因素因未到庭而败数字特征

在应用 keccak256 用商议应变量署名限制因素时,应睬限制因素典型的要求数量。,如:

functionsomefunc(uintn){...}

当签字前述的功用时,规定了工夫限制因素典型。uint,而 uint默许是 256 位,也执意 uint256,因而签名时一定是keccak256("somefunc(英)256)"),不要写它。keccak256("somefunc(尤因)")

商议关系:

#special-variables-and-functions
https://github.com/oraclize/ethereum-api

发表评论

电子邮件地址不会被公开。 必填项已用*标注