Skip to content

Code Vulnerabilities

IoT firmware often contains security vulnerabilities such as buffer overflows, use of insecure functions, and hardcoded secrets. Ghidra’s decompilation and analysis capabilities allow reverse engineers to systematically identify these issues by inspecting function behavior, memory usage, and control flow. This section covers techniques to detect common vulnerabilities in Ghidra-processed code.


Identifying Buffer Overflows

Buffer overflows occur when data exceeds allocated memory, potentially allowing arbitrary code execution. Ghidra can help identify this by analyzing memory operations and function calls.

Step 1: Search for Vulnerable Functions

Look for functions that copy data without bounds checking, such as strcpy, sprintf, or memcpy. For example:

void vulnerable_function(char *input) {
    strcpy(buffer, input); // No bounds check
}
In Ghidra, right-click the function and select "Rename" to mark it as a potential vulnerability. Use the "Function Signatures" feature to filter for known insecure APIs.

Step 2: Analyze Memory Access

Use the "Memory" view to inspect stack allocations. A buffer overflow often involves writing beyond a fixed-size buffer. For example:

char buffer[128]; // 128-byte buffer
strcpy(buffer, "This is a long string that overflows the buffer"); // Overflow occurs
In Ghidra, check the "Decompiled Code" for explicit buffer sizes and compare input lengths.


Detecting Insecure Functions

Ghidra’s "Function Signatures" tool can flag deprecated or insecure APIs. Common examples include:
- gets() (no length check)
- strcpy() (no bounds checking)
- sprintf() (potential format string vulnerabilities)

Example: Flagging gets()

char input[64];
gets(input); // Vulnerable to buffer overflow
In Ghidra, right-click the function and select "Mark as Vulnerable". Use the "Call Graph" to trace how this function is invoked and whether it’s sanitized.


Analyzing Control Flow for Exploits

Exploitable control flow patterns include indirect jumps, function pointers, and misaligned branches. Ghidra’s "Control Flow Graph" (CFG) visualization helps identify these:

Example: Indirect Jump

void *ptr = get_pointer_from_untrusted_source();
((void (*)(void))ptr)(); // Potential ROP gadget or arbitrary code execution
In Ghidra, use the "CFG" view to inspect the function’s flow. Look for jmp or call instructions that reference untrusted data.


Checking for Hardcoded Secrets

Hardcoded credentials or API keys are common in IoT firmware. Use Ghidra’s "Strings" tool to search for base64, hex, or plain-text secrets:

Example: Hardcoded API Key

char *api_key = "Y2FsdGVkX1+ABC1234567890"; // Base64-encoded secret
In Ghid, navigate to "View > Strings" and filter for base64 patterns. Right-click suspicious strings to analyze their usage in the code.


Key takeaways

  • Use Ghidra’s "Function Signatures" to flag insecure APIs like strcpy or gets.
  • Analyze memory operations for buffer overflows by comparing buffer sizes and input lengths.
  • Inspect control flow graphs for indirect jumps or function pointers that may enable ROP.
  • Leverage the "Strings" tool to identify hardcoded secrets in firmware.
  • Combine Ghidra’s decompilation with manual code review to prioritize high-risk vulnerabilities.