EFIDrill - IDA plugin for UEFI firmware vulnerability hunting base on data flow analysis
Supported versions of IDA: Well tested on IDA pro 8.2 and 8.3
Supported Platforms: Windows, Linux and OS X
git clone https://github.com/cc-crack/efidrill.gitln -s <EFIDRILL_PATH>/efidrill.py <IDA_DIR>/pluginsln -s <EFIDRILL_PATH>/efidrill <IDA_DIR>/plugins
git clone https://github.com/cc-crack/efidrill.gitmklink <IDA_DIR>\plugins\efidrill.py <EFIDRILL_PATH>\efidrill.pymklink <IDA_DIR>\plugins\efidrill <EFIDRILL_PATH>\efidrill
Configurations of EFIDrill are in config.json, you can modify it to fit your needs.
It locates in the same directory as the plugin.
We provide a template for you to modify:
{
"deep_size": 15,
"max_function_deep": 5,
"workdir": "~/efidrill_workspace/",
"logging_path": "efi_digging.log",
"just_data_taint": 1,
"debug_flag": 0,
"to_ui": 1,
"res_filename": "res.json"
}deep_size: The maximum number of instructions to be analyzed in a function.max_function_deep: The maximum recursive depth of functions to be analyzed.workdir: The directory where the analysis results and artifacts are stored.logging_path: The path of the log file.just_data_taint: Whether to perform only data taint analysis.debug_flag: Whether to enable debug mode.to_ui: Whether to output the analysis results to the UI of IDA Pro.res_filename: The name of the analysis result file.
| check_engine.py #Loaded with all plug-ins and initializes function classes
| config.json.template
| config.py
| debug.py
| function_support.py
| function_var.py
| logging.py
| plugin_mgr.py
| rd_analysis.py #Main program
| result.py
| test.py
| user_define_work.py
| __init__.py
|
+---arch
| x64.py
|
+---function_type #processing classes for different functions
| child_smi.py
| find_entry_point.py
| function_ana_loader.py
| function_type.py #SMRAM external input data is initialized here
| sub_function.py
| sw_smi.py
|
+---ida_work
| ida_support.py #Encapsulation of the IDA library
|
+---mdis #library that reaching definition analysis and encapsulates miasm
| mdis_engine.py #Generate use def engine
| mdis_support.py #Encapsulate files processed by IR
| ReachingDefinitionscfg.py
| ReachingDefinitionsvar.py
|
\---plugin #All analysis plug-ins
base_plugin.py
callout.py
datasize.py
global_var.py
indirect_call.py
memcopy.py
smmvaild.py
struct_build.py
toctou.py
Function_type.interesting_op_list: Store all the content of interestdef_var(toctou only has a -1 element description, the current variable does not analyze toctou).Function_type.all_uses,Function_type.all_defs: Store all use def{address:define}.Function_type.current_ins_addr: Theaddressof the current analysis.Function_type.ircfg: CurrentIR.Function_type.mmap_ir_address: Mapping of IR addresses and addresses:(block_index,assm_index), address.variable:{miasm_struct,address}.Variables in miasm:{miasm_struct,(block_index,assm_index)}.miasm structure: Stores variousOP,ID(registers),int,MEM.
- Inherit the Base_Plugin class in the base_plugin.py file.
- The add_interesting_memory_map_list function is called when a new def is added to the list of interesting variables, and use_list is the use_list of interest when calling the def, is_alias indicates whether this variable is an alias for another variable.
- vulnerability_find is executed at each address, use_list is all the variables of
interest used by that address, and
def_list is all variables defined by that address.
Note that since one def var corresponds to multiple use vars, variable assignment requires a list mapping of def var to use list.
Note that the toctou and struct plugins do not have RD issues, so there is a path explosion (his stack depth does not exceed the maximum limit), and the other plugins have RD issues, so there is no path explosion problem.
mmap_ir_to_address: map intermediate representation (IR) addresses to actual addresses in a binary file.check_interesting_variables: Find the variables of interest (0x40e,readsavesatate, commbuffer), different functions have different variables of interest.ana_ins_addr: Analyze each assembly instruction.add_interesting_memory_map_list: Add new define to the interesting_op_list.vulnerability_find: Call all plug-ins.fix_use: Find the far jump use(def is not in the current function), the address of the far jump block ir is (-1,-1), and the actual address is -1.get_def: generate def.
- UEFI Firmware Library and Automated Analysis
- Cross Architecture(ARM,MIPS,...)
- Variable Value Prediction Improve
- Writing a Fuzz Module
- datasize handling stack aliasing issues
- Incomplete judgment of heuristic expression jump
- The safest assumption for SMRAM out-of-bounds access: a function takes rcx as external input and we assume that it is called, whether it is actual or not (possibly false positives).
- The external data address assumes that as long as a data comes from outside, we do not consider the memory location and SMM location in our PC (possibly false positives).
cd ./test
python3 ./generate.py for extracting all modules from the raw BIOS bin files.
python3 ./run.py for running Efidrill on all modules.
If everything is done, you can find the result in your workspace folder.
Xuxiang Yang, Security researcher @ Security Lab GIC Lenovo
Qingzhe Jiang, Security researcher, Manager, @ Security Lab GIC Lenovo
Weixiao Ji, Security researcher @ Security Lab GIC Lenovo
Zhaoxing Sun helps to do some tests.
Xiaomin Li helps to create the project logo.
BH Asia 2024 arsenal: