Intelligent contract vulnerability detection method and system based on hybrid fuzzy test optimization

Through the combination of mixed fuzzy testing and symbolic execution, combined with pollution analysis techniques, the problem of high road explosion and high misunderstanding rate of smart contract vulnerability detection, and achieved effective exploration and detection of deep branch vulnerabilities of smart contracts, which has been comprehensively improved. The security of the contract.

CN119337385AActive Publication Date: 2025-01-21YANTAI UNIV

Patent Information

Application Number
CN202411845270.2
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2024-12-16
Publication Date
2025-01-21
Estimated Expiration
2044-12-16

AI Technical Summary

Technical Problem

The existing smart contract vulnerability detection technology has vulnerabilities that have explosive paths, high false alarm rates, and the inability to explore deep branches, especially under the immutability and special mechanism of blockchain, which leads to the incomplete guarantee of contract security.

Method used

Based on the method of optimization of hybrid fuzzy testing, a test case is generated through static analysis, combined with fuzzy testing and symbolic execution, and the stain analysis technology tracking data dissemination is used to set test prophecies to detect intelligent contract vulnerabilities such as detection permissions control, transaction order dependence, and rejection service.

Benefits of technology

It improves the code coverage, reduces the false positive rate, can effectively explore and detect deep branch vulnerabilities in smart contracts, and comprehensively improves the security of the contract.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN119337385A_ABST
    Figure CN119337385A_ABST
Patent Text Reader

Abstract

The invention relates to the technical field of network security and vulnerability detection, in particular to an intelligent contract vulnerability detection method and system based on hybrid fuzzy test optimization, and the method comprises the steps: carrying out the static analysis of compiled EVM byte codes, generating a first test case set, carrying out the fuzzy test, and introducing taint analysis to track the transmission of taints in an instruction stream; in the fuzzy testing process, according to the length change of the instruction counting set within the execution frequency threshold value, symbol execution processing is triggered when the length change value is 0, in the symbol execution processing process, a constraint cache reuse strategy is adopted to solve an obtained constraint expression, and a solving result is cached and reused, so that a fuzzy test result is obtained; a use case value reaching a complex branch can be quickly generated through symbolic execution and is fed back to the fuzzy engine to assist the fuzzy engine in exploring a new path to capture more deep vulnerabilities; and meanwhile, test predictions are designed for three intelligent contract vulnerabilities of authority control, transaction sequence dependence and denial of service, and vulnerability detection is more accurate.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention relates to the field of network security and vulnerability detection technology, and specifically to a smart contract vulnerability detection method and system based on hybrid fuzzy testing optimization. Background Art

[0002] In recent years, smart contracts have been widely used in various fields, and smart contracts supported by blockchain technology have made it possible to conduct trusted transactions in a decentralized or third-party-free environment. Ethereum is one of the most popular platforms for executing smart contracts. The Ethereum Virtual Machine (EVM) is the core of the Ethereum blockchain architecture, which provides the basic environment for the execution of smart contracts.

[0003] Unlike traditional software security issues, due to the immutability of blockchain technology itself, smart contracts cannot be modified once deployed, even if there are undeniable errors in their code. Therefore, the most effective way to detect vulnerabilities is to thoroughly review smart contracts on the chain before deployment to identify vulnerabilities and fix them.

[0004] At present, a variety of vulnerability detection technologies have been proposed to improve contract security, including symbolic execution, formal verification, and other static analysis methods. However, each method has its limitations. Symbolic execution symbolizes the variables in the program to explore all possible execution paths, which will lead to path explosion problems and affect the detection effect of vulnerabilities. Formal verification uses rigorous mathematical language and logic to describe smart contracts so that they can be rigorously mathematically reasoned and verified. How to effectively model necessary information such as EVM instructions is a major challenge for this technology. Because static analysis cannot actually execute each path, these methods always produce a high false positive rate.

[0005] As a dynamic detection technology, fuzz testing produces almost no false positives, which is a major advantage in vulnerability detection. However, some vulnerabilities will only be triggered when a specific function call sequence is met. On the other hand, it is difficult to cover some more complex branches in the contract by randomly generating test cases alone, making it impossible for fuzz testing to explore vulnerabilities in deep branches. Due to some special mechanisms of smart contracts, it will cause some vulnerabilities that are different from conventional software. For example, the denial of service smart contract vulnerability caused by the block gas limit. Some fuzzers cannot detect these vulnerabilities, which makes it impossible to fully guarantee the security of the contract. Summary of the invention

[0006] The present invention provides a smart contract vulnerability detection method and system based on hybrid fuzzy testing optimization.

[0007] The technical solution of the present invention is as follows: A smart contract vulnerability detection method based on hybrid fuzz testing optimization includes the following steps: S1. Obtain the source code of the smart contract, compile it to obtain EVM bytecode, perform static analysis on the EVM bytecode, and obtain the ABI interface parameter type and function call sequence based on the read-write dependency relationship between functions in the bytecode and the source code corresponding to the function; S2. Generate a first test case set based on the ABI interface parameter type and function call sequence, perform fuzz testing on the EVM bytecode based on the first test case set, obtain the number of all instructions covered by each test case when the instruction is executed, and construct an instruction count set; perform symbolic execution processing when the length change value of the instruction count set is 0 according to the length change of the instruction count set within the set execution number threshold, The symbolic execution processing operation is specifically as follows: setting the branch when the instruction count set length change value is 0 as the target branch point, only obtaining the arithmetic instructions and logic instructions of all branch constraints on each execution path when the instruction is executed to the target branch point, converting them into constraint expressions through symbolic processing, and collecting the constraint expressions to construct a path constraint set; After negating the constraint expression, perform constraint solving, cache and reuse the constraint expression and its solution results in the constraint solving, obtain a specific input value that satisfies the branch constraint condition where the target branch point is located, update the specific input value as a new test case to the first test case set, obtain a second test case set, execute S2 in a loop, expand the second test case set, until the set time is reached, terminate the loop, and execute S3; S3. Setting different test predictions for different smart contract vulnerabilities, wherein the smart contract vulnerabilities include permission control, transaction order dependency, and denial of service smart contract vulnerabilities; based on the test predictions, using the second test case set combined with taint analysis to perform smart contract vulnerability detection to obtain vulnerability detection results.

[0008] Furthermore, the taint analysis in S3 is specifically to perform taint analysis on the EVM bytecode based on the set taint propagation rules to obtain the propagation of taint data in the instruction stream, specifically: Obtain function call parameters and transaction data instructions in the EVM bytecode, including CALLDATALOAD, CALLDATACOPY, SLOAD, CALLER, ORIGIN, and CALLVALUE instructions, and mark the instructions and their return values ​​as tainted; Set CALL, SSTORE, JUMPI, ISZERO, SELFDESTRUCT, and DELEGATECALL instructions as taint sinks; When different instructions are executed, the taint propagation is tracked based on the taint propagation rules, specifically: For unary or multiary arithmetic instructions and logical instructions, if any operand contains taint, the result value obtained after executing the instruction will be marked as tainted. For instructions that query the blockchain status and instructions that do not affect the execution and status of the contract, they are marked as fixed instructions that are not considered tainted. For instructions that read data from memory or storage, if the instruction contains taint, the result value read is marked as tainted; Based on the propagation of taint to taint sink, the propagation path of taint in the instruction stream of EVM bytecode is obtained, and the vulnerability detection result is obtained based on the propagation path.

[0009] Specifically, in S2, the constraint expressions and their solution results are cached and reused in constraint solving. The specific operations are as follows: a visited set is constructed based on the visited constraint expressions, a dictionary is constructed based on the solved constraint expressions and their solution results for caching, and the corresponding unique hash value is obtained as the key for each constraint expression after the inversion operation: When solving a constraint expression, if the corresponding key exists in the dictionary, the solution result in the dictionary is reused, otherwise the constraint solution is reset; Traverse all constraint expressions except the last one in the path constraint set, add unvisited constraint expressions to the visited set, perform constraint solving after negating them, and cache the solution results in the dictionary.

[0010] Specifically, the test prediction set for the vulnerability of the permission control smart contract in S3 is specifically expressed as follows: For permission control smart contract vulnerabilities caused by permission configuration errors and lack of permission authorization check control, the test prediction set is: ErrorPermission∨(ExistDangerousI∧NoPCP), The first sub-prophecy ErrorPermission detects whether there is a permission configuration error in the smart contract. When the name of the non-standard constructor that sets the permission function of the smart contract owner is inconsistent with the name of the smart contract, ErrorPermission is judged to be true; The second sub-prediction ExistDangerousI detects whether there is a lack of permission authorization check in the smart contract, that is, whether there is tainted data from unauthorized users propagated to SELFDESTRUCT and DELEGATECALL instructions. If so, ExistDangerousI is judged to be true; The third sub-prediction NoPCP detects whether there is a permission constraint mode. If so, NoPCP is judged to be false; When ErrorPermission is true or ExistDangerousI and NoPCP are both true, the test prediction is true and there is a permission control smart contract vulnerability.

