Skip to content

Learning Binary Exploitation — Part 2

Published: at 02:25 PMSuggest Changes

After understanding the basics of how the memory diagram looks and how the stack works, I moved on to the exploitation part.

This is the program that I used to experiment:

#include <stdio.h>

void forbidden() {
  printf("The forbidden function\n");
}

void allowed() {
  char buffer[10];
  scanf("%s", buffer);
  printf("You are now inside the allowed function: %s \n", buffer);
}

int main() {
  allowed();
  return 0;
}

Stack Protection

There are a couple of safety measures in place to prevent stack overflow based attacks, which I had to deal with first:

  1. ASLR: It stands for Address Space Layout Randomization, it randomly arranges the address space positions of key data areas which makes it difficult to locate various parts of the program.

    To disable it I had to set the value of randomize_va_space = 0:

    echo "0" | sudo dd of=/proc/sys/kernel/randomize_va_space
    

    Make sure you change it back to its original state after you’re done compiling the code.

  2. Stack Canaries: According to Wikipedia:

    Stack canaries, named for their analogy to a canary in a coal mine, are used to detect a stack buffer overflow before execution of malicious code can occur. This method works by placing a small integer, the value of which is randomly chosen at program start, in memory just before the stack return pointer

    To disable this I simply had to compile my code with -fno-stack-protector flag.

Compiling the Code

After disabling these security features, I compiled my code:

gcc -m32 -g -fno-stack-protector unsafe.c -o unsafe -z execstack

P.S. I was facing some issues after compiling this code on my system, so I used a VM to compile this code and transferred it to my host system.

Finding the Offset

In my code I had allotted 10 bytes to our buffer. So, I can try with 14 or 18 bytes of input to overflow the buffer.

Buffer Overflow Demonstration

18 bytes it is! Now I know that we can overwrite the buffer after 18 bytes.

Ohh, by the way, you may have noticed we the function ‘forbidden’ is not being called in our code. So, in order to call that function, I used the base pointer of the function ‘forbidden’ to overwrite the $eip. That way, our instruction pointer will point to the beginning of the forbidden function, thus making a function call.

Finding the Required Address and Overwriting $eip

Finding the $ebp of forbidden using objdump -d ./unsafe

Objdump Output of Forbidden Function

The highlighted address is the address we need. I used the filled the first 18 bytes to overflow the stack, then used 4 bytes of NOP (\x90) for padding and finally overwrote the $eip with the $ebp of the forbidden function.

Stack Overflow Execution

As you can see, there’s the output of the printf from the forbidden function “The forbidden function”

Register State During Overflow

In the above image, I had provided the input python2 -c 'print "A"*18+"\x90"*4+"BBBB"'. So, the NOPs overwrite the $ebp and “BBBB” overwrites the $eip (\x42 is the Hex code of B). And replacing BBBB with the address of the forbidden function (“\x8b\x84\x04\x08”) executes the forbidden function.

Final Exploitation Demonstration

Thank you for reading.


Previous Post
Learning Binary Exploitation — Part 3
Next Post
Learning Binary Exploitation — Part 1