EP4612581A1 - A computer-implemented method for generating an automata-guided fuzz driver and fuzzing method using the fuzz driver - Google Patents

A computer-implemented method for generating an automata-guided fuzz driver and fuzzing method using the fuzz driver

Info

Publication number
EP4612581A1
EP4612581A1 EP23794334.5A EP23794334A EP4612581A1 EP 4612581 A1 EP4612581 A1 EP 4612581A1 EP 23794334 A EP23794334 A EP 23794334A EP 4612581 A1 EP4612581 A1 EP 4612581A1
Authority
EP
European Patent Office
Prior art keywords
fuzz
driver
data
automaton
usage
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
EP23794334.5A
Other languages
German (de)
French (fr)
Inventor
Cen ZHANG
Yuekang LI
Yaowen ZHENG
Yang Liu
Sheikh Habib MAHBUB
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Aumovio Germany GmbH
Nanyang Technological University
Original Assignee
Continental Automotive Technologies GmbH
Nanyang Technological University
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Continental Automotive Technologies GmbH, Nanyang Technological University filed Critical Continental Automotive Technologies GmbH
Publication of EP4612581A1 publication Critical patent/EP4612581A1/en
Pending legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/70Software maintenance or management
    • G06F8/75Structural analysis for program understanding
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Prevention of errors by analysis, debugging or testing of software
    • G06F11/3604Analysis of software for verifying properties of programs
    • G06F11/3608Analysis of software for verifying properties of programs using formal methods, e.g. model checking, abstract interpretation
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Prevention of errors by analysis, debugging or testing of software
    • G06F11/3668Testing of software
    • G06F11/3672Test management
    • G06F11/3676Test management for coverage analysis
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Prevention of errors by analysis, debugging or testing of software
    • G06F11/3668Testing of software
    • G06F11/3672Test management
    • G06F11/3684Test management for test design, e.g. generating new test cases
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Prevention of errors by analysis, debugging or testing of software
    • G06F11/3668Testing of software
    • G06F11/3672Test management
    • G06F11/3688Test management for test execution, e.g. scheduling of test suites
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/57Certifying or maintaining trusted computer platforms, e.g. secure boots or power-downs, version controls, system software checks, secure updates or assessing vulnerabilities
    • G06F21/577Assessing vulnerabilities and evaluating computer system security
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Prevention of errors by analysis, debugging or testing of software
    • G06F11/3668Testing of software
    • G06F11/3696Methods or tools to render software testable
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F2221/00Indexing scheme relating to security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F2221/03Indexing scheme relating to G06F21/50, monitoring users, programs or devices to maintain the integrity of platforms
    • G06F2221/033Test or assess software

Definitions

  • the invention provides a computer-implemented method for generating an automaton-guided fuzz driver for non-executable library data that include at least one API function.
  • Fuzzing is a practical dynamic analysis technique for vulnerability detection.
  • fuzzing can produce more precise results with fewer false-positives (FP) and allows security analysts to replay bugs for Proof- of-Concept.
  • FP false-positives
  • fuzzing requires an executable of the target software as the testing subject.
  • fuzz libraries executable programs using the library functions must first be generated. Conventionally, these programs are called fuzz harnesses or fuzz drivers.
  • Fuzz drivers can be composed manually by human experts or generated automatically by tools. To compose fuzz drivers, experts typically have to learn the usage of library APIs from documentations or example programs. Not only is this learning process tedious and time-consuming, but also the quality of the composed fuzz drivers heavily depends on the experience of the human experts. Therefore, techniques for automatically generating fuzz drivers are desired.
  • Another challenge can be that the learned API usage of existing works may suffer from noises such as redundant API calls or wrong API dependencies. Failing to remove the noises can limit the usability of a fuzz driver generation technique especially when it needs to learn from complex realworld consumer programs.
  • Yet another challenge can be that multiple fuzz drivers can be generated for a single target library with existing works, but how to organize and utilize these fuzz drivers to increase confidence that they can be substantially tested by the fuzzer is understudied. Poorly organized fuzz drivers can distract the fuzzer and hinder the fuzzing performance.
  • the invention provides a computer-implemented method for generating an automaton-guided fuzz driver for non-executable library data that include at least one API function, the method comprising: a) with a learning input extraction means: extracting learning input data from a nonexecutable target library and at least one executable computer program that uses the target library, wherein the learning input data are configured to allow training of an automaton; b) with an automaton generation means: generating at least one non-determ inistic finite automaton (NFA) based on the learning input data, wherein each NFA is associated with one program function of the computer program, and performing a learning method on the at least one NFA that is based on the learning input data in order to obtain a usage automaton that includes information about the a control flow graph of the target library and the computer program; c) with a fuzz driver synthesizing means: synthesizing a fuzz driver based on the usage automaton, wherein the fuzz driver is synthesized to include the usage automaton, and the fu
  • the learning input extraction means extracts the learning data by static analysis.
  • the learning input extraction means extracts learning data that include event sequence data that are indicative of control flow information.
  • the learning input extraction means extracts learning data that include API data depdency information that are indicative of possible values for arguments of API functions and/or data linkages between API functions.
  • the learning input extraction means extracts learning data that include API meta information that are indicative of basic information of an API function, such as function signature, type of argument(s), and/or type of return value.
  • the automaton generation means unifies the alphabet of each NFA obtained in step b) by associating a unique identifier with each unique event.
  • the automaton generation means distills an event sequence for each NFA by applying an L* algorithm.
  • the automation generation means merges the previously obtained NFAs into the usage automaton, preferably into a single usage automaton, by applying a deterministic finite automata (DFA) combination and minimization algorithm to the previously obtained NFAs.
  • DFA deterministic finite automata
  • the fuzz driver synthesizing means synthesizes the fuzz driver so as to include a plurality of fuzzing scenarios that are selectable by the fuzzer.
  • the fuzz driver synthesizing means synthesizes the fuzz driver so as to include a scheduling interface for a greybox fuzzer.
  • the invention provides a computer-implemented method for fuzzing non-executable library data that are used in at least one executable computer program: a) performing a preferred method with the library data and the at least one computer program in order to generate a fuzz driver for the library data; b) with a fuzzer: fuzzing the library data by means of the fuzz driver and the at least computer program in order to obtain fuzzing results.
  • the invention provides a data processing apparatus comprising means to carry out a preferred method.
  • the invention provides a computer program that includes instructions that, when executed on a data processing means, cause the data processing means to carry out a preferred method.
  • the invention provides a computer-readable storage medium or data carrier signal that includes the computer program.
  • a method for generating an automata-guided controlflowsensitive fuzz driver is disclosed.
  • One concept used in the technique is the API usage automaton (or usage automaton in short), which can represent the control dependencies among the APIs. Therefore, the method is able to increase test coverage.
  • the disclosed idea can reduce or even eliminate the noises which would otherwise limit the effectiveness of fuzzing.
  • a data extractor extracts data and control dependency information of the API functions preferably by static analysis. Specifically, the control flow information can be used to build the usage automaton. The data flow information can be used together with the usage automaton to synthesize the fuzz driver.
  • the L* algorithm can be used to build and/or refine the usage automaton.
  • a fuzz driver generator can generates a single automata- guided fuzz driver as its output.
  • the fuzz driver can operate as an automata interpretation engine.
  • This fuzz driver may encode all the control-flow and data-flow information learned from the consumer programs and coordinate with the fuzzer so that the library APIs can be tested with improved coverage.
  • the improvement may include larger overall coverage and/or larger overall coverage per unit time. In other words, computational efficiency may be increased.
  • fuzz drivers have an overall significant better performance. It is possible to learn from practical example programs. Furthermore, a better scheduling interface can be provided for the fuzzer. In contrast to known approaches, the generated fuzz drivers are able to contain control flow dependencies like branches and loops.
  • the fuzz driver may contain necessary branches and loops in order to invoke every API function of the target library correctly. Branches and loops are deemed necessary when their condition expressions have direct data dependencies with the output of API functions. The rationale is that if the execution of a branch or loop is not affected by any other API function, it is typically not affected by mutated input. Likely, excluding such branch or loop will not affect the performance of fuzzing. In practice, the desired fuzz driver is capable of describing most useful API usage patterns, e.g., state checking, objects iteration, etc.
  • Fig. 1 depicts an embodiment of a method according to the invention
  • Fig. 2 illustrates different inputs and outputs of the method steps
  • Fig. 3 illustrates difficult scenarios
  • Fig. 5 exemplify certain algorithms
  • Fig. 16 illustrate experimental results of the disclosed method.
  • a learning input extraction means extracts learning materials from at least one computer programs 12 that uses a target library 14.
  • the learning materials may include event sequences represented as a raw non-determ inistic finite automata (NFA) 16, API data dependencies 18, and API meta information 20.
  • the API meta information 20 refers to the basic information of API functions, e.g., the function signature, the type of arguments and return value, etc. Its collection is straightforward and is done once per library.
  • the method collects the learning inputs from consumer programs 12 by static analysis.
  • the learning input extractin means requires no a priori knowledge about the target library 14.
  • the learning input extracting means collects the candidate events and event sequences as NFAs 16; the API data dependencies 18; the API meta information 20.
  • CFG control flow graph
  • NFA 16 uses the above mentioned events as alphabets.
  • the method collects data dependencies between two API functions and between an API function and a constant.
  • the these can be represented as the tuple ( Provider, Consumer ) where the provider can be any output of an API function or a constant and the consumer can be any input needed by an API function. They are collected together with raw NFAs 16 by statically analyzing the consumer programs.
  • API meta information which is the basic information of API functions, e.g., the function signature, the type of arguments and return value, etc. This is done only once per target library 14.
  • a learning process is performed.
  • the second step S12 has three elements that are performed by an automaton generation means.
  • the automaton generation means first performs alphabet unification 22 among all raw NFAs 16.
  • the automaton generation means performs usage destination 24 to refine the raw NFAs 16.
  • the algorithm takes each raw NFA 16 as input and outputs a minimized DFA containing the valid event sequences.
  • the automaton generation means performs automata merging 25 of these DFAs as a single usage automaton 26.
  • the goal of alphabet unification 22 is to name each unique event a different letter.
  • the automaton generation means assigns the letters according to their function signatures.
  • the automaton generation means needs to align their condition expressions and solve the potential conflicts before assigning letters.
  • the automaton generation means parses these expressions as first-order logical formulas to check their identity.
  • the goal of usage distillation 24 is to prune incorrect event sequences of the raw NFAs 16 while removing redundancies at the same time.
  • the process is similar to the water distillation process, it first turns the raw NFA 16 to the form of event sequences (boils the water until it becomes water vapour), then removes the incorrect event sequences based on some criteria (removes impurities based on different boiling points), and summarizes it back to a minimized automaton (condense vapour back to water).
  • the automaton generating means uses an L* based algorithm for usage distillation 24 of the event sequences.
  • the usage distillation 24 may infer a minimized deterministic finite automaton (DFA) describing the valid event sequences inside each Raw NFA 16.
  • DFA minimized deterministic finite automaton
  • the automaton generating means merges these DFAs as one usage automaton 26 using DFA combination and minimization algorithms. These algorithms, such as the Hopcroft’s DFA minimization algorithm, have reasonable time complexity.
  • a fuzz driver synthesizing means performs code synthesis 28 and synthesizes the automata-guided fuzz driver 10 based on the usage automaton 26.
  • the invention synthesizes one automata-guided fuzz driver 10 where the fuzzer can pick the usage scenario it favors by providing different values to the leading bytes of the input.
  • the fuzz driver 10 is designed as event-driven. The fuzz driver 10 loads the usage automaton 26 and maintains its states at runtime. For each execution, the fuzz driver 10 starts from the initial state.
  • the fuzz driver 10 tries to traverse the usage automaton 26 until there are no successor states. In each step of the traverse, the fuzz driver 10 first searches the usage automaton 26 for the next possible events and picks one from them. After that, the fuzz driver 10 executes the code representing the picked event, and updates the status of the usage automaton 26 accordingly. Picking which event can be determined by either the input of fuzzer or the runtime information.
  • the method can automatically generate the fuzz driver 10.
  • the fuzz driver 10 is a functional component for conducting fuzz testing towards software, especially for library targets.
  • the invention can help to automatically generate the candidate fuzz drivers.
  • this idea can be integrated into their dynamic analysis tool set. Once they identify an attack surface of a given software, they can use the generation method described herein to automatically generate the fuzz drivers for conducting fuzz testings. Therefore, the attack surface can be fuzzed based on the fuzz driver generated by the invention.
  • a usage automaton is typically a deterministic finite automaton (DFA) having a finite set of states Q, a set of input symbols called the alphabet 2, a transition function 8: Q x 2 Q, an initial state q 0 e Q and a set of final states F c Q_
  • DFA deterministic finite automaton
  • An event is preferably labeled as a letter (input symbol) and an event sequence is marked as a string that includes the letters that represent the events in the event sequence.
  • the API usage is represented as a set of strings.
  • the DFA may act as an acceptor of a set of strings.
  • the DFA may contain two types of events: function events and condition events.
  • a function event may represent an action which calls an API function and updates the value of its output variables, if any.
  • a new variable can be assigned for each output of the API function.
  • a condition event may represent an action that the current value of a variable expression satisfies a certain constraint.
  • a mock API function event can be used, which calls a mock API defined the fuzz driver.
  • the usage automaton can transit itself from one state to another.
  • the learning algorithm may merge two states if all their subsequent transitions are the same.
  • the automaton preferably starts from the initial state, and the events along the path from initial state to any final state form a valid event sequence, i.e. , a valid usage to invoke the API functions.
  • the branches and loops may have direct mappings in the graph structure of the usage automaton, e.g., forks and loops.
  • the usage automaton has a property that no initial state can be a final state. In this case empty usage is treated as invalid usage, thereby saving computational parts.
  • any non-empty prefix of a valid event sequence can be a valid event sequence. For example, given a sequence designated as AHI is deemed valid, then the prefix sequence AH is also deemed valid.
  • any event sequence containing a non-empty invalid prefix is deemed invalid. For instance, if a sequence AIH is deemed invalid, then any event sequence starting with AIH is also deemed invalid.
  • the initials stat property and/or the prefix validity property can be used to infer the validity of unchecked event sequences, which allows an improvement of the distillation process.
  • the method collects learning inputs from consumer programs via static analysis. Note that no a priori knowledge about the target library is required. Given a library, the method collects: the candidate events and event sequences; the API data dependencies; the API meta information.
  • the API meta information refers to the basic information of API functions, e.g., the function signature, the type of arguments and return value, etc. Its collection is straightforward and is done once per library. In the following, only the collection of the other learning inputs is explained in more detail.
  • the method preferably extracts event sequences from the consumer programs by converting its control flow graph (CFG) into a non-determinisitic finite automaton (NFA). This can be done by translating some instructions into events and removing the irrelevant instructions.
  • CFG control flow graph
  • NFA non-determinisitic finite automaton
  • condition expressions only consist of constants and the variables storing outputs of the API functions.
  • the method may conduct taint propagation marking the outputs of the API functions as taint sources. Once a condition expression of a branch instruction is tainted, two condition events can be generated for both true and false branch.
  • Loop Case I by introducing I and J as mock API function events, necessary data flow propagations (hasNext and getNext) are kept.
  • Loop Case II introduces I and J to describe the data flow propagation of i.
  • the method may use a two-pass extraction to handle all scenarios.
  • the first pass may taint propagation as previous scenario.
  • the method preferably checks whether the collected condition expressions contain variables of the control dependencies scenario. If variables are contained, the method may redo the extraction but preferably additionally marks the definition of these variables as taint sources. Any value update of these variables will be identified as a mock API function event.
  • Fig. 4 shows Algorithm 1 of a single-pass extraction process.
  • the method may extract a raw usage automaton (namely Raw NFA) for each function inside the consumer program. This is feasible since the subsequent learning process will remove the invalid or the redundant usages.
  • the basic idea behind the extraction is to build the Raw NFA along the traverse of the interprocedural control-flow graph (ICFG). The traverse starts from the entry instruction of target function Ftarget.
  • Line 7 - 27 shows the analysis of each traversed instruction, curl points to the instruction under analysis.
  • curS points to the state in Raw NFA which new states should be linked with, ctxt holds the taint information for analyzing curl.
  • the method may extract the Raw NFA of the callee (subA) and merges it into current NFA (A). The merge is accomplished by adding a transition from curS to the start state (starts) of subA with epsilon event e and adjusting the curS to point to the end state (endS) of subA. If curl is not of the above case, the event identification strategies are applied.
  • a new transition will be added to A once a new event is identified, and curS also will be updated.
  • Last the successors of curl are added to Q for analysis. If curl is an exit point of the function , e.g., return, the edge from curS to endS is added. If a successor instruction is already analyzed, a transition from curS to the instruction’s corresponding state under event e is added.
  • the algorithm only shows the key flow. In implementation, the algorithm also maintains a stack to prevent the infinite loop caused by the recursive call of the target function. Besides, multiple callees may be returned by iCFG.getCallee in line 9, the method preferably picks the first one by default.
  • the extracted automaton is named as Raw NFA since it contains e and can have multiple transitions given one specific state and event, e.g., same events can be identified in both paths of a branch.
  • the extracted Raw NFA contains control flow information of the fuzz driver, such as the correct order of API functions, or the condition to call an API function, etc.
  • API data dependencies indicate the possible values for arguments of API functions, or the data linkages between API functions. Both are typically needed information for generating a valid fuzz driver.
  • one set of control flow usage can have multiple sets of data dependencies. For example, given three API functions FA, FB, FC, and assuming the return values of both FA and FB can be used as the first argument of Fc, the control flow usage FA — > FB — > Fc has two sets of data dependencies: Fc can use the return value of either FA or FB.
  • the method may collect data dependencies between two API functions and between an API function and a constant. Specifically, the method may abstract them as the tuple ( Provider, Consumer ) where Provider can be any output of an API function or a constant and the consumer can be any input needed by an API function. They are collected together with Raw NFAs by statically analyzing the consumer programs.
  • the learning process has three steps. First, it unifies the alphabet among all Raw NFAs. Next, a distillation algorithm is applied to refine the Raw NFAs. Specifically, the algorithm takes each Raw NFA as input and outputs a minimized DFA containing the valid event sequences. Lastly, the method merges these DFAs as a single usage automaton.
  • the goal of alphabet unification is to name each unique event a different letter.
  • the method assigns the letters according to their function signatures.
  • the method parses these expressions as first-order logical formulas to check their identity.
  • the method may assign letters to these four events and may replace the original events in their NFAs.
  • An identity check can be useful but the conflict case rarely happens.
  • the method preferably compares their identity by group. Specifically, a group of events contain all related events affecting the loop condition. Two groups are identical if their loop condition expressions, the value update expression of the mocked API functions, and the execution order of these events are equal. Otherwise, the method may assign different sets of letters to them.
  • the goal of usage distillation is to prune the incorrect event sequences of the Raw NFAs while remove the redundancies at the same time.
  • the process is similar to the water distillation process, it first turns the Raw NFA to the form of event sequences (boils the water until it becomes water vapour), then removes the incorrect event sequences based on some criteria (removes impurities based on different boiling points), and summarizes it back to a minimized automaton (condense vapour back to water).
  • Various automata learning algorithms including both active and passive learning, are good candidates.
  • active learning is more suitable than passive learning:
  • the number of positive examples (represents for valid event sequences, abbr as PE) and negative examples (represents for invalid event sequences, abbr as NE) can be infinite.
  • the passive learning algorithm which accepts a finite number of PEs and NEs, how to select a good subset from the infinite PEs/NEs which maximizes the learning effects is a challenge.
  • the active learning algorithm supports infinite amounts of learning inputs by nature and using them does not have the above concern.
  • the method preferably answers two types of queries: membership query and equivalence query.
  • membership query the method answers the correctness of the queried event sequence.
  • Fig. 5 that illustrates Algorithm 2 shows the detailed process. The idea is that an event sequence is valid if it satisfies the following three requirements: there is no unsolved data dependencies for all API functions (line 8); its dynamic execution can end up without error (line 9); it has all required properties of being a desired fuzz driver (line 7).
  • the method preferably iterates all events of a given event sequence and checks whether the prefix of each event has already initialized the variables used in that event. If the check fails, the event sequence is invalid since the fuzz driver based on it will have uninitialized variables.
  • the method first converts the event sequence to a fuzz driver.
  • the fuzz driver comes from a single event sequence, therefore it is a sequence of API calls and condition checks without loops. During the execution, if the condition is not satisfied, the execution is stopped and the event sequence is partially tested.
  • the method optimistically treats the untested parts as correct.
  • the effectiveness of dynamic validation is influenced by the diversity of the input files. The more diverse the input files are, the more effective the dynamic validation can be. In practice, we use one to three valid input seeds in the dynamic validation.
  • the method has two limitations to a valid event sequence. First, it limits that the condition event can only appear after the value of its condition expression has been updated by other events. The rationale is that since an event sequence which contains a dead loop of a condition event is valid but not desired usage. Second, it also limits that the API function which accepts the input file should appear once and only once.
  • the method preferably uses wp-method (known from F. B. Khendek, et al., Test selection based on finite state models. IEEE Transactions on software engineering, 17(591 -603): 10-1109, 1991.) to sample a test set of the automaton.
  • the learned automaton is satisfying if no counterexample can be found in the test set.
  • a counterexample consists of an event sequence and its correctness. It points out the error of current automaton, where the automaton either accepts an incorrect event sequence or refuses a correct event sequence.
  • the method chooses wp-method since it generates a slightly smaller test set than w-method while keeping similar representativeness. In practice, the method may set the lookahead value as 2.
  • the algorithm iteratively proposes possible automaton after certain rounds of membership queries and improves the automaton based on the counterexample provided by the equivalence query.
  • the method removes dead loops and trap states of the output automaton.
  • a dead loop is a loop which does not contain any condition event. Besides, removing the trap states and the related transitions simplifies the automaton while keeping its accepted event sequences.
  • the method uses DFA combination and minimization algorithms to generate the final usage automaton from the distilled ones. These algorithms, such as the Hopcroft’s DFA minimization algorithm (known from M. Isberner, F. Howar, and B. Steffen. The open-source learnlib. In D. Kroening and C. S.
  • the method synthesizes a fuzz driver based on the learned usage automaton.
  • the synthesis is nontrivial since the learned usage can inevitably contain multiple independent usage scenarios.
  • the disclosed method synthesizes an automata-guided fuzz driver where the fuzzer can pick the usage scenario it favors by providing different values to the leading bytes of the input.
  • the method uses a DFS-based algorithm to count all independent usage scenarios inside the target automaton.
  • the fuzz driver is designed as event-driven. It loads the usage automaton and maintains its states at runtime. For each execution, it starts from the initial state. Then it tries to traverse the automaton until there has no successor states. In each step of the traverse, it first searches the automaton for the next possible events and picks one from them.
  • the code representing the picked event After that, it executes the code representing the picked event, and updates the status of the automaton accordingly.
  • Picking which event can be determined by either the input of fuzzer or the runtime information. If the next events belong to multiple usage scenarios, the pick is determined by input, e.g., state 1 in Fig. 1.e), choosing B or H depends on the input. Otherwise, it should be determined by the runtime information, e.g., state 3 in Fig. 1 .e), choosing y or n depends on the runtime value of ret_E.
  • the method provides a scheduling interface to greybox fuzzers for better utilization of the learned usage.
  • evaluation several strategies and setups of the scheduling interface are discussed and compared. Results show that this interface can influence the fuzzing performance significantly. Besides, randomly assign a value to the leading bytes of all input seeds is a recommended default setup.
  • the main components of the computer-implementation of the method contain 6,979 lines of java code, 1 ,656 lines of python code, and 654 lines of bash scripts.
  • java code includes most functionalities such as the learning inputs collection, usage distillation, fuzz driver synthesis, etc.
  • the python code is mainly used for alphabet unification.
  • the bash scripts are used for gluing the workflow.
  • automata related algorithms are developed upon learnlib (M. Isberner, F. Howar, and B. Steffen. The open-source learnlib. In D. Kroening and C. S. Pasareanu, editors, Computer Aided Verification, pages 487-495, Cham, 2015. Springer International Publishing.), and the first-order logical formulas related algorithms are developed upon z3py.
  • the implementation needs to retrieve dynamic information of a specific API usage (i.e., an event sequence). Initially, for each usage, the implementation retrieves its dynamic information using three steps: conversion from usage to code; code compilation; code execution. Besides, on-the-fly compilation technique is used to reduce the costs. However, the learning costs are still too high since the amount of the queries (excluding the cached queries) can be more than millions when handling some complex raw NFAs. To solve this, a model- interpretation-based execution was used.
  • the basic idea is that one compilation per API usage is unnecessary.
  • the API usage can be fed in as data.
  • the interpreter translates the usage into real actions (e.g., calls an API, updates a variable, etc) to retrieve the dynamic information.
  • a general interpreter can be generated. This saves almost all compilation costs.
  • the implementation can test thousands to tens of thousands API usage scenarios per second, which is thousands of times faster than the other approaches.
  • the method is evaluated on six attack surfaces identified from six popular java libraries, namely apa triber, apachepoi, itextpdf, junrar, pdfbox and zip4j.
  • the overall selection criteria is to cover different types of vendors, input formats, and cover attack surfaces at different scales.
  • the libraries and attack surfaces have a many-to-many relationship. Multiple attack surfaces inside one library are separated by the input formats they accept. For example, for apachepoi and apaginar, their libraries provide APIs to parse 12 and 22 different types of input formats, which means that they have 12 and 22 attack surfaces respectively. For these libraries, we pick the attack surface which accepts a popular input format.
  • a crawler To apply the method on these attack surfaces, we first build a crawler to collect the consumer programs. The crawler first locates the open-source projects which use the attack surface, then retrieves jars of these projects as the method input. Specifically, a project is a consumer program if its code contains the package path of the attack surface, e.g., com.github.junrar.
  • src a CLI tool of Sourcegraph, to launch the match query among all open-source projects of Github, Gitlab, Bitbucket, etc. Appendix C lists all used search patterns.
  • heuristics to automatically retrieve their jars find latest released jars from their webpages; try to build jars using common building commands, e.g., mvn package. Dozens to hundreds of consumer programs are collected for each attack surface.
  • the second column shows the number of usable/matched consumer programs. A consumer program is usable if we can retrieve any jar from it.
  • the third column shows the number of usable/retrieved jars. Ajar is usable if it has the code of the target consumer program and can be analyzed by soot.
  • the first step of the method is to prepare the learning inputs from previously collected jars. Each function of the consumer program will be used as one entry function and the method tries to extract a Raw NFA from it. As shown in the fourth column of Fig.
  • the method analyzes tens of thousands to hundreds of thousands functions for each attack surface.
  • the fifth column shows the amount of extracted non-empty Raw NFAs.
  • the amounts of the covered API functions and the data dependencies are listed in the next two columns.
  • the eighth column lists the cpu time needed for the learning input preparation part.
  • the reason the method can practically analyze large amount of real world projects is two-fold:
  • the time complexity of its extraction algorithm is 0(E) where E is the amount of edges of the traversed ICFG;
  • the method configures soot to only analyze the necessary parts.
  • the method excludes the classes of third party libraries using SootClass.setPhantomClass, before constructing the ICFG of the consumer programs.
  • the method learns an usage automaton from the prepared inputs.
  • the method first unifies the alphabet for all extracted Raw NFAs. Then it distills all the Raw NFAs and merges them as a final usage automaton.
  • # of CC and CMG stand for the number of the cases of conflict condition events and merged groups.
  • the eleventh to fourteenth columns list the number of API events, mock API events, condition events, and total events of the alphabet after unification/after distillation. Note that, after distillation, the events will be removed from the alphabet if the method cannot find any valid event sequence which contains them.
  • the fifteenth column shows that the overall learning overhead ranges from hundreds to thousands of CPU seconds.
  • the method synthesizes a fuzz driver according to the usage automaton. The last three columns show its detail statistics. Overall, the method is able to generate fuzz drivers by learning usage from various real-world consumer programs.
  • Fig. 7 shows the coverage comparison results.
  • the solid line, dashed line, and dotted line stand for the coverage of the method, fuzzgen, and manual, respectively.
  • the disclosed method shows apparent performance advantage over the other two baselines.
  • Fig. 8 shows the TTE comparison results (average time in seconds), apa triber and zip4j are not listed since all fuzz drivers failed to find any bug in 24 hours.
  • the method according to the invention uses shortest time to find the first bug.
  • the results demonstrate the inventive method can generate more effective fuzz drivers than existing methods.
  • the advantage comes from the fact that the method can learn more diverse API dependencies, and provide a better scheduling interface to the fuzzer.
  • the effectiveness of FUZZGEN is limited by the aforementioned three challenges. The inventive solution centers around solving these challenges.
  • Fig. 9 shows the coverage per time comparison results.
  • Solid line and dashed line are w. cf and w.o. cf respectively.
  • the w. cf shows clear advantage in the plots. All the p-values of w. cf - w.o. cf are smaller than 5.00e-2, which shows the statistical significance.
  • Fig. 10 compares the average time of TTE (seconds), apa triber and zip4j are excluded since all fuzz drivers failed to find bugs in 24 hours. As listed, w. cf always uses less time than w.o. cf to find the first bug. The results show that, in evaluated targets, considering control flow sensitivity can significantly improve the overall fuzzing performance of the fuzz drivers.
  • Fig. 11 shows a case which demonstrates how control flow sensitivity improves fuzzing performance.
  • the case comes from one of the bugs found by the inventors. It shows a fuzz driver accepting an input file which is of certain archive format. Since the input file can archive multiple files, it iterates the file headers (FileHeader) to extract all contained files.
  • the function extractFile (line 7) contains an infinite loop bug which can be triggered by malformed file headers.
  • the loop iteration of fileHeader (line 2 - 7) increases the possibility to find this bug since the iteration can force the fuzz driver to apply extractFile on every file header. In other words, by adding execution states to differentiate the API invoking contexts, the iteration loop maximizes the exploitation of mutated input.
  • control flow sensitivity improves the performance of the fuzz drivers by using additional states to distinguish different API invoking contexts.
  • Fig. 13 lists the coverage comparison results.
  • the solid line and the dashed line represent denoised and raw respectively. In most cases, denoised reaches higher coverage with statistical significance.
  • Fig. 14 lists the TTE comparison results. The results show that raw always can find real bugs faster than denoised. Note that, we excluded the false positives found by raw in the presented TTE results. Specifically, we manually analyzed the crashes, the results of apachepoi and apa triber for raw contain false positives including dead loops, false crashes, etc. In summary, the extra complexity of raw does not benefit the fuzzing performance but introduce false positives. The usage distillation is necessary for fuzz driver generation. On the one hand, it significantly reduces the complexity of usage automaton; on the other hand, it significantly improves the quality of generated fuzz drivers in both fuzzing performance and precision.
  • the disclosed method provides a scheduling interface enabling fuzzer to determine which usage scenario should be tested during fuzzing.
  • rndlcf where the fuzzer is bound with a randomly selected usage scenario, the fuzzer will only fuzz that scenario throughout the experiment (i.e. , no control flow scheduling interface). Note that the repeated experiments are independent with each other, i.e., they can be assigned with different usage scenarios.
  • This competitor is used to represent the fuzzing strategy which does not consider multiple usage scenarios, itercf, where the fuzz driver iterates all usage scenarios for each single fuzzing iteration, itercf is another type of case that no control flow scheduling interface is provided to fuzzer.
  • rndlcf which only fuzzes one usage scenario, it goes to the other extreme, i.e., always fuzzes all usage scenarios; rndlseed, where the fuzzer can pick which usage scenario should be tested in the next execution by changing the value of leading bytes of the input.
  • cfseeds we randomly assign a value in its leading bytes to pick a random usage scenario, cfseeds.
  • This competitor is same as rndlseed except that every usage scenario is picked in its initial seeds. For instance, assuming apachepoi has 11 usage scenarios, cfseeds will generate 11 new input seeds to replace the original input seeds. And every new seed picks a different usage scenario. Comparing with rndlseed, cfseeds gives fuzzer full information for its scheduling at the beginning of the fuzzing.
  • Fig. 15 shows the coverage comparison results of these competitors: In all attack surfaces, the coverage of rnd1 seed and cfseeds is higher than itercf and rnd1 cf with statistical significance; Usually, cfseeds and rndlseed have similar performance. In apachepoi and zip4j, cfseeds has higher initial coverage than rndlseed; however, its following coverage is slightly lower than rndlseed.
  • An explanation is that the exploration ability of the fuzzer itself is good enough to this scheduling interface, and providing too many initial seeds can bring more distraction than guidance to the fuzzer; Usually, the confidence intervals of rndlcf are observably wider than others.
  • Fig. 16 shows the TTE comparison, apaginar and zip4j are excluded since all fuzz drivers cannot find their bugs in 24 hours. Usually, rndlseed and cfseeds find bugs quicker. Considering all above, the scheduling interface provided by RUBICK can significantly improve the utilization of the multiple usage scenarios, and rndlseed is a suitable default setup.
  • the disclosed method has been used to generate fuzz drivers for eleven attack surfaces, including the attack surfaces in evaluated projects, metadata-extractor, Apache Tika, fastjson, and jackson.
  • the selection criteria is that they are popular Java projects on both PC and Android systems. Therefore, finding the bugs of these projects can benefit the software of both systems.

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Computer Hardware Design (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Software Systems (AREA)
  • Quality & Reliability (AREA)
  • Computer Security & Cryptography (AREA)
  • Computing Systems (AREA)
  • Stored Programmes (AREA)
  • Image Analysis (AREA)
  • Debugging And Monitoring (AREA)

Abstract

In this disclosure, a method called RUBICK is disclosed. The method is an automata based fuzz driver generation method. Compared to existing works, the method can embed more diverse API usages such as branches and loops; it can learn API usage from large-scale real world projects; and it improves the utilization of multiple independent sets of API usage. In evaluation, the method shows great advantage over the baselines. The method has been used to generate fuzz drivers for 11 popular Java libraries and two fuzz drivers have been merged into OSSFuzz. In total, the method was able to discover 199 new bugs, including four CVEs, affecting popular PC and Android software with more than dozens of millions of downloads.

Description

TITLE
A computer-implemented method for generating an automata-guided fuzz driver and fuzzing method using the fuzz driver
TECHNICAL FIELD
The invention provides a computer-implemented method for generating an automaton-guided fuzz driver for non-executable library data that include at least one API function.
BACKGROUND
Fuzzing is a practical dynamic analysis technique for vulnerability detection.
Compared with static analysis techniques, fuzzing can produce more precise results with fewer false-positives (FP) and allows security analysts to replay bugs for Proof- of-Concept. However, as a dynamic technique, fuzzing requires an executable of the target software as the testing subject. To fuzz libraries, executable programs using the library functions must first be generated. Conventionally, these programs are called fuzz harnesses or fuzz drivers.
Fuzz drivers can be composed manually by human experts or generated automatically by tools. To compose fuzz drivers, experts typically have to learn the usage of library APIs from documentations or example programs. Not only is this learning process tedious and time-consuming, but also the quality of the composed fuzz drivers heavily depends on the experience of the human experts. Therefore, techniques for automatically generating fuzz drivers are desired.
Existing works focus on automatic fuzz driver generation. Similar to manually writing the fuzz drivers, these techniques also need to learn the correct usage of library APIs to ensure testing effectiveness. Additionally, existing works learn such knowledge by analyzing how the consumer programs (aka example programs) that use the libraries utilize the library API functions. After generating the fuzz drivers, these techniques also need to rank or ensemble the generated fuzz drivers so that the fuzzer can test them substantively.
Despite the previous efforts, three challenges still exist for both learning the correct usage of library APIs and utilizing the generated fuzz drivers.
One challenge can be that some library APIs should reside in branches and loops where the conditions are guarded by the results of other APIs, but the API usage learned by existing works emphasizes data dependencies among the APIs while ignoring most control dependencies among them. Not including the control dependencies can end up in failing to invoke certain APIs properly. As a result test coverage may be lower.
Another challenge can be that the learned API usage of existing works may suffer from noises such as redundant API calls or wrong API dependencies. Failing to remove the noises can limit the usability of a fuzz driver generation technique especially when it needs to learn from complex realworld consumer programs.
Yet another challenge can be that multiple fuzz drivers can be generated for a single target library with existing works, but how to organize and utilize these fuzz drivers to increase confidence that they can be substantially tested by the fuzzer is understudied. Poorly organized fuzz drivers can distract the fuzzer and hinder the fuzzing performance.
SUMMARY OF THE INVENTION
It is the object of the invention to improve automatic fuzz driver generation, preferably with respect to coverage and/or coverage per unit time.
The invention provides a computer-implemented method for generating an automaton-guided fuzz driver for non-executable library data that include at least one API function, the method comprising: a) with a learning input extraction means: extracting learning input data from a nonexecutable target library and at least one executable computer program that uses the target library, wherein the learning input data are configured to allow training of an automaton; b) with an automaton generation means: generating at least one non-determ inistic finite automaton (NFA) based on the learning input data, wherein each NFA is associated with one program function of the computer program, and performing a learning method on the at least one NFA that is based on the learning input data in order to obtain a usage automaton that includes information about the a control flow graph of the target library and the computer program; c) with a fuzz driver synthesizing means: synthesizing a fuzz driver based on the usage automaton, wherein the fuzz driver is synthesized to include the usage automaton, and the fuzz driver is configured to allow interaction of a fuzzer with the library data so as to perform fuzzing on the library data.
Preferably, in step a) the learning input extraction means extracts the learning data by static analysis. Preferably, in step a) the learning input extraction means extracts learning data that include event sequence data that are indicative of control flow information. Preferably, in step a) the learning input extraction means extracts learning data that include API data depdency information that are indicative of possible values for arguments of API functions and/or data linkages between API functions. Preferably, in step a) the learning input extraction means extracts learning data that include API meta information that are indicative of basic information of an API function, such as function signature, type of argument(s), and/or type of return value.
Preferably, in step b) the automaton generation means unifies the alphabet of each NFA obtained in step b) by associating a unique identifier with each unique event. Preferably, in step b) the automaton generation means distills an event sequence for each NFA by applying an L* algorithm. Preferably, in step b) the automation generation means merges the previously obtained NFAs into the usage automaton, preferably into a single usage automaton, by applying a deterministic finite automata (DFA) combination and minimization algorithm to the previously obtained NFAs.
Preferably, in step c) the fuzz driver synthesizing means synthesizes the fuzz driver so as to include a plurality of fuzzing scenarios that are selectable by the fuzzer. Preferably, in step c) the fuzz driver synthesizing means synthesizes the fuzz driver so as to include a scheduling interface for a greybox fuzzer.
The invention provides a computer-implemented method for fuzzing non-executable library data that are used in at least one executable computer program: a) performing a preferred method with the library data and the at least one computer program in order to generate a fuzz driver for the library data; b) with a fuzzer: fuzzing the library data by means of the fuzz driver and the at least computer program in order to obtain fuzzing results.
The invention provides a data processing apparatus comprising means to carry out a preferred method.
The invention provides a computer program that includes instructions that, when executed on a data processing means, cause the data processing means to carry out a preferred method.
The invention provides a computer-readable storage medium or data carrier signal that includes the computer program.
To generate better fuzz drivers, a method for generating an automata-guided controlflowsensitive fuzz driver is disclosed. One concept used in the technique is the API usage automaton (or usage automaton in short), which can represent the control dependencies among the APIs. Therefore, the method is able to increase test coverage.
Furthermore, through building and refining the usage automaton, the disclosed idea can reduce or even eliminate the noises which would otherwise limit the effectiveness of fuzzing.
Another idea leverages the usage automaton to synthesize and organize a fuzz driver which can effectively coordinate with greybox fuzzers. Concentrating on building and maintaining the usage automaton, the disclosed measures can work in some steps. Given a target library and its consumer programs, a data extractor extracts data and control dependency information of the API functions preferably by static analysis. Specifically, the control flow information can be used to build the usage automaton. The data flow information can be used together with the usage automaton to synthesize the fuzz driver.
In some embodiments the L* algorithm can be used to build and/or refine the usage automaton.
In some embodiments a fuzz driver generator can generates a single automata- guided fuzz driver as its output. The fuzz driver can operate as an automata interpretation engine. This fuzz driver may encode all the control-flow and data-flow information learned from the consumer programs and coordinate with the fuzzer so that the library APIs can be tested with improved coverage. The improvement may include larger overall coverage and/or larger overall coverage per unit time. In other words, computational efficiency may be increased.
The advantages of the method over known approaches, such as FuzzGen, include that fuzz drivers have an overall significant better performance. It is possible to learn from practical example programs. Furthermore, a better scheduling interface can be provided for the fuzzer. In contrast to known approaches, the generated fuzz drivers are able to contain control flow dependencies like branches and loops.
The fuzz driver may contain necessary branches and loops in order to invoke every API function of the target library correctly. Branches and loops are deemed necessary when their condition expressions have direct data dependencies with the output of API functions. The rationale is that if the execution of a branch or loop is not affected by any other API function, it is typically not affected by mutated input. Likely, excluding such branch or loop will not affect the performance of fuzzing. In practice, the desired fuzz driver is capable of describing most useful API usage patterns, e.g., state checking, objects iteration, etc.
BRIEF DESCRIPTION OF THE DRAWINGS Embodiments of the invention are described in more detail with reference to the accompanying schematic drawings.
Fig. 1 depicts an embodiment of a method according to the invention;
Fig. 2 illustrates different inputs and outputs of the method steps;
Fig. 3 illustrates difficult scenarios;
Fig. 4 and
Fig. 5 exemplify certain algorithms;
Fig. 6 to
Fig. 16 illustrate experimental results of the disclosed method.
DETAILED DESCRIPTION OF EMBODIMENT
In general, the method for generating an automata-guided fuzz driver 10 is described with reference to Fig. 1 .
In a first step S10, a learning input extraction means extracts learning materials from at least one computer programs 12 that uses a target library 14. The learning materials may include event sequences represented as a raw non-determ inistic finite automata (NFA) 16, API data dependencies 18, and API meta information 20. The API meta information 20 refers to the basic information of API functions, e.g., the function signature, the type of arguments and return value, etc. Its collection is straightforward and is done once per library.
In the first step S10, the method collects the learning inputs from consumer programs 12 by static analysis. Note that the learning input extractin means requires no a priori knowledge about the target library 14. Given a library, the learning input extracting means collects the candidate events and event sequences as NFAs 16; the API data dependencies 18; the API meta information 20.
For collecting candidate events and event sequences, two kinds of events are identified from the control flow graph (CFG) of the at least one consumer program 12: the function events and the condition events. After the identification, the invention traverses the CFG and extracts a simplified event graph from the CFG. The event graph is represented as an NFA 16 which uses the above mentioned events as alphabets.
For collecting API data dependencies our the method collects data dependencies between two API functions and between an API function and a constant. Specifically, the these can be represented as the tuple ( Provider, Consumer ) where the provider can be any output of an API function or a constant and the consumer can be any input needed by an API function. They are collected together with raw NFAs 16 by statically analyzing the consumer programs.
For collecting API meta information the method collects the API meta information which is the basic information of API functions, e.g., the function signature, the type of arguments and return value, etc. This is done only once per target library 14.
In a second step S12, a learning process is performed. The second step S12 has three elements that are performed by an automaton generation means. The automaton generation means first performs alphabet unification 22 among all raw NFAs 16. Next, the automaton generation means performs usage destination 24 to refine the raw NFAs 16. Specifically, the algorithm takes each raw NFA 16 as input and outputs a minimized DFA containing the valid event sequences. Lastly, the automaton generation means performs automata merging 25 of these DFAs as a single usage automaton 26.
The goal of alphabet unification 22 is to name each unique event a different letter. For function events of API functions, the automaton generation means assigns the letters according to their function signatures. For condition events, the automaton generation means needs to align their condition expressions and solve the potential conflicts before assigning letters. The automaton generation means parses these expressions as first-order logical formulas to check their identity.
The goal of usage distillation 24 is to prune incorrect event sequences of the raw NFAs 16 while removing redundancies at the same time. Intuitively, the process is similar to the water distillation process, it first turns the raw NFA 16 to the form of event sequences (boils the water until it becomes water vapour), then removes the incorrect event sequences based on some criteria (removes impurities based on different boiling points), and summarizes it back to a minimized automaton (condense vapour back to water).
For each raw NFA 16 the automaton generating means uses an L* based algorithm for usage distillation 24 of the event sequences. Generally, the usage distillation 24 may infer a minimized deterministic finite automaton (DFA) describing the valid event sequences inside each Raw NFA 16. An event sequence is considered valid if and only if it does not break any known constraints.
After usage distillation 24, the automaton generating means merges these DFAs as one usage automaton 26 using DFA combination and minimization algorithms. These algorithms, such as the Hopcroft’s DFA minimization algorithm, have reasonable time complexity.
Subsequently, in a third step S14, a fuzz driver synthesizing means performs code synthesis 28 and synthesizes the automata-guided fuzz driver 10 based on the usage automaton 26. Instead of generating multiple fuzz drivers for the fuzzer, the invention synthesizes one automata-guided fuzz driver 10 where the fuzzer can pick the usage scenario it favors by providing different values to the leading bytes of the input. To accomplish that, first the a DFS-based algorithm is performed to count all independent usage scenarios inside the target automaton. Second, the fuzz driver 10 is designed as event-driven. The fuzz driver 10 loads the usage automaton 26 and maintains its states at runtime. For each execution, the fuzz driver 10 starts from the initial state. Then the fuzz driver 10 tries to traverse the usage automaton 26 until there are no successor states. In each step of the traverse, the fuzz driver 10 first searches the usage automaton 26 for the next possible events and picks one from them. After that, the fuzz driver 10 executes the code representing the picked event, and updates the status of the usage automaton 26 accordingly. Picking which event can be determined by either the input of fuzzer or the runtime information.
The method can automatically generate the fuzz driver 10. The fuzz driver 10 is a functional component for conducting fuzz testing towards software, especially for library targets. There are two potential usage scenarios. For software developing teams, they can integrate the invention to automate the fuzzing process in their Continuous Integration (Cl) workflow, which improves the quality and security of the developed software. Specifically, for a given software library which requires a fuzz driver to do the fuzzing, the invention can help to automatically generate the candidate fuzz drivers.
For security experts or testing teams, this idea can be integrated into their dynamic analysis tool set. Once they identify an attack surface of a given software, they can use the generation method described herein to automatically generate the fuzz drivers for conducting fuzz testings. Therefore, the attack surface can be fuzzed based on the fuzz driver generated by the invention.
A usage automaton is typically a deterministic finite automaton (DFA) having a finite set of states Q, a set of input symbols called the alphabet 2, a transition function 8: Q x 2 Q, an initial state q0 e Q and a set of final states F c Q_
An event is preferably labeled as a letter (input symbol) and an event sequence is marked as a string that includes the letters that represent the events in the event sequence. Generally, the API usage is represented as a set of strings. The DFA may act as an acceptor of a set of strings. The DFA may contain two types of events: function events and condition events.
A function event may represent an action which calls an API function and updates the value of its output variables, if any. A new variable can be assigned for each output of the API function.
A condition event may represent an action that the current value of a variable expression satisfies a certain constraint. In some embodiments, to describe some types of loop cases, a mock API function event can be used, which calls a mock API defined the fuzz driver.
For states, there may be no direct mapping between the meaning of the states and the concepts in fuzz driver. Naively, once an event happens, the usage automaton can transit itself from one state to another. The learning algorithm may merge two states if all their subsequent transitions are the same. The automaton preferably starts from the initial state, and the events along the path from initial state to any final state form a valid event sequence, i.e. , a valid usage to invoke the API functions. The branches and loops may have direct mappings in the graph structure of the usage automaton, e.g., forks and loops.
In some embodiments the usage automaton has a property that no initial state can be a final state. In this case empty usage is treated as invalid usage, thereby saving computational ressources.
In some embodiments, any non-empty prefix of a valid event sequence can be a valid event sequence. For example, given a sequence designated as AHI is deemed valid, then the prefix sequence AH is also deemed valid.
In some embodiments any event sequence containing a non-empty invalid prefix is deemed invalid. For instance, if a sequence AIH is deemed invalid, then any event sequence starting with AIH is also deemed invalid.
From the perspective of the usage automaton, this means that all invalid strings, i.e. event sequences, lead the state machine into a trap state.
Using some of the previous ideas, in particular the initials stat property and/or the prefix validity property can be used to infer the validity of unchecked event sequences, which allows an improvement of the distillation process.
The method collects learning inputs from consumer programs via static analysis. Note that no a priori knowledge about the target library is required. Given a library, the method collects: the candidate events and event sequences; the API data dependencies; the API meta information.
The API meta information refers to the basic information of API functions, e.g., the function signature, the type of arguments and return value, etc. Its collection is straightforward and is done once per library. In the following, only the collection of the other learning inputs is explained in more detail.
The method preferably extracts event sequences from the consumer programs by converting its control flow graph (CFG) into a non-determinisitic finite automaton (NFA). This can be done by translating some instructions into events and removing the irrelevant instructions.
The identification of the function events of API functions is straightforward — an instruction which calls any API function is considered as a function event. For the rest of events, an idea is to divide the identification into two scenarios: Control dependencies whose usage can be described by API function events and condition events. All branches and some types of loops belong to this scenario. For example, in Fig. 2 a), the branch in line 12 and loop in line 2.
A key feature to recognize this scenario is that their condition expressions only consist of constants and the variables storing outputs of the API functions. To identify the condition events, the method may conduct taint propagation marking the outputs of the API functions as taint sources. Once a condition expression of a branch instruction is tainted, two condition events can be generated for both true and false branch.
Specifically, in Fig. 2 a), the method may generate y (ret_C == SLICC) and n (ret_C != SLICC) for the branch in line 12, and t (ret_E == true) and f (ret_E == false) for the loop in line 2.
Control dependencies whose usage description requires the introduction of extra events. Fig. 3 shows two types of cases. Reusing the method for the previous scenario usually cannot correctly describe them since the data flow relation in their loop conditions is beyond the description ability of API function events and condition events.
To solve this, the method introduces extra events. Specifically, for Loop Case I, by introducing I and J as mock API function events, necessary data flow propagations (hasNext and getNext) are kept. Similarly, Loop Case II introduces I and J to describe the data flow propagation of i. Generally, the method may use a two-pass extraction to handle all scenarios.
The first pass may taint propagation as previous scenario. After that, the method preferably checks whether the collected condition expressions contain variables of the control dependencies scenario. If variables are contained, the method may redo the extraction but preferably additionally marks the definition of these variables as taint sources. Any value update of these variables will be identified as a mock API function event.
For clarity, Fig. 4 shows Algorithm 1 of a single-pass extraction process. As shown in line 31 - 32, instead of requiring a perfect entry function for extraction, the method may extract a raw usage automaton (namely Raw NFA) for each function inside the consumer program. This is feasible since the subsequent learning process will remove the invalid or the redundant usages. The basic idea behind the extraction is to build the Raw NFA along the traverse of the interprocedural control-flow graph (ICFG). The traverse starts from the entry instruction of target function Ftarget.
Line 7 - 27 shows the analysis of each traversed instruction, curl points to the instruction under analysis. curS points to the state in Raw NFA which new states should be linked with, ctxt holds the taint information for analyzing curl. If curl is a non-API function call instruction, the method may extract the Raw NFA of the callee (subA) and merges it into current NFA (A). The merge is accomplished by adding a transition from curS to the start state (starts) of subA with epsilon event e and adjusting the curS to point to the end state (endS) of subA. If curl is not of the above case, the event identification strategies are applied.
A new transition will be added to A once a new event is identified, and curS also will be updated. Last, the successors of curl are added to Q for analysis. If curl is an exit point of the function , e.g., return, the edge from curS to endS is added. If a successor instruction is already analyzed, a transition from curS to the instruction’s corresponding state under event e is added. For simplicity, the algorithm only shows the key flow. In implementation, the algorithm also maintains a stack to prevent the infinite loop caused by the recursive call of the target function. Besides, multiple callees may be returned by iCFG.getCallee in line 9, the method preferably picks the first one by default. The extracted automaton is named as Raw NFA since it contains e and can have multiple transitions given one specific state and event, e.g., same events can be identified in both paths of a branch.
The extracted Raw NFA contains control flow information of the fuzz driver, such as the correct order of API functions, or the condition to call an API function, etc. Comparatively, API data dependencies indicate the possible values for arguments of API functions, or the data linkages between API functions. Both are typically needed information for generating a valid fuzz driver. Specifically, one set of control flow usage can have multiple sets of data dependencies. For example, given three API functions FA, FB, FC, and assuming the return values of both FA and FB can be used as the first argument of Fc, the control flow usage FA — > FB — > Fc has two sets of data dependencies: Fc can use the return value of either FA or FB.
The method may collect data dependencies between two API functions and between an API function and a constant. Specifically, the method may abstract them as the tuple ( Provider, Consumer ) where Provider can be any output of an API function or a constant and the consumer can be any input needed by an API function. They are collected together with Raw NFAs by statically analyzing the consumer programs.
The learning process has three steps. First, it unifies the alphabet among all Raw NFAs. Next, a distillation algorithm is applied to refine the Raw NFAs. Specifically, the algorithm takes each Raw NFA as input and outputs a minimized DFA containing the valid event sequences. Lastly, the method merges these DFAs as a single usage automaton.
The goal of alphabet unification is to name each unique event a different letter. For function events of API functions, the method assigns the letters according to their function signatures. For condition events, the method preferably aligns their condition expressions and solves the potential conflicts before assigning letters. For example, assuming Raw NFA A has two condition events CAI : !(ret_C != SLICC) and CA2: ret_C != SLICC, and Raw NFA B contains CBI : ret_C == SLICC, CB2: ret_C == STOP, and CBS: ret_C == ERROR.
First, CAI and CBI are assigned with one letter since both of them equal to ret_C == SLICC. The method parses these expressions as first-order logical formulas to check their identity.
Second, to unify the events, the method divides the value range of ret_C into several smaller ranges to guarantee all condition expressions can be expressed by the combination of the ranges. Specifically, the method may generate the following four events: Cui: ret_C == SUCC, C112: ret_C == STOP, C113: ret_C == FAIL, C114: (ret_C != SUCC) && (ret_C != STOP) && (ret_C != FAIL).
Last, the method may assign letters to these four events and may replace the original events in their NFAs. An identity check can be useful but the conflict case rarely happens.
For the extra events (mock API function events and their related condition events), the method preferably compares their identity by group. Specifically, a group of events contain all related events affecting the loop condition. Two groups are identical if their loop condition expressions, the value update expression of the mocked API functions, and the execution order of these events are equal. Otherwise, the method may assign different sets of letters to them.
The goal of usage distillation is to prune the incorrect event sequences of the Raw NFAs while remove the redundancies at the same time. Intuitively, the process is similar to the water distillation process, it first turns the Raw NFA to the form of event sequences (boils the water until it becomes water vapour), then removes the incorrect event sequences based on some criteria (removes impurities based on different boiling points), and summarizes it back to a minimized automaton (condense vapour back to water). Various automata learning algorithms, including both active and passive learning, are good candidates. Specifically, active learning is more suitable than passive learning: For a given Raw NFA, the number of positive examples (represents for valid event sequences, abbr as PE) and negative examples (represents for invalid event sequences, abbr as NE) can be infinite.
To apply the passive learning algorithm, which accepts a finite number of PEs and NEs, how to select a good subset from the infinite PEs/NEs which maximizes the learning effects is a challenge. Comparatively, the active learning algorithm supports infinite amounts of learning inputs by nature and using them does not have the above concern.
Different from the passive learning algorithm, active learning algorithms interact with the system under learning (abbr as SUT), which simplifies the design of the method to use dynamic execution information for validating the event sequence. Specifically, the method uses L* disclosed in D. Angluin. Learning regular sets from queries and counterexamples. Information and computation, 75(2):87-106, 1987.
Required by the L* algorithm, the method preferably answers two types of queries: membership query and equivalence query. For membership query, the method answers the correctness of the queried event sequence. Fig. 5 that illustrates Algorithm 2 shows the detailed process. The idea is that an event sequence is valid if it satisfies the following three requirements: there is no unsolved data dependencies for all API functions (line 8); its dynamic execution can end up without error (line 9); it has all required properties of being a desired fuzz driver (line 7).
To check the first requirement, the method preferably iterates all events of a given event sequence and checks whether the prefix of each event has already initialized the variables used in that event. If the check fails, the event sequence is invalid since the fuzz driver based on it will have uninitialized variables.
To check the secon requirement, the method first converts the event sequence to a fuzz driver. Note that the fuzz driver comes from a single event sequence, therefore it is a sequence of API calls and condition checks without loops. During the execution, if the condition is not satisfied, the execution is stopped and the event sequence is partially tested.
The method optimistically treats the untested parts as correct. Obviously, the effectiveness of dynamic validation is influenced by the diversity of the input files. The more diverse the input files are, the more effective the dynamic validation can be. In practice, we use one to three valid input seeds in the dynamic validation.
For the third requirement, the method has two limitations to a valid event sequence. First, it limits that the condition event can only appear after the value of its condition expression has been updated by other events. The rationale is that since an event sequence which contains a dead loop of a condition event is valid but not desired usage. Second, it also limits that the API function which accepts the input file should appear once and only once.
For the equivalence query, the method preferably uses wp-method (known from F. B. Khendek, et al., Test selection based on finite state models. IEEE Transactions on software engineering, 17(591 -603): 10-1109, 1991.) to sample a test set of the automaton. The learned automaton is satisfying if no counterexample can be found in the test set. A counterexample consists of an event sequence and its correctness. It points out the error of current automaton, where the automaton either accepts an incorrect event sequence or refuses a correct event sequence. The method chooses wp-method since it generates a slightly smaller test set than w-method while keeping similar representativeness. In practice, the method may set the lookahead value as 2.
During the learning, the algorithm iteratively proposes possible automaton after certain rounds of membership queries and improves the automaton based on the counterexample provided by the equivalence query. After learning, the method removes dead loops and trap states of the output automaton. A dead loop is a loop which does not contain any condition event. Besides, removing the trap states and the related transitions simplifies the automaton while keeping its accepted event sequences. The method uses DFA combination and minimization algorithms to generate the final usage automaton from the distilled ones. These algorithms, such as the Hopcroft’s DFA minimization algorithm (known from M. Isberner, F. Howar, and B. Steffen. The open-source learnlib. In D. Kroening and C. S. Pasareanu, editors, Computer Aided Verification, pages 487-495, Cham, 2015. Springer International Publishing.), have reasonable time complexity. The distillation and the merge are separated as two steps because: On the one hand, directly applying active learning algorithms to infer an automata from all raw NFAs at once faces performance issues. The search scope of the active learning algorithms increases exponentially when the alphabet size grows. In practice, if there exist less than 50 unique events in the raw NFA, RUBICK can figure it out in seconds to minutes. If the number grows to 100, the learning process may take hours or even days. Comparatively, applying DFA minimization algorithms to automatons which have large alphabets does not have this kind of performance issue. On the other hand, distillation and merging require different inputs. Distillation is more complicated since it requires a process to infer the automaton from a set of PEs and NEs. In contrast, the merging process only needs to minimize a set of PEs.
As the last step, the method synthesizes a fuzz driver based on the learned usage automaton. However, the synthesis is nontrivial since the learned usage can inevitably contain multiple independent usage scenarios.
Instead of generating multiple fuzz drivers for the fuzzer, the disclosed method synthesizes an automata-guided fuzz driver where the fuzzer can pick the usage scenario it favors by providing different values to the leading bytes of the input. To accomplish that, two things have to be done. First, the method uses a DFS-based algorithm to count all independent usage scenarios inside the target automaton. Second, the fuzz driver is designed as event-driven. It loads the usage automaton and maintains its states at runtime. For each execution, it starts from the initial state. Then it tries to traverse the automaton until there has no successor states. In each step of the traverse, it first searches the automaton for the next possible events and picks one from them. After that, it executes the code representing the picked event, and updates the status of the automaton accordingly. Picking which event can be determined by either the input of fuzzer or the runtime information. If the next events belong to multiple usage scenarios, the pick is determined by input, e.g., state 1 in Fig. 1.e), choosing B or H depends on the input. Otherwise, it should be determined by the runtime information, e.g., state 3 in Fig. 1 .e), choosing y or n depends on the runtime value of ret_E.
In summary, the method provides a scheduling interface to greybox fuzzers for better utilization of the learned usage. In evaluation several strategies and setups of the scheduling interface are discussed and compared. Results show that this interface can influence the fuzzing performance significantly. Besides, randomly assign a value to the leading bytes of all input seeds is a recommended default setup.
The main components of the computer-implementation of the method contain 6,979 lines of java code, 1 ,656 lines of python code, and 654 lines of bash scripts. Specifically, java code includes most functionalities such as the learning inputs collection, usage distillation, fuzz driver synthesis, etc. The python code is mainly used for alphabet unification. The bash scripts are used for gluing the workflow. Note that the automata related algorithms are developed upon learnlib (M. Isberner, F. Howar, and B. Steffen. The open-source learnlib. In D. Kroening and C. S. Pasareanu, editors, Computer Aided Verification, pages 487-495, Cham, 2015. Springer International Publishing.), and the first-order logical formulas related algorithms are developed upon z3py.
Currently, the impelementation can generate fuzz drivers for Java libraries. A motivation for building a Java version of the method is that Java libraries are important infrastructures of modern software and their bugs can have significant security effects (e.g., OSS-FUZZ has integrated fuzz drivers for Iog4j recently).
However, no existing fuzz driver generation tools can be applied to these projects. Model-interpretation-based Execution Instead of discussing every implementation detail, we discuss a technique which significantly boosts the learning process of the implementation.
In usage distillation, the implementation needs to retrieve dynamic information of a specific API usage (i.e., an event sequence). Initially, for each usage, the implementation retrieves its dynamic information using three steps: conversion from usage to code; code compilation; code execution. Besides, on-the-fly compilation technique is used to reduce the costs. However, the learning costs are still too high since the amount of the queries (excluding the cached queries) can be more than millions when handling some complex raw NFAs. To solve this, a model- interpretation-based execution was used.
The basic idea is that one compilation per API usage is unnecessary. By building a general model interpreter, the API usage can be fed in as data. The interpreter translates the usage into real actions (e.g., calls an API, updates a variable, etc) to retrieve the dynamic information. For a given alphabet, a general interpreter can be generated. This saves almost all compilation costs. In practice, the implementation can test thousands to tens of thousands API usage scenarios per second, which is thousands of times faster than the other approaches.
The implementation was evaluated and the evaluation aims to answer the following questions:
How is the quality of the fuzz drivers generated by the implementation compared with fuzz drivers generated by known techniques and manually written ones?
How does the method generate better fuzz drivers by addressing the three key challenges?
Can the fuzz drivers generated by the method help to find vulnerabilities in real world fuzzing scenarios?
The method is evaluated on six attack surfaces identified from six popular java libraries, namely apachetar, apachepoi, itextpdf, junrar, pdfbox and zip4j. The overall selection criteria is to cover different types of vendors, input formats, and cover attack surfaces at different scales. Note that the libraries and attack surfaces have a many-to-many relationship. Multiple attack surfaces inside one library are separated by the input formats they accept. For example, for apachepoi and apachetar, their libraries provide APIs to parse 12 and 22 different types of input formats, which means that they have 12 and 22 attack surfaces respectively. For these libraries, we pick the attack surface which accepts a popular input format.
To fuzz java programs, we use jazzer, which is a libfuzzer-based fuzzer used by OSS-FUZZ and ClusterFuzz. Following the suggestions from G. Klees, et al. Evaluating fuzz testing. In Proceedings of the 2018 ACM SIGSAC Conference on Computer and Communications Security., all the evaluated fuzz drivers share the same input seeds, machine, and fuzzer options (-jvm_args="-Xmx2048m" - close_fd_mask=3 -timeout=60 -rss_limit_mb=10240).
For fairness, the coverage of the fuzz driver itself is excluded, i.e. , the comparison only covers the edge coverage of the target attack surfaces. All data used in evaluation are collected from 24 hours, 10 times repeated fuzzing results. In the plots, lines are average values and the areas around the lines designated by the thinner lines represent 95% confidence intervals. The experiments are conducted on a Linux server with two Intel(R) Xeon(R) Gold 6248 CPU @ 2.50GHz processors and 188GB RAM.
To apply the method on these attack surfaces, we first build a crawler to collect the consumer programs. The crawler first locates the open-source projects which use the attack surface, then retrieves jars of these projects as the method input. Specifically, a project is a consumer program if its code contains the package path of the attack surface, e.g., com.github.junrar. We use src, a CLI tool of Sourcegraph, to launch the match query among all open-source projects of Github, Gitlab, Bitbucket, etc. Appendix C lists all used search patterns. For the matched consumer programs, we further apply heuristics to automatically retrieve their jars: find latest released jars from their webpages; try to build jars using common building commands, e.g., mvn package. Dozens to hundreds of consumer programs are collected for each attack surface. The second column shows the number of usable/matched consumer programs. A consumer program is usable if we can retrieve any jar from it. The third column shows the number of usable/retrieved jars. Ajar is usable if it has the code of the target consumer program and can be analyzed by soot. The first step of the method is to prepare the learning inputs from previously collected jars. Each function of the consumer program will be used as one entry function and the method tries to extract a Raw NFA from it. As shown in the fourth column of Fig.
6, Table 2, the method analyzes tens of thousands to hundreds of thousands functions for each attack surface. The fifth column shows the amount of extracted non-empty Raw NFAs. The amounts of the covered API functions and the data dependencies are listed in the next two columns. The eighth column lists the cpu time needed for the learning input preparation part. The reason the method can practically analyze large amount of real world projects is two-fold: The time complexity of its extraction algorithm is 0(E) where E is the amount of edges of the traversed ICFG; Instead of fully analyzing the consumer program, the method configures soot to only analyze the necessary parts. In detail, the method excludes the classes of third party libraries using SootClass.setPhantomClass, before constructing the ICFG of the consumer programs.
Next, the method learns an usage automaton from the prepared inputs. The method first unifies the alphabet for all extracted Raw NFAs. Then it distills all the Raw NFAs and merges them as a final usage automaton. In ninth and tenth columns, # of CC and CMG stand for the number of the cases of conflict condition events and merged groups. The eleventh to fourteenth columns list the number of API events, mock API events, condition events, and total events of the alphabet after unification/after distillation. Note that, after distillation, the events will be removed from the alphabet if the method cannot find any valid event sequence which contains them. The fifteenth column shows that the overall learning overhead ranges from hundreds to thousands of CPU seconds. Lastly, the method synthesizes a fuzz driver according to the usage automaton. The last three columns show its detail statistics. Overall, the method is able to generate fuzz drivers by learning usage from various real-world consumer programs.
The effectiveness of the method was evaluated by comparing the fuzzing performance of its fuzz drivers with the drivers from FUZZGEN (abbr as fuzzgen) and manually written fuzz drivers (abbr as manual). Originally, FUZZGEN is written for C/C++ programs. The inventors developed its java version. The inventors strictly followed the algorithms discussed in its paper and aligned the implementation detail with its released source code. Besides, since the fuzz drivers generated by FUZZGEN are too complex to be fuzzed when there are hundreds or thousands of consumer programs (as discussed in its paper). Five consumer programs are manually selected for each attack surface and one entry function is selected for each consumer program based on the rank criteria mentioned in its paper. The manually written fuzz drivers of apachetar, pdfbox are collected from OSSFuzz. For the rest, we invited a human expert who is not the author of this paper to manually write them. The expert is familiar with fuzzing and coding in Java but has no a priori knowledge of these attack surfaces. Writing these four fuzz drivers costs the expert around one week.
Fig. 7 shows the coverage comparison results. The solid line, dashed line, and dotted line stand for the coverage of the method, fuzzgen, and manual, respectively. In plots, the disclosed method shows apparent performance advantage over the other two baselines.
Specifically, all p-values of the inventive method - fuzzgen and the inventive method - manual are smaller than 5.00e-2, which shows the statistical significance. The p- values are acquired from Mann-Whitney U-test (N. Nachar et al. The mann-whitney u: A test for assessing whether two independent samples come from the same distribution.).
Fig. 8 shows the TTE comparison results (average time in seconds), apachetar and zip4j are not listed since all fuzz drivers failed to find any bug in 24 hours. For the listed attack surfaces, the method according to the invention uses shortest time to find the first bug. Overall, the results demonstrate the inventive method can generate more effective fuzz drivers than existing methods. The advantage comes from the fact that the method can learn more diverse API dependencies, and provide a better scheduling interface to the fuzzer. Specifically, the effectiveness of FUZZGEN is limited by the aforementioned three challenges. The inventive solution centers around solving these challenges.
To study the effectiveness of the API control dependency, the fuzzing performance of the fuzz drivers with control flow sensitivity (abbr as w. cf) and without control flow sensitivity (abbr as w.o. cf) is compared. Both fuzz drivers are generated using the inventive method except that the condition events and mock API events are not identified for w.o. cf.
Fig. 9 shows the coverage per time comparison results. Solid line and dashed line are w. cf and w.o. cf respectively. The w. cf shows clear advantage in the plots. All the p-values of w. cf - w.o. cf are smaller than 5.00e-2, which shows the statistical significance.
Fig. 10 compares the average time of TTE (seconds), apachetar and zip4j are excluded since all fuzz drivers failed to find bugs in 24 hours. As listed, w. cf always uses less time than w.o. cf to find the first bug. The results show that, in evaluated targets, considering control flow sensitivity can significantly improve the overall fuzzing performance of the fuzz drivers.
Fig. 11 shows a case which demonstrates how control flow sensitivity improves fuzzing performance. The case comes from one of the bugs found by the inventors. It shows a fuzz driver accepting an input file which is of certain archive format. Since the input file can archive multiple files, it iterates the file headers (FileHeader) to extract all contained files. The function extractFile (line 7) contains an infinite loop bug which can be triggered by malformed file headers. The loop iteration of fileHeader (line 2 - 7) increases the possibility to find this bug since the iteration can force the fuzz driver to apply extractFile on every file header. In other words, by adding execution states to differentiate the API invoking contexts, the iteration loop maximizes the exploitation of mutated input. If the fuzz driver is not aware of the states for loop, the mutations of the content which belong to non-first file headers will be wasted. In summary, the case shows that, control flow sensitivity improves the performance of the fuzz drivers by using additional states to distinguish different API invoking contexts.
To study the effectiveness of the denoise techniques, the fuzz drivers generated with the usage distillation techniques (abbr as denoised) and without these techniques (abbr as raw) are compared. Fig. 12, Table 3 lists the number of the independent control flow usages for denoised and raw. Apparently, raw has a significantly more complex usage automaton than denoised. It has 3.45 - 1 ,131 .25 times more control flow usages than denoised. In fact, a majority of the usage inside raw are noises (redundant or invalid event sequences) which can be validated and filtered during the distillation.
Fig. 13 lists the coverage comparison results. The solid line and the dashed line represent denoised and raw respectively. In most cases, denoised reaches higher coverage with statistical significance.
Fig. 14 lists the TTE comparison results. The results show that raw always can find real bugs faster than denoised. Note that, we excluded the false positives found by raw in the presented TTE results. Specifically, we manually analyzed the crashes, the results of apachepoi and apachetar for raw contain false positives including dead loops, false crashes, etc. In summary, the extra complexity of raw does not benefit the fuzzing performance but introduce false positives. The usage distillation is necessary for fuzz driver generation. On the one hand, it significantly reduces the complexity of usage automaton; on the other hand, it significantly improves the quality of generated fuzz drivers in both fuzzing performance and precision.
The disclosed method provides a scheduling interface enabling fuzzer to determine which usage scenario should be tested during fuzzing. To understand the effectiveness of this schedule interface, we conducted fuzzing experiments using the following competitors: rndlcf, where the fuzzer is bound with a randomly selected usage scenario, the fuzzer will only fuzz that scenario throughout the experiment (i.e. , no control flow scheduling interface). Note that the repeated experiments are independent with each other, i.e., they can be assigned with different usage scenarios. This competitor is used to represent the fuzzing strategy which does not consider multiple usage scenarios, itercf, where the fuzz driver iterates all usage scenarios for each single fuzzing iteration, itercf is another type of case that no control flow scheduling interface is provided to fuzzer. However, different with rndlcf, which only fuzzes one usage scenario, it goes to the other extreme, i.e., always fuzzes all usage scenarios; rndlseed, where the fuzzer can pick which usage scenario should be tested in the next execution by changing the value of leading bytes of the input. For the initial input seeds, we randomly assign a value in its leading bytes to pick a random usage scenario, cfseeds. This competitor is same as rndlseed except that every usage scenario is picked in its initial seeds. For instance, assuming apachepoi has 11 usage scenarios, cfseeds will generate 11 new input seeds to replace the original input seeds. And every new seed picks a different usage scenario. Comparing with rndlseed, cfseeds gives fuzzer full information for its scheduling at the beginning of the fuzzing.
Fig. 15 shows the coverage comparison results of these competitors: In all attack surfaces, the coverage of rnd1 seed and cfseeds is higher than itercf and rnd1 cf with statistical significance; Mostly, cfseeds and rndlseed have similar performance. In apachepoi and zip4j, cfseeds has higher initial coverage than rndlseed; however, its following coverage is slightly lower than rndlseed. An explanation is that the exploration ability of the fuzzer itself is good enough to this scheduling interface, and providing too many initial seeds can bring more distraction than guidance to the fuzzer; Mostly, the confidence intervals of rndlcf are observably wider than others. This indicates that the performance of rndlcf among multiple rounds of fuzzing is less stable. Interestingly, this can be a proof that the potentials of different usage scenarios are different; therefore, scheduling interface for maximizing the utilization of multiple usages is necessary. Besides, the execution speed of itercf is many times slower than its competitors since it executes all usage scenarios during one fuzzing iteration.
Fig. 16 shows the TTE comparison, apachetar and zip4j are excluded since all fuzz drivers cannot find their bugs in 24 hours. Mostly, rndlseed and cfseeds find bugs quicker. Considering all above, the scheduling interface provided by RUBICK can significantly improve the utilization of the multiple usage scenarios, and rndlseed is a suitable default setup.
The disclosed method has been used to generate fuzz drivers for eleven attack surfaces, including the attack surfaces in evaluated projects, metadata-extractor, Apache Tika, fastjson, and jackson. The selection criteria is that they are popular Java projects on both PC and Android systems. Therefore, finding the bugs of these projects can benefit the software of both systems. Additionally, we generated directly human readable fuzz drivers using usage scenarios of the usage automaton. Two of them have been accepted and merged into OSS-FUZZ. Considering the rules of anonymous review process, more details will be released when suitable.
REFERENCE SIGNS
10 automata-guided fuzz driver
12 computer program
14 target library
16 raw non-deterministic finite automata (NFA)
18 API data dependencies
20 API meta information
22 alphabet unification
24 usage destination
25 automata merging
26 usage automaton
28 code synthesis