[0011] Furthermore, the authority constraint mode is determined to determine whether the following taint analysis process exists: Use the marked tainted instructions SLOAD and CALLER to load the smart contract owner address and the smart contract caller address respectively, and compare the two addresses to determine whether they are equal. If they are equal, the execution continues via the tainted sink instruction JUMPI. If they are not equal, the JUMPI operation jumps to REVERT to end the execution; If the above taint analysis process exists, it is determined that a permission constraint mode exists.

[0012] Specifically, the test prediction set in S3 for the denial of service smart contract vulnerability is: For the denial of service smart contract vulnerability caused by gas limit and external call failure, the test prediction is: ExistUnLoop∨ (ExistCallException∧UnhandledPreTermination), Among them, the sub-prophecy ExistUnLoop detects whether the smart contract contains an unbounded loop condition that can be determined by external input. If so, ExistUnLoop is true; the sub-prophecy ExistCallException detects whether the smart contract has an exception of an external call failure. If so, ExistCallException is true; the sub-prophecy UnhandledPreTermination detects whether the exception is handled before the termination of the smart contract. If not, UnhandledPreTermination is true; When ExistUnLoop is true or ExistCallException and UnhandledPreTermination are both true, the test prediction is true and there is a denial of service smart contract vulnerability.

[0013] Furthermore, the determination of whether the smart contract contains an unbounded loop condition that can be determined by external input is: Based on the external input taint, when it propagates to the JUMPI instruction and the ISZERO instruction, the ISZERO instruction takes the top element of the stack and makes a conditional judgment on it. If the judgment is true, it guides the JUMPI instruction to jump and judge whether the position of the JUMPI instruction jump is the same as the position of the previous jump. If they are the same, then the JUMPI instruction is determined to jump back to the loop body, and there is an unbounded loop condition that can be determined by external input.

[0014] Specifically, the test prophecy set for the transaction order dependency smart contract vulnerability in S3 is: setting the test prophecy ExistConflictingTransactions, if there is a read-write conflict in the storage location of the same variable in the smart contract, and the same variable is modified by transactions from different senders, the test prophecy is true, and there is a transaction order dependency smart contract vulnerability.

[0015] In the S2, the number of all instructions covered by each test case during instruction execution is obtained, and an instruction count set is constructed, specifically: during the fuzz testing process, the program counter is set to point to the address of the currently executed instruction of the EVM bytecode, the program counter value is obtained, and the instruction count set is constructed based on the program counter value; the instruction execution path of each test case is traversed, and the program counter value of each executed instruction is updated to the instruction count set.

[0016] The present invention also provides a smart contract vulnerability detection system based on hybrid fuzzy testing optimization, comprising: Static analysis module: used to obtain the source code of the smart contract, compile it to obtain EVM bytecode, perform static analysis on the EVM bytecode, and obtain the ABI interface parameter type and function call sequence based on the read-write dependency relationship between functions in the bytecode and the source code corresponding to the function; Fuzzy processing module: used to generate a first test case set based on the ABI interface parameter type and function call sequence, perform fuzzy testing on the EVM bytecode based on the first test case set, obtain the number of all instructions covered by each test case when the instruction is executed, and build an instruction count set; according to the length change of the instruction count set within the set execution number threshold, perform symbolic execution processing when the length change value is 0, The symbolic execution processing operation is specifically as follows: setting the branch when the instruction count set length change value is 0 as the target branch point, only obtaining the arithmetic instructions and logic instructions of all branch constraints on each execution path when the instruction is executed to the target branch point, converting them into constraint expressions through symbolic processing, and collecting the constraint expressions to construct a path constraint set; After negating the constraint expression, constraint solving is performed. In the constraint solving, the constraint expression and its solution are cached and reused to obtain a specific input value that satisfies the branch constraint condition of the target branch point. The specific input value is updated as a new test case to the first test case set to obtain a second test case set. The fuzzy processing module is executed in a loop to expand the second test case set until a set time is reached, the loop is terminated, and the vulnerability detection module is executed. Vulnerability detection module: used to set different test predictions for different smart contract vulnerabilities, including permission control, transaction sequence dependency, and denial of service smart contract vulnerabilities; based on the test predictions, the second test case set is used in combination with taint analysis to perform smart contract vulnerability detection and obtain vulnerability detection results.

[0017] The beneficial effects of the present invention are: 1. The present invention statically analyzes the compiled EVM bytecode to generate the first test case set, performs fuzz testing, and introduces taint analysis to track the propagation of taints in the instruction stream. During the fuzz testing process, the symbolic execution process is triggered when the length change value is 0 according to the length change of the instruction count set within the execution number threshold. By combining the advantages of fuzz testing and symbolic processing, when the fuzz test encounters branches that are difficult to cover, symbolic execution can be used to solve the solution that meets the complex path conditions, and feedback to the fuzz test as a new second test case set to help it explore deeper branches.

[0018] 2. In the process of symbolic execution, the present invention adopts a constraint cache reuse strategy to solve the obtained constraint expressions, and caches and reuses the solution results, which can greatly reduce the amount of calculation. This enables symbolic execution to quickly generate use case values ​​that reach complex branches, and feeds back to the fuzzy engine to assist it in exploring new paths to capture more deep-level vulnerabilities.

[0019] 3. This invention combines the characteristics of three smart contract vulnerabilities, namely permission control, transaction order dependency, and denial of service, which are ignored by most fuzzers, and designs accurate test predictions. It specifically detects and determines the permission control smart contract vulnerabilities caused by permission configuration errors and the denial of service smart contract vulnerabilities caused by gas restrictions that have not been specifically considered by other fuzz tests. BRIEF DESCRIPTION OF THE DRAWINGS

[0020] In the attached picture: Figure 1 This is a simplified code snippet of a real smart contract; Figure 2 This is an example of a permission control smart contract vulnerability caused by a lack of authorization check; Figure 3 A smart contract snippet with a denial of service smart contract vulnerability; Figure 4 A smart contract snippet with a transaction order dependent smart contract vulnerability; Figure 5 is the average real-time coverage for small contracts; Figure 6 is the average real-time coverage for large contracts. DETAILED DESCRIPTION

[0021] Exemplary embodiments of the present disclosure will be described in more detail below with reference to the accompanying drawings.

[0022] Example This embodiment provides a smart contract vulnerability detection method based on hybrid fuzzy testing optimization, see Figure 1 , including the following steps: S1. Obtain the source code of the smart contract, compile it to obtain EVM bytecode, perform static analysis on the EVM bytecode, and obtain the ABI interface parameter type and function call sequence based on the read-write dependency relationship between functions in the bytecode and the source code corresponding to the function.

[0023] Smart contracts written in high-level programming languages ​​need to be compiled into bytecode by a compiler before they can run on the EVM. EVM parses bytecodes in bytes, and each byte corresponds to an EVM instruction or an operation data. In EVM bytecode, instructions process data from the stack, memory, or storage. Among them, the stack and memory are temporary storage, and storage is persistent storage.

[0024] A smart contract is an automatically executed program that can only be accessed and used after being compiled and deployed on the blockchain in the form of bytecode. Once deployed, each contract is assigned an address as a unique identifier, namely the contract address. This information is public, and any user can initiate transactions based on the contract's application binary interface (ABI) to interact with the contract. The ABI is generated during the compilation process and defines the interface specification for user interaction with the contract. When a user initiates a transaction to call a contract, the function information to be called (such as the function signature and corresponding parameters) is first encoded into a format that the EVM can understand according to the ABI.

[0025] The actual execution of smart contracts occurs in the EVM. The Ethereum blockchain stores the contract code but does not execute the contract itself. After the transaction is issued by the user, it enters the transaction pool and waits for packaging confirmation. After receiving the transaction request, the corresponding contract code can be read from the blockchain storage through the contract address, and then the function signature, parameters and other information provided by the user in the transaction are parsed to determine the function to be called, and the contract execution is completed. Finally, the execution results and status changes are packaged into blocks and broadcast to the network. After other nodes confirm that the transaction is valid under the consensus mechanism, the new status or results will be permanently recorded on the blockchain.

