Unverified Commit 86bf4b3c by Enkelmann Committed by GitHub

add Ghidra plugin (#42)

This PR adds a plugin for annotating the results of the cwe_checker in Ghidra.
parent 75d6c2b3
......@@ -8,6 +8,7 @@ dev
- Added file output support via --out (PR #30)
- Surpress logging of info, error and warning to STDOUT via --no-logging (PR #32)
- Added check-path feature via --check-path that searches paths between interesting input functions and cwe hits (PR #31)
- Added a plugin for integration into Ghidra (PR #42)
0.2 (2019-06-25)
=====
......
......@@ -32,7 +32,7 @@ Its main focus are ELF binaries that are commonly found on Linux and Unix operat
Please note that some of the above analyses only are partially implemented at the moment. Furthermore, false positives are to be expected due to shortcuts and the nature of static analysis as well as over-approximation. For more information about the individual checks you can look at the [online documentation](https://fkie-cad.github.io/cwe_checker/doc/html/cwe_checker/index.html).
*cwe_checker* comes with a script called `cwe_checker_to_ida`, which parses the output of *cwe_checker* and generates a IDAPython script. This script annotates the found CWEs in IDA Pro, which helps during manual analysis of a binary. The colors represent the severeness of the found issues (yellow, orange, or red). The following screenshot shows some results:
*cwe_checker* comes with scripts for IDA Pro and Ghidra, which parse the output of *cwe_checker* and annotate the found CWEs in the disassembler for easier manual analysis. See the [online documentation](https://fkie-cad.github.io/cwe_checker/doc/html/cwe_checker/index.html#ToolIntegration) for their usage. The IDA Pro plugin also uses colors to represent the severeness of the found issues (yellow, orange, or red). The following screenshot shows some results:
<p align="center">
<img src="doc/images/example_ida_anotation.png" alt="IDA Pro anotation" width="50%" height="50%"/>
......@@ -44,7 +44,7 @@ The following arguments should convince you to give *cwe_checker* a try:
- it analyzes ELF binaries of several CPU architectures including x86, ARM, MIPS, and PPC
- it is extensible due to its plugin-based architecture
- it is configureable, e.g. apply analyses to new APIs
- view results annotated in IDA Pro
- view results annotated in IDA Pro and Ghidra
- *cwe_checker* can be integrated as a plugin into [FACT](https://github.com/fkie-cad/FACT_core)
## How to install cwe_checker? ##
There are several ways to install cwe_checker. The recommended way is to get cwe_checker from the Ocaml package manager Opam. You can install cwe_checker via the package [cwe_checker](https://opam.ocaml.org/packages/cwe_checker/) (`opam install cwe_checker`). This gives you a stable version of cwe_checker.
......
# Import the results of the cwe_checker as bookmarks and comments into Ghidra.
#
# Usage:
# - Run the cwe_checker on a binary and save its output as a json file.
# - Copy this file into the Ghidra scripts folder
# - Open the binary in Ghidra and run this file as a script. Select the generated json file when prompted.
import json
def bookmark_cwe(ghidra_address, text):
previous_bookmarks = getBookmarks(ghidra_address)
for bookmark in previous_bookmarks:
if '[cwe_checker]' == bookmark.getCategory():
if text not in bookmark.getComment():
createBookmark(ghidra_address, '[cwe_checker]', bookmark.getComment() + '\n' + text)
return
createBookmark(ghidra_address, '[cwe_checker]', text)
return
def comment_cwe_eol(ghidra_address, text):
old_comment = getEOLComment(ghidra_address)
if old_comment is None:
setEOLComment(ghidra_address, text)
elif text not in old_comment:
setEOLComment(ghidra_address, old_comment + '\n' + text)
def comment_cwe_pre(ghidra_address, text):
old_comment = getPREComment(ghidra_address)
if old_comment is None:
setPREComment(ghidra_address, text)
elif text not in old_comment:
setPREComment(ghidra_address, old_comment + '\n' + text)
def get_cwe_checker_output():
ghidra_file = askFile('Select json output file of the cwe_checker', 'Open')
with open(ghidra_file.getAbsolutePath()) as json_file:
return json.load(json_file)
def compute_ghidra_address(address_string):
fixed_address_string = address_string.replace(':32u', '').replace(':64u', '')
address = int(fixed_address_string, 16)
return currentProgram.minAddress.add(address)
def main():
"""
Annotate cwe_checker results (including check_path paths) in Ghidra as end-of-line
comments and bookmarks to the corresponding addresses.
"""
cwe_checker_output = get_cwe_checker_output()
warnings = cwe_checker_output['warnings']
for warning in warnings:
if len(warning['addresses']) == 0:
cwe_text = '[' + warning['name'] + '] ' + warning['description']
ghidra_address = currentProgram.minAddress.add(0)
bookmark_cwe(ghidra_address, cwe_text)
comment_cwe_pre(ghidra_address, cwe_text)
else:
for address_string in warning['addresses']:
ghidra_address = compute_ghidra_address(address_string)
bookmark_cwe(ghidra_address, warning['description'])
comment_cwe_eol(ghidra_address, warning['description'])
if 'check_path' in cwe_checker_output:
for check_path in cwe_checker_output['check_path']:
ghidra_address = compute_ghidra_address(check_path['source_addr'])
check_path_string = 'Path to CWE at ' + check_path['destination_addr'] + ': ' + check_path['path_str']
bookmark_cwe(ghidra_address, check_path_string)
comment_cwe_eol(ghidra_address, check_path_string)
main()
......@@ -51,13 +51,15 @@ Note that debug, info and error messages are still printed to stdout and not to
E.g. [-partial=CWE190,CWE476] would only run the checks for CWE-190 and CWE-476.
The names of all available modules can be printed with the [-module-versions] command line option.
{1:ToolIntegration Integration with IDA Pro}
{1:ToolIntegration Integration with IDA Pro and Ghidra}
To annotate CWE-hits in IDA Pro, first run {i cwe_checker} and save the JSON-formatted output to a file.
To annotate CWE-hits in IDA Pro or Ghidra, first run {i cwe_checker} and save the JSON-formatted output to a file.
{[bap [BINARY] --pass=cwe-checker --cwe-checker-json --cwe-checker-out=cwe_hits.json]}
Then run the [cwe_checker_to_ida.py] script located in the [cwe_checker_to_ida] folder.
- For IDA Pro run the [cwe_checker_to_ida.py] script located in the [cwe_checker_to_ida] folder.
{[python3 cwe_checker_to_ida.py -i cwe_hits.json -o cwe_hits.py]}
Now open the binary file in IDA Pro and execute the generated [cwe_hits.py] script from within IDA Pro (Alt+F7).
- For Ghidra copy the [cwe_checker_ghidra_plugin.py] script located in the [ghidra_plugin] folder into the script folder of Ghidra.
Now open the binary in Ghidra and run the [cwe_checker_ghidra_plugin.py] script through the script manager and select the generated [cwe_hits.json] file when prompted.
{1:HackingHowto How to write your own check}
......
......@@ -21,11 +21,11 @@ let contains_multiplication d =
let check_multiplication_before_symbol _proj _prog _sub blk jmp tid_map symbols =
Seq.iter (Term.enum def_t blk)
~f:(fun d -> if contains_multiplication d then
let description = "(Integer Overflow or Wraparound) Potential overflow due to multiplication" in
let addresses = [(Address_translation.translate_tid_to_assembler_address_string (Term.tid blk) tid_map)] in
let address = (Address_translation.translate_tid_to_assembler_address_string (Term.tid blk) tid_map) in
let description = sprintf "(Integer Overflow or Wraparound) Potential overflow due to multiplication at %s" address in
let tids = [Address_translation.tid_to_string @@ Term.tid blk] in
let symbols = [(Symbol_utils.get_symbol_name_from_jmp jmp symbols)] in
let cwe_warning = cwe_warning_factory name version description ~addresses ~tids ~symbols in
let cwe_warning = cwe_warning_factory name version description ~addresses:[address] ~tids ~symbols in
collect_cwe_warning cwe_warning)
let check_cwe prog proj tid_map symbol_names _ =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment