Package related to data tainting.
Data tainting allows to follow the flow of some data throughout the execution trace. This package exposes the taint algorithm available in REVEN v2 through an (experimental and simplified) API.
The entry point of the API is the Tainter.simple_taint
method, that allows to return a Taint
object
parameterized by the data you wish to taint and the range of the
taint.
>>> # Spawning a taint with a tainter.simple_taint >>> tainter = reven2.preview.taint.Tainter(trace) >>> taint = tainter.simple_taint(tag0="[ds:0xffff88007cb95800 ; 27]", from_context=trace.context_before(0), ... to_context=trace.context_after(2968406), is_forward=False) >>> taint Taint Object (from_context=Context before #0, to_context=Context before #2968407, direction=Backward, granularity=Instruction)
Once you have a Taint
object, you
can query the results produced by the taint using a variety of TaintResultView
objects.
>>> # Getting changes and states from a taint >>> print(next(taint.changes().all())) Taint change at #2960185 rep movsb byte ptr [rdi], byte ptr [rsi] Tainted memories: [phy:0x77bcccb8; 3] : gained[tag0,] [phy:0x7cb95818; 3] : lost[tag0,] >>> print(taint.state_at(trace.context_before(0))) Taint state at Context before #0 Tainted memories: [phy:0x779fe80e; 19] : [tag0,] [phy:0x779fe828; 1] : [tag0,] [phy:0x779fe83b; 7] : [tag0,]
The taint produces three types of results:
TaintState
:
the state of the taint at some Context
, that
indicates which data is currently tainted.
TaintChange
:
a change to the state of taint at some Transition
, that
indicates which data is newly tainted and which data just lost the
taint.
TaintWarning
:
a list of warning messages associated to a range of Transition
s,
that indicate that something may be incorrect in the taint
propagation. Users are encouraged to check manually the correctness
of these range of Transition
s,
especially if the range contains one or more TaintChange
,
in which case it is likely to have had an effect on the taint.
Please refer to the documentation of Taint.changes
,
Taint.states
,
Taint.warnings
and TaintResultView
for more information on querying results.
When data is tainted, it means that it is marked with a taint marker. During the (forward) taint propagation, if some piece of data that has a taint marker influences another, it also transmits the taint marker to this other piece of data (in backward propagation, the relationship is "depends on another").
The taint algorithm in REVENv2 can operate with multiple taint
markers. This means each piece of data can be marked with zero, one or
several taint markers. A marker is defined by its name, and by an
integer
handle (for efficiency reasons when manipulating
multiple markers).
In the simplified API, only two predefined taint markers, "tag0" and "tag1" are available in taints, but we plan to allow taints with an arbitrary number of taint markers in the future.
Compared to the other objects available in the API, the Taint
object is
special in several ways:
The two next sections go in details over these points.
While the taint can be very fast (may traverse billions of instructions in a few seconds), sometimes the taint process can last for a long time (especially when there are a lot of changes to the taint state). It would be possible to wait for the taint to finish before accessing the results, but meanwhile, your script would not be able to advance. The current taint makes its results available as soon as they are computed. This means that is you query the results on a taint that is not finished, you will not get all the results of the taint, only those that are computed at the time of the query.
The API exposes various handles to address this problem:
Progress
class gives you the current status of the taint (whether it is still
running or not), and the last taint state that was computed.
>>> # Fetching the progress of a Taint >>> taint.progress() TaintProgress(last_known_state_id=0, status=Finished)
TaintResultView
class. This builds "views" of the queried results, where
results can be fetched by polling repeatedly the available results
with the TaintResultView.available
method, or the user can wait for all results to be produced with the
TaintResultView.all
method.
>>> # Fetching results >>> changes = taint.changes() >>> for change in changes.available(): ... print(change.transition.id) 21 27 52 >>> for change in changes.available(): ... print(change.transition.id) 87 101 >>> for change in taint.changes().all(): ... print(change.transition.id) 21 27 52 87 101
As of today, the main limitation to the taint being a server-side
background process is that there can only be one taint processed
at the same time per server. Starting a second taint, be it in
Axion of through the API by using Tainter.simple_taint
,
immediately cancels and discards the results of the first taint.
NOTE: Currently, starting a new taint can confuse Axion and Python clients that were in the middle of requesting results from a previous taint, resulting in the clients mixing results from the previous and the new taint. To avoid this issue, always make sure that no client is in the middle of requesting results from a taint before starting another one.
Module | helpers | Undocumented |
From the __init__.py
module:
Class | ChangeMarkers | Models gained and lost markers for a TaintChange
entry. |
Class | MarkerIterator | Models an iterator over taint markers. |
Class | MarkerManager | Manages the taint markers defined in a taint. |
Class | Progress | Represent the status of the taint at the point where it was requested. |
Class | ProgressStatus | No summary |
Class | PropagationDirection | Enum describing the taint direction |
Class | ResultGranularity | Enum describing the taint result granularity. |
Class | Taint | Represent a started taint in the backend, allowing to retrieve the taint results. |
Class | TaintChange | A change between two taint states, containing information about which data became tainted or lost the taint. |
Class | TaintChangeView | A view of the TaintChange s
that occurred in a taint. |
Class | TaintResultStatus | Enum describing the various statuses of a TaintResultView . |
Class | TaintResultView | TThe abstract class from which any result view is derived. |
Class | TaintState | A taint state lists all data that is currently tainted at a given Context . |
Class | TaintStateView | A view of the TaintState s
that occurred in a taint. |
Class | TaintWarning | A taint warning is a collection of warning messages that occurred during the taint. |
Class | TaintWarningView | A view of the TaintWarning s
that occurred in a taint. |
Class | TaintedData | Undocumented |
Class | TaintedMemories | Models a range of memory |
Class | TaintedRegisterSlice | Models a slice of an architecture register, e.g.
rax[0..4] |
Class | Tainter | Entry point object for tainting data. |
Class | _TaintData | Undocumented |