[0026] Therefore, when detecting smart contract vulnerabilities, first compile the source code of the smart contract to obtain EVM bytecode, perform static analysis on the EVM bytecode in a static analyzer, and obtain the ABI interface parameter type and function call sequence based on the read-write dependency relationship between functions in the bytecode and the source code corresponding to the function.

[0027] S2. Generate a first test case set based on the ABI interface parameter type and function call sequence, perform fuzz testing on the EVM bytecode based on the first test case set, obtain the number of all instructions covered by each test case when the instruction is executed, and construct an instruction count set; perform symbolic execution processing when the length change value of the instruction count set is 0 according to the length change of the instruction count set within the set execution number threshold, The symbolic execution processing operation is specifically as follows: setting the branch when the instruction count set length change value is 0 as the target branch point, only obtaining the arithmetic instructions and logic instructions of all branch constraints on each execution path when the instruction is executed to the target branch point, converting them into constraint expressions through symbolic processing, and collecting the constraint expressions to construct a path constraint set; After negating the constraint expression, constraint solving is performed. In the constraint solving, the constraint expression and its solution result are cached and reused to obtain a specific input value that satisfies the branch constraint condition of the target branch point. The specific input value is updated as a new test case to the first test case set to obtain a second test case set. S2 is executed in a loop to expand the second test case set until the set time is reached, the loop is terminated, and S3 is executed.

[0028] The processing process is described in detail below. First, the first test case set is generated based on the ABI interface parameter type and function call sequence. After obtaining the ABI interface parameter type and function call sequence in step S1, the fuzzer generates a series of random test cases for the function to be called according to the ABI interface parameter type and enters the fuzz engine module to start fuzz testing the EVM bytecode. The contract execution analyzer records and tracks the actual execution of these test cases. It monitors the status of the fuzzer fuzz testing and starts symbolic execution in appropriate scenarios to generate new test cases to assist in the execution of fuzz testing. The specific steps are described as follows: The fuzz engine first generates a series of test cases as initial seeds to fuzzify the smart contract. During the contract execution, the code coverage and constraint solving results of symbolic execution are used as feedback to select, cross, and mutate the seeds to generate new inputs. Constructing the initial seed is a key step that affects the fuzzy effect, because a good seed can generate potential mutations to reach deeper paths and discover vulnerabilities.

[0029] When the fuzzy engine generates test cases for smart contracts, two parts need to be considered, namely, the parameter types that meet the transaction and the valid transaction sequence. The smart contract application binary interface (ABI) specification specifies how to construct the byte data sent to the transaction as data when calling the smart contract function. By statically analyzing the smart contract, the number and type of parameters are extracted from its corresponding ABI interface, and test cases that meet the transaction are generated according to the different types of parameters, namely the first test case set. For fixed-length parameters (for example, uint256), random values ​​are generated according to the type of the parameter and the clear bytes or bits. For non-fixed-length parameters (for example, string, uint32[]), the length of the generated data is first determined, and then the value of this length is filled with random elements to simulate various possible input situations. In addition, high-quality test cases are also related to valid transaction sequences. The state of a smart contract is gradually changed through the execution of multiple transactions, and some vulnerabilities can often only be triggered in a specific contract state. By analyzing the bytecode of the smart contract, the read and write dependencies between functions are checked to determine a set of transaction sequences. This test case generation strategy, which meets both transaction parameter types and transaction sequences, enables the fuzzy engine to test different states and paths of the contract more comprehensively, making it more likely to discover potential vulnerabilities.

[0030] After generating the first test case set, the EVM bytecode is fuzz tested based on the first test case set. During the fuzz test, the number of instructions covered by each test case is recorded, and the instruction count set is constructed. Specifically, the smart contract runs in the form of bytecode in the EVM. During the fuzz test, the program counter is set to point to the address of the currently executed instruction of the EVM bytecode. The program counter is a key register when executing instructions, which points to the address of the currently executed instruction. By tracking the value of the program counter, it is possible to accurately understand which instructions the smart contract has executed, and then obtain the program counter value, and construct the instruction count set based on the program counter value; traverse the instruction execution path of each test case, and update the program counter value of each executed instruction to the instruction count set.

[0031] Furthermore, some vulnerabilities in smart contracts are often caused by complex logical errors, which are usually hidden in the deep paths of the code. When facing branches with strict constraints, the probability of fuzz testing reaching new paths by mutation alone is extremely low, and a large amount of testing resources will be wasted. In order to achieve the purpose of covering more complex branches, the present invention proposes a hybrid fuzz testing method combined with symbolic execution. After the fuzz test covers the shallow branches, the method uses symbolic execution to explore the paths missed by the fuzz test and generate inputs that meet specific branch conditions.

[0032] In this step, fuzz testing is used to obtain the number of all instructions covered by each test case during instruction execution, and an instruction count set is constructed. The length change of the instruction count set within the set execution number threshold is used, and symbolic execution processing is performed when the length change value is 0.

[0033] A key issue is when to start the symbolic execution module. In order to alleviate the path explosion problem in branch symbolic execution, the present invention dynamically detects the execution status of the contract code and starts the symbolic execution module when the code coverage reaches a bottleneck and cannot be significantly improved. By allowing symbolic execution to only explore paths that are difficult for fuzz testing to reach, a balance between high coverage and difficulty in solving is achieved.

[0034] Specifically, maintain a set C defined as an instruction count set to store the program counter values ​​of executed instructions. Traverse the execution traces of each test case and add the program counter value of each instruction to the instruction count set. By calculating the length of the instruction count set, determine whether the coverage of the contract by the test case has changed. If the length of the instruction set does not change within the set execution count threshold, and the length change value is 0, it is considered that the program has encountered a complex branch in the fuzz test, causing the execution state to stagnate. At this time, it is necessary to start the symbolic execution engine to solve the specific branch conditions to update the test case. The switching between fuzz testing and symbolic execution is shown in Table 1.

[0035] Table 1 Switching algorithm between fuzz testing and symbolic execution

[0036] The processing of symbolic execution is described in detail below. The symbolic execution processing operation in this embodiment is specifically as follows: setting the branch when the instruction count set length change value is 0 as the target branch point, only obtaining the arithmetic instructions and logical instructions of all branch constraints on each execution path when the instruction is executed to the target branch point, symbolizing them and converting them into constraint expressions, and collecting the constraint expressions to construct a path constraint set.

[0037] Symbolic execution uses the test case input of the current fuzz test as a specific value to perform both actual and symbolic execution on the smart contract, and collects symbolic path constraints during the execution process. When the execution reaches the target branch point, the constraint is negated and the constraint solver is called to solve the constraint to find possible inputs that trigger this branch.

[0038] The generation of constraints requires parsing the instructions and parameters of all branch constraints involved in each execution path. Traditional symbolic execution focuses on each execution instruction in the smart contract, and when encountering certain instructions, it jumps to the vulnerability detection module to detect vulnerabilities. The main purpose of the present invention is to use symbolic execution to generate a set of values ​​that meet complex branch conditions, and the detection of vulnerabilities is then judged by efficient fuzz testing. Specifically, a lightweight symbolic execution engine is used, that is, only focusing on arithmetic instructions (such as ADD, SUB, MUL, etc.) and logical instructions (such as AND, OR, XOR, NOT, etc.) in branch constraints, converting the problem into a set of constraint expressions, and then using functions such as BitVector() in the Z3 solver to model the EVM instructions, symbolizing the arithmetic instructions in the branch constraints and converting them into constraint expressions, and solving the path constraints in real time to determine whether the path is feasible. After the solution is completed, the symbolic value is replaced with a specific value and passed into the seed pool in the fuzzy engine to update the test case.

[0039] During symbolic execution, constraint expressions are collected to build path constraint sets, and these constraint expressions are added to the solver to determine whether they are satisfied. Since different paths may share some of the same constraints, i.e., constraint expressions, similar or identical constraints may appear on different paths. In programs containing loops or arrays, the same path may be traversed multiple times. By caching and reusing the solution results of these paths, the amount of computation can be greatly reduced. For each constraint solving problem, it can be expressed as a triple P=<V,D,C> , where: V is a set of variables, represented by { v 1 , v 2 ,…, v n}, the value of the test case is closely related to the values ​​of these variables; D is the set of variable value domains, that is, the value range of each variable. Specifically, each variable v i The value must be within its range d i The possible value range of each variable is D={d1,d2,…,d n} ;C is a set of constraints. Each constraint is a logical expression about variables, defining the relationship between variables that needs to be satisfied. Each constraint c i ∈C contains one or more variables.

