2 questions regarding ASLR - security

I've been reading about ASLR and I have a couple of questions. I have little programming experience but I am interested in the theory behind it.
I understand that it randomizes where DLLs, stacks and heaps are in the virtual address space so that malicious code doesn't know their location, but how does the actual program know their location when it needs them?
If the legitimate process can locate them, what stops the malicious code doing the same?
and finally, is the malicious code that ASLR tries to prevent running in the user space of the process it is attacking?
Thanks

As background, ASLR is intended to complicate code injection attacks where the attacker tries to utilize your overflow bug to trick your application into running the attacker's code. For example, in a successful stack buffer overflow attack the attacker pushes their code onto the stack and modifies the call frame's return pointer to point to the on-stack code.
Most code injection attacks require the attacker to know the absolute address of some part of your process's memory layout. For stack buffer overflow attacks, they need to know the address of the stack frame of the vulnerable function call so they can set the functions return pointer to point to the stack. For other attacks this could be the address of heap variables, exception tables, etc...
One more important background fact: unlike programming languages, machine code has absolute addresses in it. While your program may call function foo(), the machine code will call address 0x12345678.
but how does the actual program know their location when it needs them?
This is established by the dynamic linker and other operating system features that are responsible for converting your on-disk executable into an in-memory process. This involves replacing references to foo with references to 0x12345678.
If the legitimate process can locate them, what stops the malicious code doing the same?
The legitimate process knows where the addresses are because the dynamic linker creates the process such that the actual addresses are hard-wired into the process. So the process isn't locating them, per se. By the time the process is started, the addresses are all calculated and inserted into the code. An attacker can't utilize this because their code is not modified by the dynamic linker.
Consider the scenario where an attacker has a copy of the same executable that they are trying to attack. They can run the executable on their machine, examine it, and find all of the relevant addresses. Without ASLR, these addresses have a good chance of being the same on your machine when you're running the executable. ASLR randomizes these addresses meaning that the attacker can't (easily) find the addresses.
and finally, is the malicious code that ASLR tries to prevent running in the user space of the process it is attacking?
Unless there's a kernel injection vulnerability (which would likely be very bad and result in patches by your OS vendpr), yes, it's running in the user space. More specifically, it will likely be located on the stack or the heap as this is where user input is stored. Using data execution prevention will also help to prevent successful injection attacks.

Related

Why is eBPF said to be safer than LKM?

when talking about ebpf advantage, it always mentions safe than lkm.
I read some documentation, ebpf ensures safe by verifying code before it loaded.
these are checklists that verify to do:
loops
out of range jumps
unreachable instructions
invalid instructions
uninitialized register access
uninitialized stack access
misaligned stack access
out of range stack access
invalid calling convention
most of these checks I can understand, but it's all reason that lkm cause kernel panic? if do these can ensure safe?
I have 120000 servers in production, this question is the only reason to prevent me to migrate from traditional hids to ebpf hids. but if it can cause a kernel panic on a large scale, only one time, our business will be over.
Yes, as far as I know, the BPF verifier is meant to prevent any sort of kernel crash. That however doesn't mean you can't break things unintentionally in production. You could for example freeze your system by attaching BPF programs to all kernel functions or lose all connectivity by dropping all received packets. In those cases, the verifier has no way to know that you didn't mean to perform those actions; it won't stop you.
That being said, any sort of verification is better than no verification as in traditional kernel modules. With kernel modules, not only can you shoot yourself in the foot as I've described above, but you could also crash the whole system because of a subtle bug somewhere in the code.
Regardless of what you're using, you should obviously test it extensively before deploying to production.

How Process can Share array2(the oracle array) in Spectre Attack?

In spectre paper, the PoC place Victim and Attacker code in same process.
The code is like this:
if (x < array1_size)
y = array2[ array1[x] * 256 ];
So Attacker and victim can use the same array2(because they are in same code, process).
But in real world, Attacker and Victim is separated(they are different process), so they can't share array2.
So here is my question, in this case, How can Attacker measure access time to array2?
How can Attacker know array2's address?
I have no idea how to attacker access to array2. What is misunderstood here?
The code from the question refers to Spectre Variant 1, also known as bounds check bypass.
What is misunderstood here?
Instead of thinking of Variant 1 in terms of victim process and attacker process, think of it as sandboxed attacker code, whose goal is to read memory outside of its sandbox.
In other words, the attacker controls some code which runs within a software sandbox, and this software sandbox would normally enforce that each code domain only accesses its own data.
However, Spectre allows the attacker's code to bypass such sandbox's enforcements.
For example, the attacker provides Javascript code for a malicious website which will be sandboxed by the Javascript interpreter upon execution.
The Javascript interpreter would check that code such as y = array2[ array1[x] * 256 ] can only execute if x < array1_size.
This is called bounds check and serves to ensure that the website is not allowed to read from the address space of the browser process running it.
Upon execution, the attacker (who controls x) can perform conditional branch misprediction by having their own code train the branch predictor to take the branch if (x < array1_size).
Finally, the attacker will set x to a desired, out-of-bounds value which, because of Spectre, will allow them to bypass the bounds check of the sandbox and read memory from the address space of the browser process.
In summary, the attacker here controls the code of a (sandboxed) website and Spectre allows them to read memory of the browser where the website is opened (which would normally be prevented by the sandbox).
The second example uses eBPF, where the attacker injects and executes some code from the Linux kernel.
The eBPF interface allows unprivileged users to do so.
This code would normally be executed in a in-kernel VM/sandbox which performs bounds checks to prevent the loaded code from reading arbitrary memory.
However, Spectre allows an attacker violate this sandboxing outside of the BPF sandbox and leak arbitrary memory.
In summary, the attacker here is an unprivileged user of the host and Spectre allows them to read arbitrary memory on the host!
But in real world, Attacker and Victim is separated(they are different process)
Not in this case.
As explained above, in Spectre Variant 1 the "victim's code" encapsulates the "attacker's code" within the same process.
The attacker's code would normally be isolated by the victim using a software sandbox, but Spectre allows to bypass that and read any memory in the victim's address space.
To attack across address spaces without shared memory, you'd need a different side-channel.
Maybe you'd have the spectre gadget result in eviction of one of the lines in your array, so you have to time groups of 8 entries (that all index the same set in cache) instead of 1 at a time, because the eviction could have been any line of a set.
It can be done without shared memory.

