{{Header}} {{Anchor|backdoors_table}} '''Table:''' ''Finding Backdoors in Freedom Software vs Non-Freedom Software''
{| class="wikitable" style="background-color: #fff;text-align: center" ! ! Non-Freedom Software (precompiled binaries) ! Freedom Software (source-available) |- ! Original source code is reviewable | {{No}} | {{Yes}} |- ! Compiled binary file can be decompiled into disassembly | {{Yes}} | {{Yes}} |- ! Regular pre-compiled binaries | style="background-color: {{Yellow}}"| Depends Some use binary obfuscators. | {{Yes}} |- ! [https://en.wikipedia.org/wiki/Obfuscation_(software) Obfuscation] (anti-disassembly, anti-debugging, anti-VM) https://resources.infosecinstitute.com/topic/anti-disassembly-anti-debugging-and-anti-vm/ is usually not used | style="background-color: {{Yellow}}"| Depends Some use obfuscation. | {{Yes}} An Open Source application binary could be obfuscated in theory. However, depending on the application and the context -- like not being an Open Source obfuscator -- that would be highly suspicious. An Open Source application using obfuscators would probably be criticized in public, get scrutinized, and lose user trust. |- ! Price for security audit searching for backdoors | style="background-color: {{Red}}"| Very high This is because non-freedom software is usually only available as a pre-compiled, possibly obfuscated binary. Using an anti-decompiler: * Auditors can only look at the disassembly and cannot compare a pre-compiled version from the software vendor with a self-compiled version from source code. * There is no source code that is well-written, well-commented, and easily readable by design. | style="background-color: {{Green}}"| Lower |- ! Difference between precompiled version and self-compiled version | style="background-color: {{Red}}"| Unavailable Since there is no source code, one cannot self-build one's own binary. | style="background-color: {{Green}}"| Small or none * small: for non-reproducible builds (or reproducible builds with bugs) * none: for reproducible builds |- ! [https://en.wikipedia.org/wiki/Reverse_engineering Reverse-engineering] is not required | {{No}} | {{Yes}} |- ! Assembler language skills required | style="background-color: {{Red}}"| Much more | style="background-color: {{Green}}"| Less |- ! Always legal to decompile / reverse-engineer | {{No}} Decompilation is often expressly forbidden by license agreements of proprietary software. [https://www.phoronix.com/news/MTAwNzI Skype used DMCA (Digital Millenium Copyright Act) to shut down reverse engineering of Skype] | {{Yes}} Decompilation is always legal and permitted in the license agreements of Freedom Software. |- ! Possibility of catching backdoors via observing incoming/outgoing Internet connections | style="background-color: {{Yellow}}"| Very difficult This is very difficult because most outgoing connections are encrypted by default. At some point the content must be available to the computer in an unencrypted (plain text) format, but accessing that is not trivial. When running a suspected malicious application, local traffic analyzers like [https://www.wireshark.org/ Wireshark] cannot be trusted. The reason is the malicious application might have compromised the host operating system and be hiding that information from the traffic analyzer or through a backdoor. One possible option might be running the application inside a virtual machine, but many malicious applications actively attempt to detect this configuration. If a virtual machine is identified, they avoid performing malicious activities to avoid being detected. Ultimately this might be possible, but it is still very difficult. | style="background-color: {{Yellow}}"| Very difficult |- ! Convenience of spotting backdoors | style="background-color: {{Red}}"| Lowest convenience It is necessary to decompile the binary and read "gibberish", or try to catch malicious traffic originating from the software under review. As an example, consider how few people would have decompiled Microsoft Office and kept doing that for every upgrade. | style="background-color: {{Green}}"| Very high convenience It is possible to: # Audit the source code and confirm it is free of backdoors. # Compare the precompiled binary with a self-built binary and audit the difference. Ideally, and in future, there will be no difference (thanks to the Reproducible Builds project) or only a small difference (due to non-determinism introduced during compilation, such as timestamps). |- ! Difficulty of spotting intentional, malicious backdoors An example of a malicious backdoor is a hardcoded username and password or login key only known by the software vendor. In this circumstance there is no plausible deniability for the software vendor. List of [https://en.wikipedia.org/wiki/Backdoor_(computing)#List_of_known_backdoors malicious backdoors in wikipedia]. | style="background-color: {{Red}}"| Much higher difficulty Requires strong disassembly auditing skills. | style="background-color: {{Green}}"| Much lower difficulty If for example hardcoded login credentials were in the published source code, that would be easy to spot. If the published source code is different from the actual source code used by the developer to compile the binary, that difference would stand out when comparing pre-compiled binaries from the software vendor with self-compiled binaries by an auditor. |- ! Difficulty of spotting a "bugdoor" A "bugdoor" is a vulnerability that can be abused to gain unauthorized access. It also provides plausible deniability for the software vendor. See also: [https://en.wikipedia.org/wiki/International_Obfuscated_C_Code_Contest Obfuscated C Code Contest]. | style="background-color: {{Red}}"| Much higher difficulty Such issues are hard to spot in the source code, but even harder to spot in the disassembly. | style="background-color: {{Green}}"| Lower difficulty |- ! Third parties can legally release a [https://en.wikipedia.org/wiki/Fork_(software_development) software fork], a patched version without the backdoor | {{No}} This is forbidden in the license agreement. Due to lack of source code, no serious development is possible. | {{Yes}} Since source code is already available under a license that permits software forks and redistribution. |- ! Third parties can potentially make (possibly illegal) modifications like disabling serial key checks This entry is to differentiate from the concept immediately above. Pre-compiled proprietary software is often modified by third parties for the purposes of privacy, game modifications, and exploitation. | {{Yes}} | {{Yes}} |- ! Software is always modifiable | {{No}} For example, Intel ME could not be disabled in Intel CPUs yet. At the time of writing, a Freedom Software re-implementation of Intel microcode is unavailable. | {{Yes}} |- ! Third parties can use static code analysis tools | {{No}} | {{Yes}} |- ! Third parties can judge source code quality | {{No}} | {{Yes}} |- ! Third parties can find logic bugs in the source code | {{No}} | {{Yes}} |- ! Third parties can find logic bugs in the disassembly | {{Yes}} | {{Yes}} |- ! Benefits from population-scale scrutiny | {{No}} | {{Yes}} |- ! Third parties can benefit from [https://en.wikipedia.org/wiki/Debug_symbol debug symbols] during analysis | style="background-color: {{Yellow}}"| Depends Some may publish debug symbols. | {{Yes}} |- ! Display source code intermixed with disassembly | {{No}} | {{Yes}} * [https://manpages.debian.org/bullseye/binutils-common/objdump.1.en.html objdump] with parameter -S / --source * [https://stackoverflow.com/questions/2511018/how-does-objdump-manage-to-display-source-code-with-the-s-option How does objdump manage to display source code with the -S option?] |- ! Effort to audit subsequent releases | style="background-color: {{Red}}"| Almost same It is possible to review the disassembly, but that effort is duplicated for subsequent releases. The disassembly is not optimized to change as little as possible or to be easily understood by humans. If the compiled version added new optimizations or compilation flags changed, that creates a much bigger [https://en.wikipedia.org/wiki/Diff diff] of the disassembly. | style="background-color: {{Green}}"| Usually lower After the initial audit of a source-available binary, it is possible to follow changes in the source code. To audit any newer releases, an auditor can compare the source code of the initially audited version with the new version. Unless there was a huge code refactoring or complete rewrite, the audit effort for subsequent versions is lower. |- !colspan="3"| [https://forums.whonix.org/t/finding-backdoors-in-freedom-software-vs-non-freedom-software/11335 Forum discussion: Finding Backdoors in Freedom Software vs Non-Freedom Software] |- |}
Spotting backdoors is already very difficult in Freedom Software where the full source code is available to the general public. Spotting backdoors in non-freedom software composed of obfuscated binaries is exponentially more difficult. The consensus is the assembler [https://en.wikipedia.org/wiki/Low-level_programming_language low level] programming language is more difficult than other [https://en.wikipedia.org/wiki/High-level_programming_language higher level abstraction] programming languages. Example web search terms: assembler easy, assembler easier, assembler difficult. Source code written in higher level abstraction programming languages such as C and C++ are compiled to [https://en.wikipedia.org/wiki/Object_code object code] using a compiler. See [https://www.geeksforgeeks.org/difference-between-compiler-and-assembler/ this article] for an introduction and [https://media.geeksforgeeks.org/wp-content/uploads/20190823140215/compiler.png this image]. Source code written in lower level abstraction programming language assembler is converted to object code using an assembler. See the same article above and [https://contribute.geeksforgeeks.org/wp-content/uploads/assem.png this image]. Reverse engineering is very difficult for a reasonably complex program that is written in C or C++, where the source code is unavailable; that can be deduced from the high price for it. It is possible to decompile (meaning re-convert) the object code back to C with a decompiler like [http://boomerang.sourceforge.net Boomerang]. To put a price tag on it, consider this quote -- [http://boomerang.sourceforge.net/lostsource.php Boomerang: Help! I've lost my source code]:
How much will it cost? You should expect to pay a significant amount of money for source recovery. The process is a long and intensive one. Depending on individual circumstances, the quality, quantity and size of artifacts, you can expect to pay upwards of US$15,000 per man-month.
* [https://unix.stackexchange.com/questions/229802/convert-executable-back-to-c-source-code convert executable back to C source code]
The following resources try to solve the question of how to disassemble a binary (byte code) into assembly source code and re-assemble (convert) to binary. * [https://gts3.org/2015/rasm.html Tricks to Reassemble Disassembly] * [https://stackoverflow.com/questions/6327862/ida-pro-asm-instructions-change IDA pro asm instructions change] * [https://reverseengineering.stackexchange.com/questions/3800/why-there-are-not-any-disassemblers-that-can-generate-re-assemblable-asm-code Why there are not any disassemblers that can generate re-assemblable asm code?] * [https://reverseengineering.stackexchange.com/questions/3203/recompile-the-asm-file-ida-pro-created Recompile the asm file IDA pro created] * [https://www.researchgate.net/publication/323249543_Superset_Disassembly_Statically_Rewriting_x86_Binaries_Without_Heuristics Superset Disassembly: Statically Rewriting x86 Binaries Without Heuristics] * [https://gist.github.com/jarun/ea47cc31f1b482d5586138472139d090 GitHub: Guide to disassemble - disassemble.md] * [https://stackoverflow.com/questions/5125896/how-to-disassemble-a-binary-executable-in-linux-to-get-the-assembly-code How to disassemble a binary executable in Linux to get the assembly code?] * [https://reverseengineering.stackexchange.com/questions/22223/use-gcc-and-objdump-to-disassemble-any-hex-to-assembly-code Use GCC and objdump to disassemble any hex to assembly code] {{Box|text= '''1.''' Take a hello world assembler source code. '''2.''' Assemble. {{CodeSelect|code= nasm -felf64 hello.asm }} '''3.''' Link. {{CodeSelect|code= ld hello.o -o hello }} '''4.''' objdump (optional). {{CodeSelect|code= objdump -d hello }} '''5.''' Exercise for the reader: disassemble hello and re-assemble. The [https://en.wikipedia.org/wiki/GNU_Hello GNU Hello] program source file [https://git.savannah.gnu.org/cgit/hello.git/tree/src/hello.c hello.c] at the time of writing contains 170 lines. The objdump -d /usr/bin/hello on Debian buster has 2757 lines. {{Install Package|package= hello }} {{CodeSelect|code= objdump -d /usr/bin/hello | wc -l }}
2757
}}
For example, consider how difficult it was to reverse engineer Skype: [https://web.archive.org/web/20230330171636/https://www.oklabs.net/skype-reverse-engineering-the-long-journey/ Skype Reverse Engineering : The (long) journey ;)..] * Consider all the Debian package maintainer scripts. Clearly these are easier to review as is, since most of them are written in sh or bash. Review would be difficult if these were converted to a program written in C, and were closed source and precompiled. * Similarly, it is far preferable for OnionShare to stay Open Source and written in python, rather than the project being turned into a precompiled binary. Salary comparison ($K): * low - median - high * [https://www.salary.com/research/salary/posting/python-developer-salary Python]: 77 - 92 - 108 * [https://www.payscale.com/research/US/Job=Python_Developer/Salary Python]: 51 - 79 - 107 * [https://www.salary.com/research/salary/posting/c-programmer-salary C]: 56 - 80 - 100 * [https://www.payscale.com/research/US/Job=C_Developer/Salary C]: 49 - 80 - 112 * [https://www.salary.com/research/salary/posting/malware-reverse-engineer-salary Malware reverse engineering]: 101 - 124 - 149 * [https://www.payscale.com/research/US/Skill=Assembler_(Intel_x86%2FPentium)/Salary Assembler]: 81 - 104 - 131 * [https://www.talent.com/salary?job=Malware+Analyst Malware Analyst]: 75 - 115 - 141 It is obvious the cost of a security audit involving reverse engineering will be far greater than for source-available code.
Quote research paper [https://www.scss.tcd.ie/Doug.Leith/Android_privacy_report.pdf Android Mobile OS Snooping By Samsung, Xiaomi, Huawei and Realme Handsets]:
''Reverse Engineering'' A fairly substantial amount of non-trivial reverse engineering is generally required in order to decrypt messages and to at least partially decode the binary plaintext. 1) Handset Rooting: The first step is to gain a shell on the handset with elevated privileges, i.e. in the case of Android to root the handset. This allows us then to (i) obtain copies of the system apps and their data, (ii) use a debugger to instrument and modify running apps (e.g. to extract encryption keys from memory and bypass security checks), and (iii) install a trusted SSL root certificate to allow HTTPS decryption, as we explain below. Rooting typically requires unlocking the bootloader to facilitate access to the so-called fastboot mode, disabling boot image verification and patching the system image. Unlocking the bootloader is often the hardest of these steps, since many handset manufacturers discourage bootloader unlocking. Some, such as Oppo, go so far as to entirely remove fastboot mode (the relevant code is not compiled into the bootloader). The importance of this is that it effectively places a constraint on the handset manufacturers/ mobile OSes that we can analyse. Xiaomi and Realme provide special tools to unlock the bootloader, with Xiaomi requiring registering user details and waiting a week before unlocking. Huawei require a handset-specific unlock code, but no longer supply such codes. To unlock the bootloader on the Huawei handset studied here, we needed to open the case and short the test point pads on the circuit board, in order to boot the device into the Huawei equivalent of Qualcomm’s Emergency Download (EDL) mode. In EDL mode, the bootloader itself can be patched to reset the unlock code to a known value (we used a commercial service for this), and thereby enable unlocking of the bootloader.
''Decompiling and Instrumentation'' On a rooted handset, the Android application packages (APKs) of the apps on the /system disk partition can be extracted, unzipped and decompiled. While the bytecode of Android Java apps can be readily decompiled, the code is almost always deliberately obfuscated in order to deter reverse engineering. As a result, reverse engineering the encryption and binary encoding in an app can feel a little like exploring a darkened maze. Perhaps unsurprisingly, this is frequently a time-consuming process, even for experienced researchers/practitioners. It is often very helpful to connect to a running system app using a debugger, so as to view variable values, extract encryption keys from memory, etc.
The research paper describes in far more detail the highly complicated technical challenges of reverse engineering. To further improve the situation in the future, the Freedom Software community is working on the [https://reproducible-builds.org/ Reproducible Builds] project. Quote:
Reproducible builds are a set of software development practices that create an independently-verifiable path from source to binary code.
Whilst anyone may inspect the source code of free and open source software for malicious flaws, most software is distributed pre-compiled with no method to confirm whether they correspond. This incentivises attacks on developers who release software, not only via traditional exploitation, but also in the forms of political influence, blackmail or even threats of violence. This is particularly a concern for developers collaborating on privacy or security software: attacking these typically result in compromising particularly politically-sensitive targets such as dissidents, journalists and whistleblowers, as well as anyone wishing to communicate securely under a repressive regime. Whilst individual developers are a natural target, it additionally encourages attacks on build infrastructure as an successful attack would provide access to a large number of downstream computer systems. By modifying the generated binaries here instead of modifying the upstream source code, illicit changes are essentially invisible to its original authors and users alike. The motivation behind the Reproducible Builds project is therefore to allow verification that no vulnerabilities or backdoors have been introduced during this compilation process. By promising identical results are always generated from a given source, this allows multiple third parties to come to a consensus on a “correct” result, highlighting any deviations as suspect and worthy of scrutiny. This ability to notice if a developer has been compromised then deters such threats or attacks occurring in the first place as any compromise would be quickly detected. This offers comfort to front-liners that they not only can be threatened, but they would not be coerced into exploiting or exposing their colleagues or end-users. [https://reproducible-builds.org/who/ Several free software projects] already, or will soon, provide reproducible builds.
= Footnotes = {{Footer}}