[0040] The constraint expression is further negated, and then the constraint is solved. In the constraint solution, the constraint expression and its solution results are cached and reused to obtain a specific input value that satisfies the branch constraint condition of the target branch point. The details are as follows: During the symbolic execution process, a constraint set C={c1,c2,…,c n} That is, the path constraint set mentioned above. Different paths may share some of the same constraint expressions c i If the constraint expression c i If the problem has been solved in the previous path, the system can check the cache to determine whether the previous solution result can be reused. This can avoid repeated calculations of the same or similar constraints during solution. Therefore, the constraint solution result reuse strategy is adopted during symbolic execution, specifically caching and reusing the constraint expression and its solution result in the form of hash value.

[0041] The operation steps are as follows: build an accessed set based on the visited constraint expressions, build a dictionary for caching based on the constraint expressions that have been solved and their solution results, and obtain the corresponding unique hash value as the key based on each constraint expression after the inversion operation: When solving a constraint expression, if the corresponding key exists in the dictionary, the solution result in the dictionary is reused, otherwise the constraint solution is reset; Traverse all constraint expressions except the last one in the path constraint set, add unvisited constraint expressions to the visited set, perform constraint solving after negating them, and cache the solution results in the dictionary.

[0042] The symbolic execution process using the constrained cache reuse strategy is shown in Table 2.

[0043] Table 2 Symbolic execution process using the constraint cache reuse strategy

[0044] The processing process corresponding to Table 2 is further described as follows: First, an empty set (visited_constraints) is initialized to store the visited constraint expressions, and a dictionary (Ccache) is created to record the solved constraint expressions and their solution results. Then, the negated constraint (negated_branch) of the current branch constraint expression is calculated, and a unique hash value (cache_key) is generated as the key of the dictionary. Then, check whether cache_key exists in Ccache; if it exists, reuse the solver state in the dictionary, that is, the solution result (solver); otherwise, reset the solver and reset the constraint solution. Next, traverse all constraint expressions except the last constraint expression in the path constraint set, simplify each constraint, and check whether it has been visited; if it has not been visited, add it to the visited set, and solve the constraint after negating it, and cache the solution result in the dictionary. Then call the solver to solve, if the solution is successful, obtain the solution result, and update the solver state in the dictionary. Regardless of whether the new constraint solution uses the cached result, the final result will be stored in the dictionary for reuse in subsequent symbolic execution. Finally, a set of solution results (Result) is returned.

[0045] Specifically, the Z3 solver is used to solve symbolic execution and collect path constraints. Specific input values ​​can be generated for complex branches in the smart contract. The specific input values ​​are updated as new test cases to the first test case set to obtain the second test case set. The new second test case set is then fed back to the fuzzy test. In this way, the fuzzy engine can break through the bottleneck of shallow branches and explore vulnerabilities in deep branches.

[0046] Fuzz testing can quickly generate a large number of unexpected test cases for the program to be tested to cover as many program paths as possible to discover vulnerabilities. However, some branches with strict conditions are difficult to cover only through the mutation strategy of fuzz testing. Symbolic execution is good at solving branch paths that are difficult to explore by fuzz testing mutation due to the large search space. But its constraint solving process will take a certain amount of time. Therefore, in this step, the advantages of both are combined. When fuzz testing encounters branches that are difficult to cover, symbolic execution is used to solve the solution that can meet the complex path conditions and feedback to fuzz testing as a new test case to help it explore deeper branches.

[0047] S3. Setting different test predictions for different smart contract vulnerabilities, wherein the smart contract vulnerabilities include permission control, transaction order dependency, and denial of service smart contract vulnerabilities; based on the test predictions, using the second test case set combined with taint analysis to perform smart contract vulnerability detection to obtain vulnerability detection results.

[0048] In this step, in order to determine whether the attacker can pass in malicious data to affect the security of the smart contract, taint analysis technology is also introduced to monitor the flow of data during the execution of the contract when performing vulnerability detection on the smart contract. The core purpose of taint analysis is to track the flow of potentially malicious or untrusted data (i.e., "taints") in the program, and this flow process is directly driven by EVM instructions. Therefore, we perform taint tracking at the EVM instruction level. The core components of taint analysis include taint sources, taint propagation rules, and taint sinks, which respectively define the starting point of the data, the flow process, and the end point to be detected. The following explains the marking and settings of taints, taint sinks, and taint propagation rules.

[0049] Taint marking: Some EVM instructions read data from the external environment or untrusted input. If these data contain malicious content, it is easy to cause security vulnerabilities in the contract. Obtain function call parameters and transaction data instructions in the EVM bytecode, including CALLDATALOAD, CALLDATACOPY, SLOAD, CALLER, ORIGIN, and CALLVALUE instructions, and mark the instructions and their return values ​​as tainted; Therefore, the EVM instructions that introduce user data are regarded as taint sources, namely taints, as shown in Table 3. These instructions are mainly related to reading contract function parameters and transaction-related data (such as the sender and the amount in the transaction).

[0050] Table 3 Instructions defined as tainted sources

[0051] Among them, the EVM instructions CALLDATALOAD and CALLDATACOPY read external parameters; the SLOAD instruction reads internal data from the storage of the smart contract and is also defined as a source of pollution because these internal data may have been polluted by untrusted inputs; CALLER and ORIGIN return the address of the current contract caller and the address of the initial initiator of the current transaction respectively, and CALLVALUE returns the ether value of the transaction. Therefore, in order to prevent external untrusted callers from manipulating contracts and using unreliable authentication mechanisms, these instructions and their return values ​​are marked as tainted.

[0052] For the marking of tainted sinks: set CALL, SSTORE, JUMPI, ISZERO, SELFDESTRUCT, and DELEGATECALL instructions to tainted sinks; If key operations such as transfer, storage or jump are affected by tainted data, this indicates that the attacker may manipulate the execution of the contract by constructing malicious data, thereby changing its state and damaging the contract. Logical instructions such as ISZERO are used to process conditional judgments, which will have a direct impact on the execution path of the loop; and conditional jump instructions such as JUMPI, based on the results of the logical instructions, decide whether to continue the loop. In this embodiment, the CALL, SSTORE, JUMPI and ISZERO instructions are set as tainted sinks. In addition, the instructions SELFDESTRUCT and DELEGATECALL may have extremely bad effects on the contract if they are manipulated by unauthorized users. For example, an attacker can control the SELFDESTRUCT instruction and pass his own account address as a parameter. Those who will receive all the ether assets in the contract while destroying the contract; the DELEGATECALL instruction may call a harmful contract maliciously designed by the attacker, so the SELFDESTRUCT and DELEGATECALL instructions are also defined as tainted sinks. The specific description of these instructions is shown in Table 4.

[0053] Table 4

[0054] Setting of taint propagation rules: Based on the set taint propagation rules, the EVM bytecode is tainted and analyzed to obtain the propagation of tainted data in the instruction stream. When different instructions are executed, the taint propagation is tracked based on the taint propagation rules. Specifically: Rule 1: For unary or multiary arithmetic instructions or logical instructions, if any operand contains taint, the result value obtained after executing the instruction will be marked as tainted.

[0055] Assume that instruction I has n operands, expressed as t(v) = I( op 1 , op 2 ,…… op n ), the taint status of each operand can be expressed as follows: , in, Indicates i operands, =1 means the operand is marked as tainted, =0 means that the operand is not marked as tainted.

[0056] Rule 2: For instructions that query the blockchain status and instructions that do not affect the execution and status of the contract, they are marked as fixed instructions that are not considered tainted.

[0057] For instructions that query the blockchain status (such as TIMESTAMP) and those that do not affect the contract execution and contract status (such as LOGn instructions), these instructions will not cause taint propagation in the taint propagation analysis. LOGn instructions are used to generate event logs. Although these data will be permanently stored on the blockchain, they will not affect the execution of the contract and these log data cannot be directly accessed within the contract. Therefore, instructions with similar functions are recorded as These instructions do not cause taint propagation, which helps reduce the complexity of taint propagation and the degree of over-pollution.

[0058] Rule 3: For instructions that read data from memory or storage, if the instruction contains taint, the result value read is marked as tainted.

[0059] For example, = MLOAD( m i ) indicates that the MLOAD instruction loads the Read data from Indicates the taint state of the memory address. If the memory address The data is tainted, then the result is also marked as 1. Similarly, the SLOAD instruction that reads data from storage also follows this rule, using Indicates storage address The stain state.

[0060] Based on the propagation of taint to taint sink, the propagation path of taint in the instruction stream of EVM bytecode is obtained, and a security report is generated based on the propagation path to obtain the vulnerability detection result.

