Page 381 - 《软件学报》2025年第12期
P. 381

5762                                                      软件学报  2025  年第  36  卷第  12  期


                 数将根据状态变量判断当前合约状态是否满足分支的条件约束                      [15,31] . 因此, 若仅符号化执行控制流图中可到达目
                 标语句的基本块, 缺少相关变量的符号约束, 将无法满足目标语句所在分支的条件约束, 使符号执行错误判断路径
                 的可达性, 影响对目标语句的安全漏洞检测.
                    本文将影响目标语句可达性判断的语句称为目标依赖语句, 接下来将以图                         1  中第  72  行的整型溢出漏洞为例,
                 具体描述利用符号执行对智能合约进行安全漏洞检测的具体过程, 以及目标依赖语句的作用.
                                       T  的过程中, 会收集变量的符号约束. 当存在漏洞模型预定义的操作时, 将在路径条件
                    在符号化执行事务序列
                 中添加相应的漏洞检测符号约束, 如图            1  中在第  72  行进行加法运算前添加符号约束         ¬(a+v > a). 如果事务序列   T
                 执行语句的路径条件约束求解的结果为可满足, 则该事务序列中存在整型溢出漏洞, 约束求解的结果可以作为复
                 现该漏洞的测试用例.
                    若仅将漏洞语句作为目标, 由于漏洞语句位于函数                transferFrom
                                                                      中, 因此事务序列    T only  可表示为:
                                               T only = {init,transferFrom(p 1 , p 2 , p 3 )},
                 其中,  p 1 、  p 3  分别表示参数_from、_to                       T only 执行语句的路径条件S only  展开可得:
                         p 2  和                    和_value 的符号化表示. 将
                                              ′
                                                         ′
                                   S only = balances = 0∧allowed = 0               (s1)
                                                [ ]
                                                  ′
                                       ∧balances p 1 ⩾ p 3                          (s2)
                                              [ ][                       ]
                                                                          ′
                                       ∧allowd p 1 sender(transferFrom(p 1 , p 2 , p 3 )) ⩾ p 3  (s3)
                                       ∧ p 3 > 0                                   (s4)
                                                 [ ]            [ ]
                                                                   ′
                                       ∧¬(balances p 2 + p 3 > balances p 2 )       (s5)
                                                    ′
                 其中, s1  为第  41  行和第  42  行对合约状态变量的初始化, s2–s4    为第  71  行的  require 语句判断条件, s5  则为整型溢
                                  S only  可以看出, 由于  s1、s2  和  s4                           S only  无法满足, 导
                 出漏洞的检测条件. 从                                无法同时满足, 因此约束求解器将判断
                 致符号执行未能检测出整型溢出漏洞.
                    若将漏洞语句作为目标的同时, 定位与其存在依赖关系的其他语句, 补充事务序列以添加相关变量的符号约
                 束, 能够更准确地判断路径可达性. 从图           1  可以看出, 第  72  行目标语句受到第     71  行分支语句的控制, 分支语句读
                 取了变量   balances 和  allowed, 第  79  行  (位于  mint 函数) 和第  90  行  (位于  approve 函数) 分别对这两个变量进行赋
                 值. 将这  2  个函数作为事务序列     T only  的补充, 可得到由  mint、approve 以及  transferFrom  共  3  个函数调用所组成的
                 事务序列. 当事务序列的长度限制为           3  时共有  3 = 27 种组合方式, 其中一种事务序列       T sv  为:
                                                     3

                                      T sv = {init,mint(p 4 ),approve(p 5 , p 6 ),transferFrom(p 1 , p 2 , p 3 )},
                 其中,  p 4  为函数  mint 的参数  amount 的符号化表示,   p 5  和  p 6  为函数  approve 的参数_spender 和_value 的符号化表
                 示. 将  T sv 执行语句的路径条件S sv  展开可得:

                                       ′
                            S sv = balances = 0∧allowed = 0                              (s1)
                                                  ′
                                                                                           +
                                ∧ p 4 ⩾ 0∧ sender(mint(p 4 )) = owner ′                  (s2 )
                                         [            ]            [            ]
                                                                                           +
                                                                                 ′
                                ∧(balances sender(mint( p 4 )) + p 4 > balances sender(mint(p 4 )) )  (s3 )
                                                       ′
                                        [             ]        [             ]
                                                                                           +
                                                                             ′
                                ∧balances sender(mint(p 4 ))  ′′  = balances sender(mint( p 4 )) + p 4  (s4 )
                                           ′            ′          ′′         ′            +
                                ∧(totalSupply + p 4 > totalSupply )∧totalSupply = totalSupply + p 4  (s5 )
                                        [                 ][ ]
                                                                                           +
                                                              ′                          (s6 )
                                ∧allowed sender(approve(p 5 , p 6 )) p 5 = p 6
                                        [ ]
                                           ′
                                ∧balances p 1 ⩾ p 3                                      (s2)
                                       [ ][                       ]
                                                                   ′                     (s3)
                                ∧allowd p 1 sender(transferFrom(p 1 , p 2 , p 3 )) ⩾ p 3
                                ∧ p 3 > 0                                                (s4)
                                          [ ]            [ ]
                                                            ′
                                ∧¬(balances p 2 + p 3 > balances p 2 )                   (s5)
                                             ′
                                T sv  在  transferFrom  前执行了  mint 和                             +  s6  共 +  5
                    由于事务序列                                  approve 函数, 因此在  S only  的基础上, 新增了  s2  –
                 条路径条件, 添加了      balances 和  allowed  的符号约束, 使  S sv  可以满足, 即检测出整型溢出漏洞. 经约束求解, 可得
                                                                            (
                   S sv  的一个可满足解为:   mint(p 4 ) 的调用者为  owner,   2 255  −1 approve p 5 , p  )  的调用者为  owner,  p 5  为任意
                                                                     ;
                 到                                         p 4  为               6
                 地址,  p 6  为大于  0  的整型数值;  transferFrom(p 1 , p 2 , p 3 ) 的调用者为   p 5 p 1  和  p 2  为  owner,   p 3  为  p 6 .
                                                                     ,
   376   377   378   379   380   381   382   383   384   385   386