Claims

1 . A computer-implemented method for generating an automaton-guided fuzz driver (10) for non-executable library data that include at least one API function, the method comprising: a) with a learning input extraction means: extracting learning input data from a nonexecutable target library (14) and at least one executable computer program (12) that uses the target library (14), wherein the learning input data are configured to allow training of an automaton; b) with an automaton generation means: generating at least one non-determ inistic finite automaton (NFA) (16) based on the learning input data, wherein each NFA (16) is associated with one program function of the computer program (12), and performing a learning method on the at least one NFA (16) that is based on the learning input data in order to obtain a usage automaton (26) that includes information about the a control flow graph of the target library (14) and the computer program (12); c) with a fuzz driver synthesizing means: synthesizing a fuzz driver based on the usage automaton (26), wherein the fuzz driver is synthesized to include the usage automaton (26), and the fuzz driver is configured to allow interaction of a fuzzer with the library data so as to perform fuzzing on the library data.
2. The method according to claim 1 , wherein in step a): aO) the learning input extraction means extracts the learning data by static analysis; and/or a1 ) the learning input extraction means extracts learning data that include event sequence data that are indicative of control flow information; and/or a2) the learning input extraction means extracts learning data that include API data depdency (18) information that are indicative of possible values for arguments of API functions and/or data linkages between API functions; and/or a3) the learning input extraction means extracts learning data that include API meta information (20) that are indicative of basic information of an API function, such as function signature, type of argument(s), and/or type of return value.
3. The method according to any of the preceding claims, wherein in step b): bO) the automaton generation means unifies the alphabet of each NFA obtained in step b) by associating a unique identifier with each unique event; and/or b1 ) the automaton generation means distills an event sequence for each NFA (16) by applying an L* algorithm; and/or b2) the automation generation means merges the previously obtained NFAs (16) into the usage automaton (26), preferably into a single usage automaton (26), by applying a deterministic finite automata (DFA) combination and minimization algorithm to the previously obtained NFAs (16).
4. The method according to any of the preceding claims, wherein in step c): cO) the fuzz driver synthesizing means synthesizes the fuzz driver so as to include a plurality of fuzzing scenarios that are selectable by the fuzzer; and/or c1 ) the fuzz driver synthesizing means synthesizes the fuzz driver so as to include a scheduling interface for a greybox fuzzer.
5. A computer-implemented method for fuzzing non-executable library data that are used in at least one executable computer program (12): a) performing a method according to any of the preceding claims with the library data and the at least one computer program (12) in order to generate a fuzz driver for the library data; b) with a fuzzer: fuzzing the library data by means of the fuzz driver and the at least computer program (12) in order to obtain fuzzing results.
6. A data processing apparatus comprising means to carry out a method according to any of the preceding claims.
7. A computer program (12) that includes instructions that, when executed on a data processing means, cause the data processing means to carry out a method according to any of the claims 1 to 5.
8. A computer-readable storage medium or data carrier signal that includes the computer program (12) accordingt to claim 7.
EP23794334.5A 2022-11-01 2023-10-23 A computer-implemented method for generating an automata-guided fuzz driver and fuzzing method using the fuzz driver Pending EP4612581A1 (en)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
GB2216175.6A GB2623966A (en) 2022-11-01 2022-11-01 A computer-implemented method for generating an automata-guided fuzz driver and fuzzing method using the fuzz driver
PCT/EP2023/079512 WO2024094464A1 (en) 2022-11-01 2023-10-23 A computer-implemented method for generating an automata-guided fuzz driver and fuzzing method using the fuzz driver