[0061] Taking into account the complex memory management of EVM, this embodiment specifically adopts a key-value pair data structure to realize the propagation of taints between the stack, memory, and storage. The key of each key-value pair represents the location of the taint, and the value contains the input parameter set that triggers the taint. For the convenience of description, three key-value pairs are used and named t_InStack, t_InMemory, and t_InStorage respectively. EVM uses a stack to store temporary calculation data and instruction operands. t_InStack is used to record whether the data at each stack position is contaminated. If subsequent operations use the data at this position, the result will also be marked as a taint and recorded through the key-value pair structure. Similarly, t_InMemory and t_InStorage are used to record whether the data at each location in the memory and storage is contaminated.

[0062] For example, the MSTORE instruction indicates that a value is stored from the stack to the memory area. When the MSTORE instruction is executed, the taint engine will first pop the taint corresponding to the value in the stack from the key-value pair t_InStack, then associate the taint with the memory address corresponding to the value, and store the taint in the corresponding position in the key-value pair t_InMemory. In this way, the data at the corresponding address in the memory is given the same taint mark, realizing the transfer of the taint from the stack to the memory.

[0063] Table 5 lists the three main taint propagation rules improved in this embodiment.

[0064] Table 5 Taint propagation rules

[0065] In the present invention, three different test oracles are designed for three different smart contract vulnerabilities, namely, permission control, transaction order dependency, and denial of service. Based on the test oracles, the second test case set is used in combination with taint analysis to detect smart contract vulnerabilities and obtain vulnerability detection results. The detailed introduction of the designed test oracles is as follows: Test oracles are used to determine vulnerabilities in smart contracts during fuzz testing. At present, the research on using fuzz testing technology to detect permission control smart contract vulnerabilities, denial of service smart contract vulnerabilities, and transaction order dependency smart contract vulnerabilities is not comprehensive, so in this embodiment, three test oracles are formulated based on the characteristics of these three vulnerabilities and are specifically introduced.

[0066] Regarding permission control smart contract vulnerabilities, permission control is an effective permission strategy to prevent assets in the contract from being manipulated by unauthorized users. Smart contracts usually use various permission constraints to limit the address or attributes of the caller. If the permission constraints are set incorrectly or key operations lack permission control, it may lead to permission control smart contract vulnerabilities (AC), resulting in contract asset losses. Generally, permission control smart contract vulnerabilities include permission configuration errors and lack of authorization checks.

[0067] For the case where permission configuration errors lead to permission control smart contract vulnerabilities, such as Figure 1As shown in the figure, it is a simplified code snippet of a real smart contract. In this code snippet, the state variable owner in line 2 is used to store the address of the contract owner. frozenAccount in line 3 is used to store frozen accounts that cannot perform specific operations in a mapping manner. The modifier onlyOwner is used to check whether the contract caller is the owner. The modifier onlyOwner is used to protect the freezeAccount() function. The contract owner and some other variables are initialized in the function UBSecToken(). It performs the function of the constructor in this contract. In Solidity, each contract can only define one constructor. This function is automatically run once when the contract is deployed to initialize some parameters, including the address of the owner. The developer made a major mistake here. The name of the constructor is UBSecToken instead of the contract name BAFCToken. This makes the constructor with special functions become an ordinary function that anyone can call, that is, anyone can make themselves the owner of the contract by calling UBSecToken(), thereby performing some operations beyond ordinary permissions. Although freezeAccount() in line 11 uses the onlyOwner modifier for permission check, an attacker can hijack the contract ownership before this and freeze any account in the contract. A vulnerability caused by a misconfigured permissions configuration where anyone can equip themselves with the elevated permissions of a contract owner.

[0068] For cases where the lack of authorization checks leads to vulnerabilities in permission control smart contracts, such as Figure 2 As shown. The selfdestruct(msg.sender) statement involves a special dangerous instruction SELFDESTRUCT, which is a self-destruct instruction. Once this instruction is executed, the contract will be removed from the blockchain, and all assets in the contract balance will be sent to the address (msg.sender) provided as the instruction parameter. Therefore, only authorized users (such as contract owners) should be allowed to call the function removeContract(). In addition, unauthorized users cannot arbitrarily set the parameters of the self-destruct instruction.

[0069] The test prediction for the vulnerability setting of the permission control smart contract is as follows: For permission control smart contract vulnerabilities caused by permission configuration errors and lack of permission authorization check control, the test prediction set is: ErrorPermission∨(ExistDangerousI∧NoPCP), The first sub-prophecy ErrorPermission detects whether there is a permission configuration error in the smart contract. When the name of the non-standard constructor that sets the permission function of the smart contract owner is inconsistent with the name of the smart contract, ErrorPermission is judged to be true; The second sub-prediction ExistDangerousI detects whether there is a lack of permission authorization check in the smart contract, that is, whether there is tainted data from unauthorized users propagated to SELFDESTRUCT and DELEGATECALL instructions. If so, ExistDangerousI is judged to be true; The third sub-prediction NoPCP detects whether there is a permission constraint mode. If so, NoPCP is judged to be false; When ErrorPermission is true or ExistDangerousI and NoPCP are both true, the test prediction is true, indicating that there is a permission control smart contract vulnerability.

[0070] The third sub-oracle determines the permission constraint mode. It determines whether there is protection of the permission constraint mode during the contract execution process through taint analysis. Specifically, it determines whether there is the following taint analysis process: Use the marked tainted instructions SLOAD and CALLER to load the smart contract owner address and the smart contract caller address respectively, compare the two addresses through the EQ operation to determine whether they are equal, if they are equal, continue to execute through the tainted sink instruction JUMPI operation; if they are not equal, jump to REVERT through the JUMPI operation to end the execution; If the above taint analysis process exists, it is determined that a permission constraint mode exists.

[0071] Not all dangerous instructions can be exploited by attackers to cause damage to the contract. In the source code of smart contracts, developers usually use permission constraint modes to control the accessibility of functions containing dangerous instructions. require (msg.sender == owner) is the most common permission constraint mode. The require statement is used to check conditions and throw an exception if the check fails. In this permission constraint mode, msg.sender is the smart contract caller, and owner is the smart contract owner address. In other words, only when the caller is the owner of the smart contract can it pass the permission check. This is an effective protection measure to prevent permission control smart contract vulnerabilities, as shown below: require(msg.sender==owner), During fuzz testing, by analyzing the flow of tainted data, we can identify whether the permission check logic depends on unvalidated inputs (msg.sender) and whether these inputs affect key decision points of the contract (such as JUMPI).

[0072] For the Denial of Service (DOS) smart contract vulnerability, during the execution of the smart contract, some unexpected situations may cause the contract program to fail to run normally, resulting in transaction failure, that is, a denial of service situation. This type of vulnerability can be caused in many ways. Figure 3 Shows a code snippet of a smart contract deployed on the Ethereum blockchain.

[0073] Figure 3 is a smart contract fragment. It sets a jackpot for each game, allows users to participate in the game by buying tickets and guessing the price, and selects the winner according to the amount through the pickTheWinner() function at the end of the game. Users can participate in the game by calling the buyTicket function on line 8. The buyTicket function stores the address player and amount betPrice of each participant in the mapping order. It adds the remaining amount to the jackpot[game] of the current game after deducting 20% ​​of the user's amount as participation fee. The contract owner can call the start() function to specify the winning price winPrice. If the number of participants in the current game is not empty (order[game].length>0), the pickTheWinner() function on line 18 is called, which distributes all the amounts in the jackpot equally to each winner, that is, the participants whose amounts are consistent with the winPrice specified by the contract owner. However, there are two different denial of service smart contract vulnerabilities in this function, namely gas limit and external call failure.

[0074] Furthermore, for the first type of denial of service smart contract vulnerability caused by Gas restriction, Figure 3The pickTheWinner() function in the game allocates the prize money in the jackpot through a for loop with orders[game].length as the termination condition. It should be noted that orders is a dynamic mapping determined by external input. When a large number of players participate in the game, the gas cost of executing the loop will exceed the block limit, resulting in the failure of the loop, and no winner will receive the prize money. And the amount in the jackpot will be frozen forever because there is no other function in the contract that can transfer money. Gas limit is a special concept in the Ethereum network. In the Ethereum network, each time a transaction or smart contract is executed, a certain amount of computing resources are consumed, and the use of these resources is measured in gas. The Ethereum network specifies a block gas limit. When the cost of executing a function exceeds the block limit, the transaction will be terminated and the contract state will be rolled back, resulting in a denial of service.