C Windows/Linux Buffer Overflow Exploits

I have looked at how the buffer overflows work and have to determine that the program (with gcc) must compile with the following parameters: -fno-stackprotector and -z execstack.
You have to tell the kernel that it does not randomly allocate the addresses every time you start the program (which, however, is not absolutely necessary, just makes the buffer overflow easier)
Should a person now write an exploit e. g. against Apache, the Apache Developers will not compile the program with the above parameters.
How would these exploits still work?
-fno-stack-protector disables canary which is a random value placed between a function frame and saved instruction pointer. -zexecstack makes the stack memory region executable so that code execution is easy. With both these protections disabled its much easier to write exploits. Sometimes Address Space Layout Randomization (ASLR) is also disabled which means that all offsets in memory will be same on each execution.
For people who are starting with exploit development these protections are turned off so that they appreciate the techniques and attack vectors.
However with actual softwares such as apache, they are usually compiled with all protections (additionally PIE, RELRO). But there exist techniques that will help you to get code execution. One of them is called Return Oriented Programming(ROP) when used properly helps you defeat NX(non executale memory regions). Additionally to bypass ASLR/PIE you'll need one more leak primitive to get addresses from the memory. Its not impossible to write exploits for modern software its just difficult.

Relevant debug data for a Linux target

For an embedded ARM system running in-field there is a need to retrieve relevant debug information when a user-space application crash occurs. Such information will be stored in a non-volatile memory so it could be retreived at a later time. All such information must be stored during runtime, and cannot use third-party applications due to memory consumption concerns.
So far I have thought of following:
Signal ID and corresponding PC / memory addresses in case a kernel SIG occurs;
Process ID;
What other information do you think it's relevant in order to indentify the causing problem and be able to do a fast debug afterwards?
Thank you!
Usually, to be able to understand an issue, you'll need every register (from r0 to r15), the CPSR, and the top of the stack (to be able to determine what happened before the crash). Please also note that, when your program is interrupt for any invalid operation (jump to invalid address, ...), the processor goes to an exception mode, while you need to dump the registers and stack in the context of your process.
To be able to investigate, using those data, you also must keep the ELF files (with debug information, if possible) from your build, to be able to interpret the content of your registers and stack.
In the end, the more information you keep, the easier the debug is, but it may be expensive to keep every memory sections used by your program at the time of the failure (as a matter of fact, I've never done this).
In postmortem analysis, you will face some limits :
Dynamically linked libraries : if your crash occurs in a dynamically loaded and linked code, you will also need the lib binary you are using on your target.
Memory corruption : memory corruption usually results in the call of random data as code. On ARM with linux, this will probably lead to a segfault, as you can't go to an other process memory area, and as your data will probably be marked as "never execute", nevertheless, when the crash happens, you may have already corrupted the data that could have allow you to identify the source of the corruption. Postmortem analysis isn't always able to identify the failure cause.

How a process can refer to objects that are not in its address space (for example, a file or another process)?

I have the homework question:
Explain how a process can refer to objects that are not in its
address space (for example, a file or another process)?
I know that each process is created with an address space that defines access to every memory mapped resource in that process (got that from this book). I think that the second part to this question does not make sense. How can a process reference an object of another process? Isn't the OS suppose to restrict that? maybe I am not understanding the question correctly. Anyways if I understood the question correctly the only way that will be possible is by using the kernel I believe.
If you are asking it in a general sense, then its a no. Operating systems do not allow one process to access another process's virtual address space under the normal circumstances.
However there are ways in which you can create a controlled environment where such a thing can be done using various techniques.
A perfect example is the debugger. It uses process tracing mechanism (like reading from /proc filesystem or using the ptrace() system calls) to gain access to read and write from another address space.
There is also a shared memory concept, where a particular piece of memory is explicitly shared between two processes and can be controlled via a shared memory object.
You can attach as a debugger to the application. Or if using Windows, you can use windows hooks
I have researched and I have the answer to the file part of the question.
first of an address space is the collection of addresses that a
thread can reference. Normally these addresses reference to an
executable in memory. Some operating systems allow a programmer to
read and write the contents of a file using addresses from the process
address space. This is accomplished by opening the file, then binding each byte in the file to an address in the address space.
The second part of the question this is what I will answer:
Most operating systems will not allow reading addresses from another
process. This will imply a huge security risk. I have not heard of any
operating system that enables you to read data from a thread that is
not owned by the current process. So in short I believe this will not
be possible.

Resources