1. (25 points) True and False with Justification (2 for True/False and 3 for Justification for each question)
a. Shellcode developed for i386/Linux cannot be used to exploit a Buffer-Over-Flow-vulnerable program running on SPARC/Solaris. (SPARC and i386 correspond to different instruction sets)
b. The StackGuard solution (“canary word” solution) includes the operation to push a number into the stack for detection.
c. The control-flow-integrity solution includes the operation to push a number into the stack for detection.
d. The instruction-set randomization solution includes the operation to push a number into the stack for detection.
e. A kernelized reference monitor analyzes the interactions between a user-space process with the kernel (e.g., analyzing system calls). A browser loads a plugin into its memory in the user space of the memory and this plugin modifies some critical data inside the user-space-based memory for this browser. This modification is visible to the reference monitor.
2. (10 points) In order to launch successful buffer-over-flow attacks, one problem is we need to guess *exactly* where the address of our code will start. If we are off by one byte more or less we will just get a segmentation violation or an invalid instruction. Please propose one solution to increase the chance of success. (hint: the answer can be found in the “Smashing The Stack For Fun and Profit” paper.)
3. (10 points) The shellcode and BoF attack layout discussed in the “Smashing” article can be summarized in the following figure (e.g., Figure 2). However, the size of the shellcode is bounded by the size of the buffer to be exploited. In certain cases, the size of the shellcode might be too large to be put into the buffer to be exploited. Please propose one solution to solve this challenge (you should plot the stack layout of your solution.) (hint: the answer can be found in Section V. – Page 7 and 8 in the “Buttercup” paper.)
4. (15 points) Consider the following C code fragment. We have a server program that uses this fragment once to process user input (both “input” and “i” are provided by unprivileged users). We compile the server program in a 32-bit operating system, in which the type of int, memory address, and registers, such as EIP, EBP, as well as ESP, are represented by 32 bits.
a. Is it possible to design an attack to exploit this “foo” function so that the CPU will execute an instruction at an arbitrary address in the user space? Please plot the stack layout and your attack. (5 points)
b. Will the StackGuard approach be able to detect this attack? Please justify. (5 points)
c. Will the control flow integrity approach be able to detect this attack? Please justify. (5 points)
void foo(int i, int *input){
int *arr[10];
arr[i] = input;
}
6
code is placed at the center, and then followed with the return addresses. If the return address
points anywhere in the string of NOPs, they will just get executed until they reach the shell code.
Assuming the stack starts at 0xFF, that S stands for shell code, and that N stands for a NOP
instruction, the new stack would look like this:
bottom of EEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF top of
memory 123456789AB CDEF 0123 4567 89AB CDEF memory
buffer sfp ret a b c
<----- [NNNNSSSSSSS][0xE2][0xE2][0xE2][0xE2][0xE2]
^ |
|_____________________|
Fig. 2: Structure (graphical representation) of a buffer overflow exploit
IV. Polymorphic shellcode
Polymorphic shellcode [8] is basically a functionally equivalent form of a buffer overflow exploit
with a different signature on the network. The attack code is subtly transformed such that it looks
different from the known signature. As it hits the target machine, it reassembles, having eluded
the IDS [9].
A well-known tool that generates polymorphic shellcode is a polymorphic buffer-overflow engine
called ADMutate [10]. An attacker feeds the ADMutate a buffer overflow exploit to generate
hundreds or thousands of functionally equivalent exploits [11]. This is accomplished by using
simple encryption techniques, along with the substitution of functionally equivalent machine-
language instructions. This confuses many IDS tools (including Snort) that search for the familiar
NOP sled or the known machine-language exploit included in buffer overflows, as ADMutate
dynamically modifies these elements.
A buffer overflow attack script consists of three parts, a set of NOPs, the shellcode, and the return
address in the form [NNNN][SSSS][RRRR]. In polymorphic shellcode, the NOPs are replaced by
a random mix of no-effect instructions and the shellcode is encrypted differently each time, thus
making signature-based detection by an NIDS, that looks for NOPs or certain strings within the
shellcode, impossible. Having generated encoded shellcode and substituted NOPs, ADMutate
6code is placed at the center, and then followed with the return addresses. If the return address points anywhere in the string of NOPs, they will just get executed until they reach the shell code. Assuming the stack starts at 0xFF, that S stands for shell code, and that N stands for a NOP instruction, the new stack would look like this: bottom of EEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF top of
memory 123456789AB CDEF 0123 4567 89AB CDEF memory
buffer sfp ret a b c
<----- [NNNNSSSSSSS][0xE2][0xE2][0xE2][0xE2][0xE2]
^ |
|_____________________|
Fig. 2: Structure (graphical representation) of a buffer overflow exploit
IV. Polymorphic shellcode
Polymorphic shellcode [8] is basically a functionally equivalent form of a buffer overflow exploit
with a different signature on the network. The attack code is subtly transformed such that it looks
different from the known signature. As it hits the target machine, it reassembles, having eluded
the IDS [9].
A well-known tool that generates polymorphic shellcode is a polymorphic buffer-overflow engine
called ADMutate [10]. An attacker feeds the ADMutate a buffer overflow exploit to generate
hundreds or thousands of functionally equivalent exploits [11]. This is accomplished by using
simple encryption techniques, along with the substitution of functionally equivalent machine-
language instructions. This confuses many IDS tools (including Snort) that search for the familiar
NOP sled or the known machine-language exploit included in buffer overflows, as ADMutate
dynamically modifies these elements.
A buffer overflow attack script consists of three parts, a set of NOPs, the shellcode, and the return
address in the form [NNNN][SSSS][RRRR]. In polymorphic shellcode, the NOPs are replaced by
a random mix of no-effect instructions and the shellcode is encrypted differently each time, thus
making signature-based detection by an NIDS, that looks for NOPs or certain strings within the
shellcode, impossible. Having generated encoded shellcode and substituted NOPs, ADMutate