[0075] For the second type of denial of service smart contract vulnerability caused by external call failure, Figure 3 The function pickTheWinner() in the contract also involves an external call, which uses transfer() to transfer money to the winner. If one of the winners wants to perform a DoS attack on this contract, he can add a revert() function to the fallback() function of his attack contract to deliberately make the call fail. Then other winners will not receive the prize money, and the attacker will also achieve the goal of freezing all prize money and stopping the normal service of the contract. If an external call exception occurs during the execution of the contract and these exceptions are not properly handled before the execution is terminated, it may lead to a denial of service smart contract vulnerability.

[0076] Therefore, for the denial of service smart contract vulnerability caused by gas limit and external call failure, the test prophecy is set as: ExistUnLoop∨ (ExistCallException∧UnhandledPreTermination).

[0077] Among them, the sub-prophecy ExistUnLoop detects whether the smart contract contains an unbounded loop condition that can be determined by external input. If so, ExistUnLoop is true; the sub-prophecy ExistCallException detects whether the smart contract has an exception of an external call failure. If so, ExistCallException is true; the sub-prophecy UnhandledPreTermination detects whether the exception is handled before the termination of the smart contract. If not, UnhandledPreTermination is true; When ExistUnLoop is true or ExistCallException and UnhandledPreTermination are both true, the test prediction is true, indicating that a denial of service smart contract vulnerability exists.

[0078] In the specific denial of service smart contract vulnerability detection, the execution of the CALL instruction of the external call will be triggered first, and the result returned by the call will be pushed to the stack. Then, combined with the taint analysis, the valid exception result will be recorded, and the prediction ExistCallException will be triggered. During the execution of the contract, it is determined whether the exception is handled by tracking whether the exception of each failed external call flows into the JUMPI instruction. If the jump condition is true, the corresponding exception is removed from the record, proving that these exceptions have been handled during the execution process. When the termination instruction (such as REVERT, RETURN, STOP, SUICIDE, SELFDESTRUCT) is executed, CSOptiHyFuzz checks whether the exception record is empty. If there are still unhandled exceptions in the record, it means that the exception was not handled before termination, and the UnhandledPreTermination sub-prediction is triggered.

[0079] In the sub-oracle ExistUnLoop, it is necessary to determine whether the smart contract contains unbounded loop conditions that can be determined by external input. Because when the boundary conditions of loop iterations are determined by user input, it may cause a denial of service smart contract vulnerability caused by Gas limit. In smart contracts, when developers use function parameters to pass user input values, they generally impose reasonable restrictions on them to avoid excessive loop iterations. Therefore, user input passed directly by function parameters is usually not a direct source of vulnerabilities. However, special attention should be paid to loop conditions constructed by external users through dynamic data structures, such as arrays, mappings, etc. They will continue to grow over time and user interactions, and can be operated by contract users. An attacker can use their unbounded loops to exhaust the gas of the contract, causing the contract to be unable to continue execution or process other important operations.

[0080] Although fuzz testing will report the termination of the transaction when the specified Gas limit is exceeded during the execution of the contract, this often requires a lot of resources to achieve this termination condition. If the test resources are limited, it will cause a certain degree of underreporting. Therefore, when the test case fuzzifies the contract, we also use taint analysis to determine whether there is an unbounded loop in the contract code. The specific process is: Based on the external input taint, when it propagates to the JUMPI instruction and the ISZERO instruction, the ISZERO instruction takes the top element of the stack and makes a conditional judgment on it. If the judgment is true, it guides the JUMPI instruction to jump and judge whether the position of the JUMPI instruction jump is the same as the position of the previous jump. If they are the same, then the JUMPI instruction is determined to jump back to the loop body, and there is an unbounded loop condition that can be determined by external input.

[0081] Taint analysis is used to track whether the data introduced by the pollution source reaches the loop condition. If an external user can change the execution result of the ISZERO instruction through the pollution source (such as user input), it is possible to change the number of executions of the loop.

[0082] In the case of transaction order dependency smart contract vulnerability (TOD), the behavior of smart contracts depends on the execution order of transactions, and this dependency is maliciously exploited to cause unfair transaction results. After the transaction is initiated by the user, it is not executed immediately, but waits to be packaged into the block. Usually, transactions that provide higher gas fees are packaged first, which gives attackers the opportunity to disrupt the normal transaction order. Figure 4 A contract snippet with a TOD vulnerability is shown. This contract implements the function of buying and selling goods. Specifically, when there is enough inventory, the user purchases a certain amount of goods by calling the buy() function and pays the seller the corresponding amount price*amount. However, if before this transaction is confirmed, the contract owner (owner) initiates a transaction as a seller with a higher gas and raises the price of the goods by using setPrice(), the user will pay more according to the new price (_newPeice).

[0083] To detect the TOD vulnerability of a contract, it is necessary to confirm whether a function can change the global variables involved in the contract state, and the output of this function depends on the order of transactions. For this purpose, the test prophecy ExistConflictingTransactions is designed. This prophecy mainly performs two checks: one is to check whether there is a read-write conflict in the storage location of the same variable, and the other is to check whether the variable is modified by exchanges from different senders. If there is a read-write conflict in the storage location of the same variable in the smart contract, and the same variable is modified by exchanges from different senders, the test prophecy is true, and it is determined that there is a transaction order-dependent smart contract vulnerability.

[0084] During the execution of the test case, check whether the current instruction is SSTORE, which performs storage operations on variables in the function. If the data stored is tainted data, record its storage location. When it is detected that the instruction is an SLOAD instruction that performs a read operation on a variable, record the location of the data it reads and determine whether this location is the same as the location previously written by SSTORE, that is, determine if the data read by the SLOAD operation depends on the previous SSTORE operation. If the current instruction is CALL, further confirm whether the external call has modified the previously recorded storage location, and verify whether the modified transaction initiator is consistent. If the external transaction involved in the CALL instruction affects the storage location of the previously recorded SSTORE operation, this may indicate that changes in the order of transactions can cause storage variables to be modified by different transactions.

[0085] The present invention also provides a smart contract vulnerability detection system based on hybrid fuzzy testing optimization, comprising: Static analysis module: used to obtain the source code of the smart contract, compile it to obtain EVM bytecode, perform static analysis on the EVM bytecode, and obtain the ABI interface parameter type and function call sequence based on the read-write dependency relationship between functions in the bytecode and the source code corresponding to the function; Fuzzy processing module: used to generate a first test case set based on the ABI interface parameter type and function call sequence, perform fuzzy testing on the EVM bytecode based on the first test case set, obtain the number of all instructions covered by each test case when the instruction is executed, and build an instruction count set; according to the length change of the instruction count set within the set execution number threshold, perform symbolic execution processing when the length change value is 0, The symbolic execution processing operation is specifically as follows: setting the branch when the instruction count set length change value is 0 as the target branch point, only obtaining the arithmetic instructions and logic instructions of all branch constraints on each execution path when the instruction is executed to the target branch point, converting them into constraint expressions through symbolic processing, and collecting the constraint expressions to construct a path constraint set; After negating the constraint expression, constraint solving is performed. In the constraint solving, the constraint expression and its solution are cached and reused to obtain a specific input value that satisfies the branch constraint condition of the target branch point. The specific input value is updated as a new test case to the first test case set to obtain a second test case set. The fuzzy processing module is executed in a loop to expand the second test case set until a set time is reached, the loop is terminated, and the vulnerability detection module is executed. Vulnerability detection module: used to set different test predictions for different smart contract vulnerabilities, including permission control, transaction sequence dependency, and denial of service smart contract vulnerabilities; based on the test predictions, the second test case set is used in combination with taint analysis to perform smart contract vulnerability detection and obtain vulnerability detection results.

[0086] Experimental content In the experimental part, two aspects need to be focused on. One is whether the smart contract vulnerability detection method based on hybrid fuzzy testing optimization proposed in the present invention can achieve higher code coverage compared with the existing methods; the other is whether the smart contract vulnerability detection method based on hybrid fuzzy testing optimization used in the present invention can more effectively detect permission control smart contract vulnerabilities, denial of service smart contract vulnerabilities and transaction order dependency smart contract vulnerabilities in smart contracts compared with other vulnerability detection methods.

[0087] The present invention is compared with different vulnerability detection methods listed in Table 6. The methods listed in Table 6 all use symbolic execution or fuzz testing technology to detect vulnerabilities and have been made public on GitHub. For vulnerability detection methods based on symbolic execution, Oyente and Mythril are selected for comparison. Among them, Oyente is the first method used for smart contract vulnerability detection, and as a pioneering work, it has a high degree of recognition in the field of smart contract security. The difference between Mythril and Oyente is that it adopts a dynamic symbolic execution method to simulate the execution process of smart contracts in real situations. Moreover, Mythril, as an open source community technology, has been kept updated in recent years. For fuzz testing methods, sFuzz, which has appeared in recent years, is selected. It selects a distance-based seed selection strategy to generate a large number of test cases to dynamically fuzz the contract to find security issues therein. Compare the code coverage and effectiveness of the present invention and them under the same configuration environment. The specific comparison methods involved in the experiment are shown in Table 6.

