BufferOverflows - Opty-Forks/SSof GitHub Wiki

Buffer Overflow Exploitation

For this lab we propose a series of simple exercises 00_simple.c to 06_game_of_chance.c that were adapted from the Exploit Exercises Project namely the Protostar Project and from the book Hacking, The Art of Exploitation by Jon Erickson.

The goal of this session is to analyse and exploit buffer-overflow vulnerabilities. Buffer-overflow vulnerabilities occur when someone is allowed to write and/or to execute code in areas that one should not, and usually derives from the usage of unsafe functions like gets.

Modern OS's and compilers already incorporate some security features that prevent these attacks such as Canaries, Executable space protection (XP)/Data Execution Prevention (DEP), Address Space Layout Randomisation (ASLR), and Position Indepent Executable (PIE).

  1. Canaries (or Stack Cookies) are known values that are placed between a buffer and control data on the stack to monitor buffer overflows. When the buffer overflows occur, the first data to be corrupted will be the canary, and a failed verification of the canary data is therefore an alert of an overflow;
  2. Executable space protection (XP) prevents certain memory sectors, e.g. the stack, from being executable;
  3. Address Space Layout Randomisation (ASLR) is a security feature used to help prevent shell-code from being successful. It does this by randomly offsetting the location of modules and certain in-memory structures; and
  4. PIE is a compilation option that makes the binary position independent. This means that in the presence of ASLR the kernel loads the binary and dependencies into a random location of virtual memory each time the program runs.

Combining these protection techniques makes it very difficult to exploit vulnerabilities in applications using shell-code or return-oriented programming (ROP) techniques. In order for our attacks to succeed we'll thus need to disable them. For that we compiled our programs using the following flags (we use here vuln.c as the program to be compiled, and vuln as the generated binary).

Disable canaries: gcc vuln.c -o vuln -fno-stack-protector

Disable XP: gcc vuln.c -o vuln -z execstack

Enable XP: gcc vuln.c -o vuln -z noexecstack

Disable PIE: gcc vuln.c -o vuln -no-pie

ASLR is a security of the feature of the OS. To disable/enable ASLR we do it for the whole system:

Disable ASLR: echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

Enable ASLR: echo 2 | sudo tee /proc/sys/kernel/randomize_va_space

To interact with the server use the following snippet: netcat_template.py

Setup

Start by disabling ASLR in your VM as we need it for all our exercises.

If you are working on a VM other than the one we provided you, make sure you also have the 32-bit libraries installed

sudo dpkg --add-architecture i386 &&
sudo apt-get update &&
sudo dpkg --configure -a &&
sudo apt-get install libseccomp-dev:i386 seccomp:i386 libc6-dev-i386

Also, install some graphical plugin gor GDB. PEDA and pwndbg are 2 good ones.

Finally you may want to recall some GDB Basics here.


Task 1 -- Exercises with No Protection

0-Simple Overflow

Let us start with program 00_simple.c. The goal of this attack is to print the message YOU WIN!!! in the screen. How can we do it?

  • Recall how variables are stored in the stack; can variable buffer interfere with variable control?
  • You might want to use GDB to see where buffer and control are stored in memory and how many bytes they are apart.
  • Do not know how to use GDB? A quick GDB-101 with a list of basic GDB commands can be found here.

This file was compiled with no canaries and -no-pie and is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 9990.

1-Match an Exact Value

Now that you know how to overflow a buffer, can you do it with an exact value?. 01_match.c file was compiled with no-canaries and -no-pie. The goal of this attack is to print the Congratulations message in the screen. Can you do it?

  • Recall that 0x61626364 is the string abcd;
  • Are you getting 0xWWXXYYZZ instead of 0xZZYYXXWW? Have you heard of little-endian and big-endian?

This challenge is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 9991.

2-Calling Functions

Ok, you already know how to overflow a buffer in a controlled way and change variables to an exact value. But can you call a function that is not called anywhere in our code?
File 02_functions.c was compiled with no-canaries and -no-pie. The goal of this attack is to call function win and print the Congratulations message on the screen. Can you do it?

  • Recall that the name of a function in C is the address where this function is written in the memory;
  • Can fp be win?
  • To perform this attack you may need to input chars that are non-printable. In the end of this document you have some suggestions on how to do it.

This challenge is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 9992.

3-Return Address

You now know everything about the stack and how to change its values, change the functions that are called and so on. But can you call a function even if NO function is called anywhere in our code?

File 03_return.c was compiled with no-canaries and -no-pie. The goal of this attack is to call function win and print the Congratulations message in the screen. Can you do it?

  • Recall that the name of a function in C is the address where this function is written in the memory;
  • Is it true that no function is called in our program? How can you call win? Recall how the stack is organised and what are the values stored in the stack.

