C代写:CMSC414BufferOverflowsPart1


研究缓冲区溢出漏洞,并加以利用,编写程序,破坏程序原有逻辑结构。

Project Overview

This project will give you first-hand experience with buffer overflow attacks.
This attack exploits a buffer overflow vulnerability in a program to make the
program bypass its usual execution and instead jump to alternative code (which
typically starts a shell). There are several defenses against this attack
(other than fixing the overflow vulnerability itself), such as address space
randomization, compiling with stack guard, and making the stack non-
executable.
The learning objective of this lab is for students to gain first-hand
experience of the buffer-overflow attack. This attack exploits a buffer-
overflow vulnerability in a program to make the program by- pass its usual
execution sequence and instead jump to alternative code (which typically
starts a shell). Specifically, the attack overflows the vulnerable buffer to
introduce the alternative code on the stack and appropriately modify the
return address on the stack (to point to the alternative code). There are
several defenses against this attack (other than fixing the overflow
vulnerability), such as address space randomization, compiling with stack-
guard, dropping root privileges, etc.
In this lab, students are given a set-root-uid program with a buffer-overflow
vulnerability for a buffer allocated on stack. They are also given a
shellcode, i.e., binary code that starts a shell. Their task is to exploit the
vulnerability to corrupt the stack so that when the program returns, instead
of going to where it was called from, it calls the shellcode, thereby creating
a shell with root privilege. Students will also be guided through several
protection schemes implemented in Ubuntu to counter this attack.
Note: There is a lot of helpful information in Section 13; be sure to read it
before you get started. Also, if you get stuck, “Smashing the Stack for Fun
and Profit” and the lecture notes and slides will help.

Getting Set Up

This is the machine we will use for testing your submissions. If it doesn’t
work on that machine, you will get no points. It makes no difference if your
submission works on another Ubuntu version (or another OS).
The amount of code you have to write in this lab is small, but you have to
understand the stack. Using gdb (or some equivalent) is essential. The
article, Smashing The Stack For Fun And Profit, is very helpful and gives
ample details and guidance. Read it if you’re stuck.
Throughout this document, the prompt for an ordinary (non-root) shell is “$”,
and the prompt for a root shell is “#”.

Starter files

Starter files are available at the class projects page.

Disabling address space randomization

Ubuntu, and several other Linux-based systems, use “address space
randomization” to randomize the starting address of heap and stack. This makes
it difficult to guess the address of the alternative code (on stack), thereby
making buffer-overflow attacks difficult. Address space randomization can be
disabled by executing the following command:
$ sudo sysctl -w kernel.randomize_va_space=0
To re-enable ASLR, you simply run the above command but with a two instead of
a zero:
$ sudo sysctl -w kernel.randomize_va_space=2

Alternative shell program /bin/zsh

A “set-root-uid” executable file is a file that a non-root user can execute
with root privilege; the OS temporarily gives root privilege to the user. More
precisely, each user has a real id (ruid) and an “effective” id (euid).
Ordinarily the two are the same. When the user enters the executable, its euid
is set to root. When the user exits the executable, its euid is restored (to
ruid).
However if the user exits abnormally (as in a buffer-overflow attack), its
euid stays as root even after exiting. To defend against this, a set-root-uid
shell program usually drops its root privilege before starting a shell if the
executing process is only an effective (but not real) root. So a non-root
attacker would get a shell but it would not be a root shell. Ubuntu’s default
shell program, /bin/bash, has this protection mechanism. There is another
shell program, /bin/zsh, that does not have this protection scheme. You can
make it the default by modifying the symbolic link /bin/sh.
$ cd /bin
$ sudo rm sh
$ sudo ln -s /bin/zsh /bin/sh
Whenever you are not working on this project, you will want to change back to
running bash. You can do that by running the above commands with /bin/bash
instead of /bin/zsh.
Note: Avoid shutting down Ubuntu with /bin/zsh as the default shell! Instead,
in VirtualBox, chose to “Save the machine state.” Otherwise, when Ubuntu
reboots, the GNOME display is disabled and only a tty comes up. If that
happens, here are several fixes:
Log in, run the following:
$ sudo shutdown
A menu comes up. Choose “filesystem clean”, then “normal reboot”.
Log in, run the following:
$ sudo mount -o remount / mountsthefilesystemasread-write
$ sudo /etc/init.d/gdm restart restartsGNOMEDisplayManager

Compiling

We will be using gcc to compile all of the programs in this project. There are
a few non-standard ways we will be using gcc, like turning off basic
protection mechanisms, but this can all be done by providing gcc some
commandline arguments, which we describe here.
In general, we highly recommend creating a Makefile that will automate these
for you.

Working with a debugger

gdb will be your best friend in this project. To get useful information from
gdb regarding the names of functions and variables, include the -g commandline
argument to gcc.

Compiling to 32-bit

This semester, we will be using the latest, 64-bit version of Ubuntu. For the
sake of this project, how- ever, we will be running in 32-bit. To have gcc
compile to 32-bit, provide the following commandline option: -m32

Disabling compiler protections

The gcc compiler implements two security mechanisms that help protect against
buffer overflows and code injection. For the sake of this project, we will be
turning both of these off (but please leave them on in practice!).

  1. Canaries: gcc implements the idea in the “Stack Guard” paper by introducing canaries in each stack frame. You can disable this protection by compiling with the commandline argument -fno-stack-protector
  2. Non-executable stack: In the updated VM we are using, gcc by default will make the stack non-executable, thereby making it more difficult to launch arbitrary code. You can disable this with the commandline argument -z execstack

Putting it all together

To compile a program vulnerable.c into a binary named vuln, with the above
protections dis- abled, in 32-bit, and ready for gdb, you would run the
following command:
gcc -fno-stack-protector -z execstack -m32 -g vulnerable.c -o vuln

Task 0: Guessing Game

To get things started, consider the following simple program (provided in the
start-up files as guesser.c):
/* guesser.c /
#include <stdio.h> /
for printf() /
#include <stdlib.h> /
for EXIT_SUCCESS /
int your_fcn()
{
/
Provide THREE different versions of this,
* that each win the “guessing game” in main(). */
return 0;
}
int main()
{
int mine = 0;
int yours = 0;
yours = your_fcn();
mine = yours + 1;
if (mine > yours)
printf(“You lost!\n”);
else
printf(“You won!\n”);
return EXIT_SUCCESS;
}
—|—
This program runs a simple “guessing game” to see who can choose the biggest
number. It draws your number by calling your_fcn(), a function that you have
complete control over. It chooses its own number by just adding some to
yourshow convenient! Your task is to write not one but three different
versions of the function that each win the guessing game every time. As a
slight hint, note that the only way that we determine whether or not you win
is if the program prints “You won!” (followed by a newline) at the end.
We will be compiling them with address space randomization and stack
protection turned off and the stack executable (Sections 2 and 3).
Caveats. While you are allowed to set the body of your_fcn() as you wish, you
are not allowed to modify main() itself. Also, this task permits an exception
to the syllabus: hardcoding is allowed, if you think it will help you win! All
of your solutions must be fundamentally distinct. You do not have to use a
buffer overflow as one of your three solutions, but it is certainly one way to
go!
Submitting. Create three copies of the guesser: guesser1.c, guesser2.c, and
guesser3.c, each of which has a different implementation of your_fcn(). (There
are general submission instructions in Section 12.


文章作者: SafePoker
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 SafePoker !
  目录