[0088] Table 6 Different vulnerability detection methods and the types of vulnerabilities that can be detected

[0089] In the experiment, two datasets of different sizes were used to evaluate the experimental effect of the smart contract vulnerability detection method based on hybrid fuzz testing optimization in this embodiment. The main goal of dataset 1 is to test its performance in contract code coverage. Based on the publicly available dataset, 1,000 smart contracts were selected, all of which are real-world smart contracts from Etherscan and have access to source code. In order to verify whether symbolic execution can assist fuzz testing to achieve higher code coverage when stuck in the dilemma of complex branches, the number of EVM instructions for each smart contract was calculated, and the 1,000 smart contracts were divided into small-scale contracts and large-scale contracts according to the number of instructions. Table 7 shows the number of source code lines and instructions for all smart contracts in dataset 1. Among them, there are 628 small-scale contracts with less than 3,000 instructions; there are 372 large-scale contracts with more than 3,000 instructions. Generally speaking, the more instructions a contract has, the more complex the code branches and execution logic involved.

[0090] Table 7 Number of source code lines and instructions of all smart contracts in Dataset 1

[0091] The purpose of Dataset 2 is to test the detection effect of permission control smart contract vulnerabilities (AC), denial of service smart contract vulnerabilities (DoS) and transaction order dependency smart contract vulnerabilities (TOD) in smart contracts. In the Smartbugs official dataset, there are few contracts marked with these three vulnerabilities, which cannot show the detection effect well. Therefore, contracts obtained from the Etherscan official website are added on its basis and manually marked. The final expanded Dataset 2 contains a total of 129 contracts.

[0092] By comparing the detection results of various methods, we can measure whether there are security issues in smart contracts. Specifically, in the experiment, all contracts found to have problems are marked as true positives (True Positive, TP) or false positives (False Positive, FP). TP means that the vulnerability in the contract is correctly detected, and FP means that the smart contract vulnerability is incorrectly detected, that is, there is no vulnerability in the contract itself but the tool reports an incorrect detection result. In addition, the number of false negatives (False Negative, FN) is also counted. FN means that the tool did not detect the real vulnerability in the contract, that is, it is missed. Further, based on the three statistical values ​​of TP, FP and FN, the false positive rate (False Positive Rate, FPR), false negative rate (False Negative Rate, FNR) and precision (Precision), recall rate (Recall) and F1 score (F1-score) evaluation indicators of each tool are calculated to judge the detection performance. Among them, precision (Precision) can be calculated as, recall rate (Recall) and F1-score can be calculated as: , , , , , in, n Represents the number of contracts.

[0093] Code coverage is an important evaluation indicator in the field of fuzz testing. In the experiment, the real-time code coverage obtained in this embodiment is compared with sFuzz, and the running time is set to 60s. The average value of the code coverage of each contract over time is calculated. Figure 5 and Figure 6 What is shown is the real-time code coverage of the two methods for small-scale contracts and large-scale contract detection respectively.

[0094] The method used in the present invention has the highest code coverage of 89% and 82% for small-scale and large-scale contracts, respectively. The coverage of sFuzz for contracts is below 30%. At the same time, it was found that sFuzz converged too early. In a small-scale contract set, the coverage trend was basically flat after 20s. The smart contract vulnerability detection method based on hybrid fuzz testing optimization achieved a new breakthrough in coverage after 25s. Analyzing the working principle behind it, it is speculated that because sFuzz adopts a seed selection strategy based on branch distance, the test case may gradually shorten the distance to certain branches, but it may not be able to capture the complex path to the global optimal solution, thus falling into the local optimal solution, resulting in no further optimization. Differently, the smart contract vulnerability detection method based on hybrid fuzz testing optimization uses symbolic execution technology to generate new test cases by solving constraint expressions, which is not limited to the "evolution" of existing test cases, thereby avoiding falling into the local optimal situation under complex conditions. However, because it involves constraint solving, it takes more time to achieve higher code coverage.

[0095] Regarding whether the smart contract vulnerability detection method based on hybrid fuzz testing optimization can more effectively detect permission control smart contract vulnerabilities, denial of service smart contract vulnerabilities and transaction order dependency smart contract vulnerabilities in smart contracts, according to the detection report results of each method on data set 2, the TP, FP and FN of each vulnerability type are calculated, and the FDR, FNR, precision, recall and F1 score of each vulnerability type are calculated. The specific results are shown in Table 8. As can be seen from the table, compared with other methods, the smart contract vulnerability detection method based on hybrid fuzz testing optimization can correctly detect the largest number of vulnerabilities and the least number of false positives and false negatives. For example, for the denial of service smart contract vulnerability (Dos), its precision is 95.8%, which is 20.8% higher than Mythril. At the same time, it is noted that for the permission control smart contract vulnerability (AC), although sFuzz using dynamic fuzz testing achieves 0 false positives, its false negative rate is as high as 78.5%, and it can only detect the dangerous situation of unauthorized delegate calls.

[0096] Table 8 Comparison of evaluation indicators of different vulnerability detection methods

[0097] Compared with other detection methods, the present invention can detect smart contract vulnerabilities more effectively. Analysis shows that the present invention can achieve better detection results because of the following two points: On the one hand, the present invention combines symbolic execution with a hybrid fuzzy testing method to improve code coverage, so that it can capture more vulnerabilities. On the other hand, a better test oracle is designed and taint analysis technology is introduced to reduce false positives.

[0098] In summary, the present invention proposes a smart contract vulnerability detection method and system based on hybrid fuzz testing optimization, which is used to detect permission control smart contract vulnerabilities, denial of service smart contract vulnerabilities and transaction order dependency smart contract vulnerabilities in smart contract vulnerabilities. First, the smart contract is statically analyzed to obtain the ABI interface parameter type and transaction order to generate test cases to start fuzz testing, and the taint analysis technology is used to track the propagation of data in the instruction stream. Monitor the changes in the contract code coverage during the fuzzy process, and use the current test case as input for dynamic symbolic execution when it no longer changes. Then, the constraint cache reuse strategy is adopted to solve the constraints, so that symbolic execution can quickly generate use case values ​​that reach complex branches, and feedback to the fuzzy engine to assist it in exploring new paths. Finally, the test predictions of three vulnerabilities of permission control, transaction order dependency, and denial of service are defined, and detailed vulnerability information reports are generated by analyzing the contract execution log and taint records. Experiments are conducted on a data set of more than 1,000 real Ethereum smart contracts to evaluate the vulnerability detection effect. Experimental results show that, compared with other tools, the method used in the present invention can detect more vulnerabilities and the detection effect is more accurate; at the same time, the average code coverage is as high as 85%, which is about 3 times that of the more advanced tool sFuzz.

Claims

1. A smart contract vulnerability detection method based on hybrid fuzzy testing optimization, characterized in that: The following steps are involved: S1. Obtain the source code of the smart contract, compile it to obtain EVM bytecode, perform static analysis on the EVM bytecode, and obtain the ABI interface parameter type and function call sequence based on the read-write dependency relationship between functions in the bytecode and the source code corresponding to the function; S2. Generate a first test case set based on the ABI interface parameter type and function call sequence, perform fuzz testing on the EVM bytecode based on the first test case set, obtain the number of all instructions covered by each test case when the instruction is executed, and construct an instruction count set; perform symbolic execution processing when the length change value of the instruction count set is 0 according to the length change of the instruction count set within the set execution number threshold, The symbolic execution processing operation is specifically as follows: setting the branch when the instruction count set length change value is 0 as the target branch point, only obtaining the arithmetic instructions and logic instructions of all branch constraints on each execution path when the instruction is executed to the target branch point, converting them into constraint expressions through symbolic processing, and collecting the constraint expressions to construct a path constraint set; After negating the constraint expression, perform constraint solving, cache and reuse the constraint expression and its solution results in the constraint solving, obtain a specific input value that satisfies the branch constraint condition where the target branch point is located, update the specific input value as a new test case to the first test case set, obtain a second test case set, execute S2 in a loop, expand the second test case set, until the set time is reached, terminate the loop, and execute S3; S3. Setting different test predictions for different smart contract vulnerabilities, including permission control, transaction sequence dependency, and denial of service smart contract vulnerabilities; Based on the test oracle, the second test case set is used in combination with taint analysis to detect smart contract vulnerabilities and obtain vulnerability detection results.