This challenge is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 9993.

4-Unhauthorized Access

The goal of this attack is to gain access to the system without introducing the correct password. Can you do it? Elaborate on Exercise 1.

File 04_auth.c was compiled with no-canaries and -no-pie, and is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 9994.

5-Game of Chance

We have now a more serious game. Can you make a profit out of the house? Can you win the jackpot?

File 06_game_of_chance.c was compiled with no-canaries and -no-pie, and is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 9996.

To run this challenge locally you need to create the folders that are used in line 165 to store user data. For that run

sudo mkdir /home/ctf
sudo mkdir /home/ctf/data
sudo chown -R <your_user>:<your_user> /home/ctf

Task 2 -- Exercises with Active Protection (Extra class)

6-ASLR (Extra class)

Now everything changes in each run given that ASLR is enabled. The stack and the code are always in a different place. Can you still win the game? (with some help from our friends...)

Do not forget to enable ALSR to run this challenge locally (and disable it afterwards).

File 01_aslr_leak.c was compiled with no-canaries but does not allow execution in the stack (XP enabled). It is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 10151.

7-Canaries (Extra class)

Canaries are in place to protect us and prevent buffer overflows. Really?

Do not forget to disable ALSR again.

File 01_canary_basic.c was compiled with canaries and does not allow execution in the stack (XP enabled). It is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 10201.

8-More Canaries (Extra class)

Oh 7-Canaries was just to easy. Now we will not leak the canary for you. Good luck!

File 02_canary_leak.c was compiled with canaries and does not allow execution in the stack (XP enabled). It is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 10202.

9-EvenMore Canaries (Extra class)

You will never be able to succeed in this challenge. Do not even try.

File 03_param_change.c was compiled with canaries and does not allow execution in the stack (XP enabled). It is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 10203.

10-ASLR++ (Extra class. This one is tough!)

Follow-up of 6-ASLR. Our friends provided you to much help leaking the address of the function. Can you do it on your own? Everything is changing again in each run given that ASLR is enabled.

Do not forget to enable ALSR to run this challenge locally (and disable it afterwards).

File 02_aslr2_leak.c was compiled with no-canaries but does not allow execution in the stack (XP enabled). It is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 10152.

Tip: You can use pwntools instruction elf.symbols['fn'] to get the address of function fn in binary bin and next(elf.search(string)) for the address of the occurrence of string in the binary.

from pwn import *

context.arch = 'i386'
context.os = 'linux'

elf = ELF('./bin')
addr_fn = elf.symbols['fn']
addr_string = next(elf.search(string))

11-Welcome to your first ret2libc (Extra class. This one is even tougher!)

Enough. Now you can no longer execute code in the stack. Can you still call /bin/sh?

Do not forget to disable ALSR again.

File 01_retlibc.c was compiled with no-canaries and -no-pie but does not allow execution in the stack (XP enabled). It is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 10101.

Tip: It might be worth reading this, in particular how the stack frame has to be constructed (middle page 7-top page 11).

12-ROP (Extra class. This one is 31337!)

Follow-up of 11-Welcome to your first ret2libc. Calling system was just to simple so we removed it from our bin. Can you still do it without system?

Do not forget to disable ALSR again.

Tip: Have you heard of ROPGadget? It might be useful to generate the ROP-chain for this challenge.

File 05_rop_get_shell was compiled with no-canaries and -no-pie but does not allow execution in the stack (XP enabled). It is running at nc mustard.stt.rnl.tecnico.ulisboa.pt 10105.


Extras - Strings with non-printable chars

You may need to input chars that are non-printable to perform some of these attacks. If you do not want to script it, the easier way to do it is to write such input string to a file, and then use this file as input to the program. For this, do the following:

python -c 'print string1 + string2 + ... + stringn' > input-file.txt

./program < input-file.txt

Example:

python -c 'print "\x48\x31\xc0\x48" + "\x90" * 30 + "\x7f\x00\x00"' > input-exerciseX.txt

./file < input-exerciseX.txt

You can also use echo -e

echo -e "\x48\x31\xc0\x48\x90\x7f\x00\x00" > input-exerciseY.txt


Extras - Some pwntools commands

  • from pwn import * --- load pwntools library.

  • p32(address) --- writes address 0xAABBCCDD as a string in little-endian DDCCBBAA.

  • elf = ELF('./bin') --- reads ELF binary bin

  • elf.symbols['fn'] --- returns the address of function fn in the binary (previously read to var elf)

  • next(elf.search(string)) --- returns the address of the occurrence of string in the binary.

⚠️ **GitHub.com Fallback** ⚠️