It is essential to ensure that all the binaries in the root file system are hardened against potential vulnerabilities. IoT devices often use many third-party binaries, for example binaries coming with the chipset SDK or a middleware vendor. These could have different levels of hardening settings and coding style. It is also necessary to understand how binaries are hardened and to identify any memory corruption issues resulting from unsafe function calls or insecure coding style. These issues are easily present in C and C++ code due to the inherent memory unsafe nature of these languages.
Verifying security is a challenging task due to the large number of binaries present in the root file system. To address this, BugProve provides a coarse grained risk assessment over system binaries to estimate how likely it is that they contain a practical vulnerability or unsafe code pattern. With BugProve, you can determine which binaries are more likely to contain vulnerabilities and carry out further analysis on those, focusing on common classes of weaknesses that have the potential to lead to remote code execution or other detrimental attack vectors.
In order to support these use cases, BugProve features Weak Binaries analysis that is shown in this report view.
This view consists of a header that aggregates data over a set of binaries on the system and a table that shows detailed information for each binary.
You will find the following results in the header when opening a Weak binaries report.
- Unsafe function calls
The sum of unsafe function invocation callsites that our coarse grained static analysis engine can identify, calculated for each of 7 different functions that we consider security relevant.
- A list of top 5 vulnerable functions
Based on hardening information and our static analysis engine, BugProve is going to list 5 binaries that have the highest heuristic score among all files on the system.
- Score distribution
Based on the same heuristic score as used above, a chart is shown to summarize the distribution of potentially problematic binaries. This should serve as a quick glimpse into the general security posture of the system, often reflecting on the coding convention prevalent on the system.
The risk score is calculated based on the number of dangerous functions used by the binary, the size of the binary, its hardening status and a number of other factors.
Unsafe function counters
The use of system can potentially lead to command injection vectors.
The use of strcpy can potentially lead to buffer overflow issues.
The use of strcat can potentially lead to buffer overflow issues.
The use of mmap is not considered a secure coding issue by itself, however, our static analysis engine pays special attention to these calls to find IoT specific vulnerable code patterns.
The use of sprintf can potentially lead to buffer overflow issues.
The use of fprintf where the format string is influenced by attacker controlled data is a code smell at best and it can potentially lead to format string vulnerabilities (primarily on certain legacy systems.)
- NX - No eXecute. These binaries mark their data segments as non-executable. Makes exploiting memory corruption issues significantly harder.
- PIE - Position Independent Executable. The binary can be loaded at an arbitrary memory addresses by the system. This is the default behavior for shared objects, and is set for executables on ASLR enabled systems. Exploits can’t rely on known addresses in the base binary.
- SC - Stack Canaries. Detects and mitigates stack buffer overflows before execution of malicious code can occur.
- Stripped - Binaries with debugging information removed. Harder to reverse engineer.
- RELRO - Relocation Read-Only. Locks down the data sections of executables after dynamic linking has completed.
Weak binaries and PRIS
As you can see, each binary has either a completed scan associated with it that can be opened via “Show scan” or you can initiate a new PRIS scan for binaries that don’t. Navigating among system binaries using sorting on heuristics and executing PRIS scans can be a very powerful technique to discover the weak links in the system. Doing so will often help you discover memory corruption issues or command injection vectors that have the potential to be exploitable 0-day vulnerabilities.
For a detailed discussion, see Running subscans.