In order to attempt to exploit a system’s vulnerabilities it is important to understand the levels to which a computer or electronic system is built upon. There are many ways to depict the layers that make up electronic devices but the point that I will try to get across remains the same – that there are different layers to the overall design that certain parties are responsible for handling.
Electronic devices are layered into respective domains to reduce the level of complexity for individuals who work within other areas of the stack. It’d be inconceivable to expect one person to know a computer and its operations inside and out; however, that would be quite the accomplishment for an individual whom achieved this ability. At its simplest form and to put things into perspective, hardware engineers are responsible for the circuitry of system boards; handling electricity, transistors, logic gates, etc. They then hand off the physical hardware and an ability to interface with it to software engineers. So, there are two main domains: hardware and software. Within each you can abstract even more but for simplicity in this blog, we’re only going to focus on the software domain.
The software domain is composed of application developers, various programming languages and developers therein, libraries offered by an operation system’s (OSs) API, etc. As we can see, there are many areas of software development and within each lies potential mishaps and human error. This is where quality assurance comes in handy but it’s unrealistic to expect it to catch all unintended behaviors, which only broadens the exploit / attack surface potential. The good guys would research these surfaces and report them to the developer via bugs, whereas the bad guys would use the surface as a potential way to take advantage. To provide some sort of visual aid to better understand just how layered these domains can get, the following is an awesome example:
Be sure to check out the references for more detail about understanding these particular levels, as each layer offers some attack surface that’s susceptible to exploitation. Again, we’re going to focus on the software domain aspect as physical manipulation requires physical access to a computer system. Your servers and network devices are secured behind authorized access-only doors, right?
Within the software domain is the ability to categorize software applications in certain “spaces” denoted by 4 distinct rings: user space (ring 3) versus kernel space (ring 0). Software in the user space is where end users commonly interact with a computer system, and that piece of software makes appropriate system calls to an OS’s API for library functions or other lower-level system calls – the kernel space. Examples of these system calls include memory allocation, executing new processes, or accessing hard disks. The higher the ring, the less privilege to certain tasks and function; therefore, the lower you get the more privilege there is to lower-level functions. Here’s a great depiction of this:
In this fairly simple perspective, any application in the user space is what an end user might typically interact with whereas the tasks behind that application make the appropriate system calls into the kernel space. Now not just anything can make its way into kernel space, there are checks in place to ensure calls are made properly and within limits of reasonable usage.
By this point you might be asking what I am trying to get to and how does this help to potentially identify vulnerabilities and exploits. The complexity in this can be daunting but I urge you to stick with me to better understand the vectors in which vulnerabilities can be taken.
Starting with the Instruction Set Architecture (ISA), which warrants a post on its own but is included here as a starting point. It’s a protocol that covers how computers process data bits – that is, it defines how to translate 1’s and 0’s – and machine language programming / assembly. This is developed by humans and is therefore prone to errors. A few examples of exploits here would be Meltdown, Spectre, and Lazy FPU.
Working up from there, per the previously depicted “Layers of Abstraction” graph, each of these layers is potentially vulnerable because of the human factor. Programming languages set the base in which applications for user interaction are developed. You might have a Java, or Python / PHP, etc. application and if they’re not developed properly, then the application could crash causing all input to be lost. Alternatively, you can also have malformed system calls by these applications that allow the remote execution of arbitrary code. Examples of these would be recent Office exploits, Flash player, and others.
In summary, any level that requires human involvement, which is pretty much at any level, is prone to mishaps or erroneous code developments. Thus, the attack vector is wide per the abstraction layers, although that doesn’t mean it’s that easy to exploit by just anyone. The measures in place that validate system calls or deny them are there but they’re equally prone to errors. We can only hope that independent security researchers and users responsibly report bugs or flaws appropriately, and that the developers of said applications patch the vulnerability. Otherwise, we’re susceptible to threat actors discovering these vulnerabilities and taking advantage of unknowing prey.
Atwood, J. (January 3, 2008). Understanding User and Kernel Mode. Retrieved from https://blog.codinghorror.com/understanding-user-and-kernel-mode/
Bansal, G. G. (October 6, 2013). Overview of Computer Abstraction: Computer Abstractions, and Technology. Retrieved from http://girdhargopalbansal.blogspot.com/2013/10/computer-abstractions-and-technology.html
[CSP-AIMS online course]. (November 10, 2015). Abstraction in Computer Science[Video File]. Retrieved from https://www.youtube.com/watch?v=i55nz9xAtJE
EDC.org, Contributors. The Beauty and Joy of Computing – BJC: Abstraction Inside the Computer. Retrieved from https://bjc.edc.org/bjc-r/cur/programming/6-computers/1-abstraction/01-abstraction.html?topic=nyc_bjc%2F6-how-computers-work.topic&course=bjc4nyc.html&novideo&noassignment
Hernandez, C. I. (February 24, 2017). Abstraction Layers: From Atoms to Apps. Retrieved from https://email@example.com/abstraction-layers-from-atoms-to-apps-1888e7943f14
McCarty, S (July 29, 2015). Architecting Containers Part1: Why Understanding User Space vs. Kernel Space Matters. Retrieved from https://rhelblog.redhat.com/2015/07/29/architecting-containers-part-1-user-space-vs-kernel-space/