-
Notifications
You must be signed in to change notification settings - Fork 10
Stock Triggers
LFI comes with a set of useful triggers which you can use out-of-the box for your injection experiments and as a starting point for creating new triggers:
The Random injection trigger (class RandomTrigger
) can be used to inject with a configurable probability in each associated function call.
To create a trigger instance that injects with 40% probability use the following XML snippet in your scenario
<trigger id="random40" class="RandomTrigger">
<args>
<percent>40</percent>
</args>
</trigger>
The Call stack injection trigger (class CallstackTrigger
) can be used to inject when the current call stack matches a predefined (partial) call stack. More exactly, the trigger tries to match the outermost frames of the current call stack (excluding the frames belonging to FIT) with the given call stack.
Each given frame can be specified to match
- Any part of an executable module
- Any part of an executable module and a file name (if debug information is available)
- Any part of an executable module, file name and line number (if debug information is available)
- The absolute offset of a function call
- When using a frame that matches any part of an executable module use either:
-
__main
- to specify that the main executable is targeted (no libraries) - library name including extension
-
- When using a frame to target a module, file name (with or without line number), always use the full module path. The file name will be matched against the last part of the file name from the debug information i.e. the path is optional
- When using an absolute offset (usually after disassembling the program), give the offset in hexadecimal form (e.g.,
0x8049cf0
)
The trigger below injects in calls made by the mysqld module, file mi_create.c
, through a wrapper that can be anywhere in the mysqld module.
<trigger id="t" class="CallStackTrigger">
<args>
<frame>
<module>__main</module>
</frame>
<frame>
<module>/home/paul/mysql-5.1.44/sql/mysqld</module>
<file>mi_create.c</file>
<!-- <line>832</line> -->
</frame>
</args>
</trigger>
- Injecting in libraries, by specifying only the library module can give unexpected results. This happens because the trigger does not determine the library size in memory; a default size of 512KB is used.
- Injecting in the main executable, by specifying only the module (i.e.,
__main
) can give unexpected results when the injection library is loaded in multiple processes (as in the case of a test suite) because faults may be injected in other processes. Use the form__main_
''entry_point'' (e.g.,__main_0x8049cf0
) to specify that injection should happen only in an executable with the given entry point. The entry point can be determined viareadelf -h /path/to/program
Used to inject after a specific number of invocations.
Trigger instance that injects after being invoked 40 and 55 times.
<trigger id="cc" class="CallCountTrigger">
<args>
<callcount>40</callcount>
<callcount>55</callcount>
</args>
</trigger>
The state trigger allows injection when a predicate based on program variable holds. The implementation supports global and local variables of integer and string (char*) type and the equality predicate.
Specifying variables is done differently for global and local storage. For global variables, the absolute offset of the variable must be provided.
This can be obtained via gdb
using the ''info address '' command after loading the target executable, assuming debug symbols exist.
For local variables, the stack frame where the variable resides, relative to the frame that makes the library call, must be provided along with the variable offset (ebp
-relative) inside the frame. A [DetermineLocalVariables detailed walkthrough] is available.
Specifying a local variable:
<trigger id="l1" class="StateTrigger">
<args>
<local>
<frame>24</frame>
<offset>-0x8</offset>
<type>string</type>
<value>foo</value>
</local>
</args>
</trigger>
Specifying a global variable:
<trigger id="g1" class="StateTrigger">
<args>
<global>
<offset>0x8049cf0</offset>
<type>int</type>
<value>2010</value>
</global>
</args>
</trigger>
If the targeted function is called from multiple places (or with different call stacks), evaluating local variables may result in undefined behavior. It is good practice to accompany any local variable evaluation with a call stack trigger that only matches the particular call stack of interest.
Each instance of the single injection trigger evaluates to true
the first time its Eval
function is called and to false
otherwise. The trigger does not take any arguments. It is useful in combination with other triggers, usually as the last-to-be-evaluated.
<trigger id="single" class="SingleTrigger" />
<trigger id="l1" class="StateTrigger">
<args>
<local>
<frame>24</frame>
<offset>-0x8</offset>
<type>string</type>
<value>foo</value>
</local>
</args>
</trigger>
<function name="opendir" retval="NULL" errno="EMFILE">
<triggerx ref="l1" />
<triggerx ref="single" />
</function>
+----------------------------+------------------+--------------------------------------+ |Trigger Purpose | Trigger Class | Arguments | +----------------------------+------------------+--------------------------------------+ | Random injection trigger | RandomTrigger | <!DOCTYPE args [ | | | | <!ELEMENT args (percent)> | | | | <!ELEMENT percent(#PCDATA)> | | | | ]> | +----------------------------+------------------+--------------------------------------+ |Call count trigger - inject | CallCountTrigger | <!DOCTYPE args [ | |the fault when the function | | <!ELEMENT args(callcount+)> | |is called a specific number | | <!ELEMENT callcount (#PCDATA)> | |of times | | ]> | +----------------------------+------------------+--------------------------------------+ |Callstack trigger - inject | CallStackTrigger | <!DOCTYPE args [ | |when the current call stack | | <!ELEMENT args(frame+)> | |(partially) matches a given | | <!ELEMENT frame(module,file?,line?)>| |call stack | | <!ELEMENT module (#PCDATA)> | | | | <!ELEMENT file(#PCDATA)> | | | | <!ELEMENT line (#PCDATA)> | | | | ]> | +----------------------------+------------------+--------------------------------------+