2. The smart contract vulnerability detection method based on hybrid fuzzy testing optimization according to claim 1 is characterized in that: The taint analysis in S3 is specifically to perform taint analysis on the EVM bytecode based on the set taint propagation rules to obtain the propagation of taint data in the instruction stream, specifically: Obtain function call parameters and transaction data instructions in the EVM bytecode, including CALLDATALOAD, CALLDATACOPY, SLOAD, CALLER, ORIGIN, and CALLVALUE instructions, and mark the instructions and their return values ​​as tainted; Set CALL, SSTORE, JUMPI, ISZERO, SELFDESTRUCT, and DELEGATECALL instructions as taint sinks; When different instructions are executed, the taint propagation is tracked based on the taint propagation rules, specifically: For unary or multiary arithmetic instructions and logical instructions, if any operand contains taint, the result value obtained after executing the instruction will be marked as tainted. For instructions that query the blockchain status and instructions that do not affect the execution and status of the contract, they are marked as fixed instructions that are not considered tainted. For instructions that read data from memory or storage, if the instruction contains taint, the result value read is marked as tainted; Based on the propagation of taint to taint sink, the propagation path of taint in the instruction stream of EVM bytecode is obtained, and the vulnerability detection result is obtained based on the propagation path.

3. The smart contract vulnerability detection method based on hybrid fuzzy testing optimization according to claim 1 is characterized in that: In S2, the constraint expressions and their solution results are cached and reused in constraint solving. The specific operations are as follows: a visited set is built based on the visited constraint expressions, a dictionary is built based on the solved constraint expressions and their solution results for caching, and the corresponding unique hash value is obtained as the key based on each constraint expression after the inversion operation: When solving a constraint expression, if the corresponding key exists in the dictionary, the solution result in the dictionary is reused, otherwise the constraint solution is reset; Traverse all constraint expressions except the last one in the path constraint set, add unvisited constraint expressions to the visited set, perform constraint solving after negating them, and cache the solution results in the dictionary.

4. The smart contract vulnerability detection method based on hybrid fuzzy testing optimization according to claim 1 is characterized in that: The test prediction set for the vulnerability of the permission control smart contract in S3 is specifically expressed as follows: For permission control smart contract vulnerabilities caused by incorrect permission configuration and lack of permission authorization check control, the test prediction is set as follows: ErrorPermission ∨( ExistDangerousI ∧ NoPCP ), The first of these prophecies ErrorPermission Detect whether there is a permission configuration error in the smart contract. When the name of the non-standard constructor that sets the permission function of the smart contract owner is inconsistent with the name of the smart contract, judge ErrorPermission is true; The Second Sub-Prophecy ExistDangerousI Detect whether there is a lack of permission authorization check in the smart contract, that is, whether there is tainted data from unauthorized users propagated to the SELFDESTRUCT and DELEGATECALL instructions. If so, judge ExistDangerousI is true; The Third Sub-Prophecy NoPCP Check whether there is a permission constraint mode, if so, judge NoPCP is false; when ErrorPermission True or ExistDangerousI , NoPCP When both are true at the same time, the test prediction is true and there is a permission control smart contract vulnerability.

5. The smart contract vulnerability detection method based on hybrid fuzzy testing optimization according to claim 4 is characterized in that: The permission constraint mode is determined to determine whether the following taint analysis process exists: Use the marked tainted instructions SLOAD and CALLER to load the smart contract owner address and the smart contract caller address respectively, and compare the two addresses to determine whether they are equal. If they are equal, the execution continues via the tainted sink instruction JUMPI. If they are not equal, the JUMPI operation jumps to REVERT to end the execution; If the above taint analysis process exists, it is determined that a permission constraint mode exists.

6. The smart contract vulnerability detection method based on hybrid fuzzy testing optimization according to claim 1 is characterized in that: The test prediction set in S3 for the denial of service smart contract vulnerability is as follows: For the denial of service smart contract vulnerability caused by gas limit and external call failure, the test oracle is set as: ExistUnLoop ∨( ExistCallException ∧ UnhandledPreTermination ), The neutron prophecy ExistUnLoop Check if the smart contract contains unbounded loop conditions that can be determined by external input. If so, ExistUnLoop True; Sub-prophecy ExistCallException Check whether the smart contract has an exception of external call failure. If so, ExistCallException True; Sub-prophecy UnhandledPreTermination Check whether the exception is handled before the smart contract terminates. If not, UnhandledPreTermination is true; when ExistUnLoop True or ExistCallException , UnhandledPreTermination When both are true, the test oracle is true and there is a denial of service smart contract vulnerability.

7. The smart contract vulnerability detection method based on hybrid fuzzy testing optimization according to claim 6 is characterized in that: Whether the smart contract contains an unbounded loop condition that can be determined by external input is determined as follows: Based on the external input taint, when it propagates to the JUMPI instruction and the ISZERO instruction, the ISZERO instruction takes the top element of the stack and makes a conditional judgment on it. If the judgment is true, it guides the JUMPI instruction to jump and judge whether the position of the JUMPI instruction jump is the same as the position of the previous jump. If they are the same, then the JUMPI instruction is determined to jump back to the loop body, and there is an unbounded loop condition that can be determined by external input.

8. The smart contract vulnerability detection method based on hybrid fuzzy testing optimization according to claim 1 is characterized in that: The test oracle set in S3 for the transaction sequence dependency smart contract vulnerability is as follows: ExistConflictingTransactions ,If there is a read-write conflict in the storage location of the same variable in the smart contract, the same variable is modified by exchanges from different senders, the test prediction is true, and there is a transaction order dependent smart contract vulnerability.

9. The smart contract vulnerability detection method based on hybrid fuzzy testing optimization according to claim 1 is characterized in that: In the S2, the number of all instructions covered by each test case during instruction execution is obtained, and an instruction count set is constructed, specifically: during the fuzz testing process, the program counter is set to point to the address of the currently executed instruction of the EVM bytecode, the program counter value is obtained, and the instruction count set is constructed based on the program counter value; the instruction execution path of each test case is traversed, and the program counter value of each executed instruction is updated to the instruction count set.

10. A smart contract vulnerability detection system based on hybrid fuzzy testing optimization, characterized in that: include: Static analysis module: used to obtain the source code of the smart contract, compile it to obtain EVM bytecode, perform static analysis on the EVM bytecode, and obtain the ABI interface parameter type and function call sequence based on the read-write dependency relationship between functions in the bytecode and the source code corresponding to the function; Fuzzy processing module: used to generate a first test case set based on the ABI interface parameter type and function call sequence, perform fuzzy testing on the EVM bytecode based on the first test case set, obtain the number of all instructions covered by each test case when the instruction is executed, and build an instruction count set; according to the length change of the instruction count set within the set execution number threshold, perform symbolic execution processing when the length change value is 0, The symbolic execution processing operation is specifically as follows: setting the branch when the instruction count set length change value is 0 as the target branch point, only obtaining the arithmetic instructions and logic instructions of all branch constraints on each execution path when the instruction is executed to the target branch point, converting them into constraint expressions through symbolic processing, and collecting the constraint expressions to construct a path constraint set; After negating the constraint expression, constraint solving is performed. In the constraint solving, the constraint expression and its solution are cached and reused to obtain a specific input value that satisfies the branch constraint condition of the target branch point. The specific input value is updated as a new test case to the first test case set to obtain a second test case set. The fuzzy processing module is executed in a loop to expand the second test case set until a set time is reached, the loop is terminated, and the vulnerability detection module is executed. Vulnerability detection module: used to set different test predictions for different smart contract vulnerabilities, including permission control, transaction sequence dependency, and denial of service smart contract vulnerabilities; Based on the test oracle, the second test case set is used in combination with taint analysis to detect smart contract vulnerabilities and obtain vulnerability detection results.

Citation Information

Patent Citations

  • Method for improving smart contract detection coverage rate, electronic equipment and storage medium

    CN115292172A

  • Intelligent contract fuzzy test method and system

    CN115794625A

  • Intelligent contract denial of service vulnerability detection method based on symbolic execution constraint optimization

    CN117150497A

  • Intelligent contract vulnerability detection method and system based on hybrid fuzzy test

    CN117828616A

  • Intelligent contract vulnerability detection method based on combination of static analysis and fuzzy testing

    CN117951712A

Cited By

  • Smart contract vulnerability detection method and system based on taint analysis

    CN120197178A

  • Unmanned aerial vehicle configuration error fuzzy test method and system based on check points

    CN120336185A

  • Checkpoint-based drone misconfiguration fuzzing method and system

    CN120336185B

  • Data transmission protocol constraint-aware firmware fuzz testing method and related equipment

    CN122346438A