Lab 2 - Buffer overruns

Obtaining the r00t shell

The purpose of this lab is to show how a
vulnerability in a program can be exploited to provide an attacker
with a shell
running with elevated rights.

In this lab, you are given a source of a
vulnerable program that is installed on the system. This program has the user
set-ID(s) bit set, which means that upon execution the proram will right with
the rights of the owner of the file and not the right of the current user. The
real user ID will still be the ID of the current user, but the effective user ID
will be that of the owner of the file. For example, a shell with the
s
bit set will be executed with the
rights of the owner of the program file.

Useful information

Login to the system, with the username 'dvader' and password 'luke'
(no quotes).

In the home directly you will find:

addhostalias.c:
The source code to the vulnerable binary

shellcode.h:
A C/C++ header file with IA32 shellcode in 75 bytes, with no nulls.

shellcode.py:
A Python script exporting the shellcode as a simple string. This file
may be useful if you choose to write an exploit with other tools, e.g.
Perl or Python.

The system contains suitable versions of gcc and gdb, as well as scripting interpreters such as perl and python. Networking tools such as curl and wget are also available.

It is recommended to SSH into the machine, rather than using the console. The VirtualBox file is set up to forward port 2222 on your host computer to port 22 on the guest system.
Use ssh -c aes256-cbc -p 2222 dvader@localhost

Since the system is old, no address-space
randomization is in place, nor is addhostalias compiled with stack protector checks (canaries). The call stack is executable.

We recommend creating the buffer overflow using Python, as this is the easiest and most straight forward solution.

If you want to send something built with Python as an argument to addhostalias, you can use $(python -c "program string") as an argument.

Deliverables

An explanation of how your exploit gains root access in detail, including memory layout.

Details on how you created the exploit, including how you found the return address (no bruteforcing).

Any scripts and/or programs you wrote or used.

Instructions how to regain root access, even without the root password. Clearly, rerunning the exploit is not a valid answer.

Include a comprehensive discussion of countermeasures at language and operating system levels. Give use cases for each countermeasure and discus how they can be deployed for the scenario of the lab.

Submissions with poor discussion of countermeasures will be rejected.

Notes and Links

Notes to keep in mind:

On the IA32 platform, the stack grows "downwards", i.e. items that are
higher on the stack have lower addresses.

Stack addresses depend on the environment, e.g. a program started in a
SSH session will have different stack addresses than if it was started
directly on the console.

Command line arguments are allocated and stored below the stack, so
their size will affect stack addresses.

IA32 has little-endian byte order. That means that e.g. the address
0xDEADBEEF will be stored in memory as the byte sequence 0xEF, 0xBE,
0xAD, 0xDE.

The solution might be
sensitive to the size of the environment.
The shellcode suggested will start a new shell, and does not exit it even if the r00ting fails.
This means, in the next attempt, you might be running in a nested shell and, therefore, in a different environment
The offset number depends of the stack addresses in that environment.
If your exploit successes in some deeply nested shell, might not be reproducible later.

Shellcode

The following shellcode is useful to build a buffer overrun. It avoids
null-characters, and fits in the buffer in the vulnerable program.
This file, and a C compatible version are included in the
virtual machine.