Publications (1)

Publication Number Publication Date
EP4612581A1 true EP4612581A1 (en) 2025-09-10

Family

ID=84839564

Family Applications (1)

Application Number Title Priority Date Filing Date
EP23794334.5A Pending EP4612581A1 (en) 2022-11-01 2023-10-23 A computer-implemented method for generating an automata-guided fuzz driver and fuzzing method using the fuzz driver

Country Status (4)

Country Link
EP (1) EP4612581A1 (en)
CN (1) CN120167062A (en)
GB (1) GB2623966A (en)
WO (1) WO2024094464A1 (en)

Family Cites Families (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US8271950B2 (en) * 2009-07-06 2012-09-18 Microsoft Corporation Test generation from captured user interface status
CN114201381B (en) * 2020-09-02 2025-04-29 株洲中车时代电气股份有限公司 Test case generation method, device and storage medium

Also Published As

Publication number Publication date
GB202216175D0 (en) 2022-12-14
WO2024094464A1 (en) 2024-05-10
GB2623966A (en) 2024-05-08
CN120167062A (en) 2025-06-17

Similar Documents

Publication Publication Date Title
Watson et al. On learning meaningful assert statements for unit test cases
Lee et al. Montage: A neural network language {Model-Guided}{JavaScript} engine fuzzer
Marjanov et al. Machine learning for source code vulnerability detection: What works and what isn’t there yet
Abdulla et al. An integrated specification and verification technique for highly concurrent data structures
Koc et al. An empirical assessment of machine learning approaches for triaging reports of a java static analysis tool
Le et al. Interactive program synthesis
Santolucito et al. Learning CI configuration correctness for early build feedback
Haryono et al. Characterization and automatic updates of deprecated machine-learning api usages
Liang et al. {WingFuzz}: Implementing continuous fuzzing for {DBMSs}
Sheng et al. All You Need Is A Fuzzing Brain: An LLM-Powered System for Automated Vulnerability Detection and Patching
Faddegon et al. Algorithmic debugging of real-world haskell programs: deriving dependencies from the cost centre stack
WO2024094464A1 (en) A computer-implemented method for generating an automata-guided fuzz driver and fuzzing method using the fuzz driver
Hassanshahi et al. Unlocking reproducibility: Automating re-build process for open-source software
Chabbi et al. Barrier elision for production parallel programs
Naik Petablox: Large-scale software analysis and analytics using Datalog
Long Automatic patch generation via learning from successful human patches
Insa et al. Erlang code evolution control
Arcelli et al. Design pattern detection in java systems: A dynamic analysis based approach
Giroh et al. < SYNTACT>: Structuring Your Natural Language SOPs into Tailored Ambiguity-Resolved Code Templates
Dissanayake Fuzz Driver Generation
CN121349524B (en) Plugin Dependency Resolution and Architecture Extension Methods and Systems for Low-Code Platforms
Tim et al. Deep security analysis of program code
Almeida Automatic Resolution of Deadlocks in Concurrent Programs
Oliver Investigating Configurations for Automated Crash Reproduction in JavaScript
Ahmed Learning Program Embedding From Unlabeled Source Code

Legal Events

Date Code Title Description
STAA Information on the status of an ep patent application or granted ep patent

Free format text: STATUS: UNKNOWN

STAA Information on the status of an ep patent application or granted ep patent

Free format text: STATUS: THE INTERNATIONAL PUBLICATION HAS BEEN MADE

PUAI Public reference made under article 153(3) epc to a published international application that has entered the european phase

Free format text: ORIGINAL CODE: 0009012

STAA Information on the status of an ep patent application or granted ep patent

Free format text: STATUS: REQUEST FOR EXAMINATION WAS MADE

17P Request for examination filed

Effective date: 20250602

AK Designated contracting states

Kind code of ref document: A1

Designated state(s): AL AT BE BG CH CY CZ DE DK EE ES FI FR GB GR HR HU IE IS IT LI LT LU LV MC ME MK MT NL NO PL PT RO RS SE SI SK SM TR

RAP3 Party data changed (applicant data changed or rights of an application transferred)

Owner name: AUMOVIO GERMANY GMBH

Owner name: NANYANG TECHNOLOGICAL UNIVERSITY

DAV Request for validation of the european patent (deleted)
DAX Request for extension of the european patent (deleted)
STAA Information on the status of an ep patent application or granted ep patent

Free format text: STATUS: EXAMINATION IS IN PROGRESS

17Q First examination report despatched

Effective date: 20260305