Shellcode Development
General registers (accoumlators) - an accumulator is a register in which intermediate arithmetic and logic results are storedan accumulator is a register in which intermediate arithmetic and logic results are stored.
For more information the "IA-32 Intel® Architecture Software Developer's Manual Volume 1: Basic Architecture" is a good starting point. 6.1.2Virtual Memory conceptsVirtual memory is a construct implemented in as a subsystem of a processor. It essentially allows processes to operate as if they were alone on the system [5] as well as provide perpetual contiguous memory. Figure 1 - Virtual Memory [6] 6.1.3Basic knowledge of Compilers and DebuggersA basic understanding of C/C++ compilers is also necessary in order to be aware of intricacies in what the assembly code generated will be and also compiler constructs to optimize code and also the layout of the program in memory depending on the addressing mode. Experience with debuggers will prove useful for generating and analyzing disassembled code. Illustrations and examples in section 5.3 use the gdb compiler. 6.2Program flow dynamicsWe assume the reader is understands fundamental concepts of computing and the x86 architecture. As Shellcode interrupts the normal flow of a process, it is important to understand how the instructions of a program are executed, how the process makes use of registers and memory and also how function calls are handled using a call stack. The stack is a memory area allocated by the operating system, it essentially used to hold the execution states of process, and a level of the stack represents an execution text of variables in that state and the return address to a memory area where the next instruction exists. Context transitions occur when a function is called, or when a hardware or software interrupt is serviced. The following diagram is an illustration of how a program is organized in memory. The text region is determined by the program; it includes code and read only data. The data region contains static variables and dynamic memory allocated by the program. The stack region is the focus area pertaining to shellcode, because a stack overflow is the means by which shellcode can be injected into a running program. “A stack is an abstract data type frequently used in computer science. As stack of objects has the property that the last object placed on the stack will be the first object removed. This property is commonly referred to as last in, first out queue, or a LIFO. [4]” The following illustration, reworked from “Smashing The Stack For Fun And Profit [4]” demonstrates how a process uses the stack. We start of with a simple program that makes a call to function ‘A’ which takes 3 arguments. Function A declares 2 character arrays and returns. The diagram below shows the C code and corresponding assembly code: When function A is called, its arguments are first pushed on the stack, followed by the RET address which is the address of the next instruction following the function call. Following that are the local variables Buffer1 and Buffer 2. The following diagram shows the stack right before the epilog portion of function A which is not shown in the assembly code above. Notice that Buffer2 and Buffer1 are using more space that was declared in the function code, the additional bytes are necessary since records can only be addressed in multiples of 4 bytes, hence the compiler compensates by putting in extra bytes. 6.3Introduction to Stack based buffer overflowsTo illustrate the buffer overflow we use a simple program which initializes a string of 8 bytes and passes it to a function A, which takes character pointer and copies the string into a local buffer. Because there is no bounds checking in function A, it will copy the entire string overwriting SFP and RET location in the stack. This mechanism can be used to modify the RET address. If the contents of the string were to be populated with machine opcodes and padded with an address which points to first instruction Buffer1 in this case, we would have achieved a means to execute foreign code. This is the crux of how ShellCode can be injected into a running program. In this scenario the address AAAA may be an address that lies outside the process’s memory area and a segmentation violation will be triggered. 7Developing the Shellcode7.1Finding the vulnerability /Buffer OverflowSystematic methods to detect a buffer flow are available. A trail an error approach is always an option. Simply execute the target application and specify large parameters, a segmentation fault is will indicate that a buffer overflow has occurred. 7.2Writing the Shellcode:Shellcode is sequence of machine instructions or opcode. Opcode can be written directly in hexcode, or they can be written in assembly and converted to the opcodes, or they can be written in C in which case the assembly and then the opcodes must be extracted. To take advantage of the injected code and to gain access to the target system, system calls must be used. System calls are “a special case of a software initiated trap … the machine instruction used to initiate a system call typically causes a hardware trap that is handled specially by the kernel [8].” A system call handler is issued by the kernel when such an interrupt is executed. On linux there are two ways of implementing a system call, they are icall87/icall27 gates and INT 0x80 software interrupt, these are machine instructions that cause the processor to jump to a system call entry point. The EAX register contains a descriptor for the system call. Refer to “Designing Shell Code Demystified [8] for details about accessing system calls in an assembly. Depending on the value in the EAX register, other registers will be used accordingly. Section 6.3 demonstrates the development of shell code that spawns a shell. 7.3Example - SHELL SPAWNING SHELLCODEThe following example extracted from “Buffer Overflow and ShellCode [4].” The assembly code generated is for an Intel based Linux system. We start with knowledge of a program that possesses a buffer overflow vulnerability to exploit. The process is as follows:
The C code looks as shown: The next step is to extract the assembly code using a compiler. GDB is used in this case producing the assembly code show in the diagrams below. Refer to the referenced article for a full explanation of the assembly code. Dump of assembler code for function main: 0x8000130 0x8000131 0x8000133 0x8000136 0x800013d 0x8000144 0x8000146 0x8000149 0x800014a 0x800014d 0x800014e 0x8000153 0x8000156 0x8000158 0x8000159 End of assembler dump.
To compose the shellcode, a few intricacies are needed:
A condensed version of the shellcode will look like this: And this corresponding shell code can be used to initialize the buffer that will be used. Note that null bytes in the character buffer this will cause the string to be considered terminated when these bytes are processed, through strcpy for example, therefore the shellcode must be written such that there are no null opcodes. To test the shellcode the following construct can be used. Notice that we are modifying the return address with the address of the opcode buffer. When main returns the shellcode will be executed.
NIDS (Network Intrusion Detection System) can be used to identify shellcode on the wire using Signature databases and Protocol analysis methods. This targets the shellcode bytes and can easily expose the whole attack by pointing out the shellcode in the traffic. IPS (Intrusion Prevention System) identifies shellcode by running the code on a sandbox/virtualization in order to detect if the given code is malicious or not. This targets the shellcode actions, and can easily see that the shellcode is trying to perform actions which can are considered to be "malicious". 9ConclusionShellcode is a powerful mechanism for the exploitation of software vulnerabilities. Software engineers with a mind for security should be aware of how to develop them and understand how they can be injected through system vulnerabilities. Shellcode can be employed to automate software security tests, where the shellcode is written to expose and draw attention to security holes 10References1. Wikipedia - http://en.wikipedia.org/wiki/Shellcode 2. Foster James C. & M Stuart (March 2003) Sockets, Shellcode, Porting, & Coding: Reverse Engineering Exploits and Tool Coding for Security Professionals.
The Basics of ShellCoding. Retrieved November 26 from http://www.infosecwriters.com/text_resources/pdf/basics_of_shellcoding.pdf
Smashing The Stack For Fun And Profit. Retrieved November 26, 2007 from http://www.cs.wright.edu/~tkprasad/courses/cs781/alephOne.html
What every programmer should know about memory. Retrieved November 26 from http://lwn.net/Articles/253361/ 6. Wikipedia (November 2007). Virtual Memory. Retrieved November 26 from http://en.wikipedia.org/wiki/Virtual_memory 7. Wikipedia (November 2007) X86 Architecture. Retrieved November 26 from http://en.wikipedia.org/wiki/X86 8. Aleph One (November 08, 1996) Designing Shellcode Demystified. Retrieved November 26 from http://www.enderunix.org/docs/en/sc-en.txt Directory: education -> classes -> sjsu engr education -> 100 Village Primary School Music Classrooms education -> Between global market and international and regional cooperation education -> Biographies of Patriots of Color at The Battle of Bunker Hill John Ashbow Colony: Connecticut Age: 22 Race: Native American Status: Free Rank: Private Position: Rail Fence Unit: Putnam/Durkee education -> a geospatial Activity a buffer from the Storms education -> Guide to Preparedness education -> Social Sciences Teaching Unit Levels 2 6 Environmental Justice education -> I. Introduction 2 II. The Creation of Literate Environments education -> Harold j. Brody, md education -> October/November 2015 Teacher's Guide Table of Contents sjsu engr -> Professor: Sinn Richard project report (04/11/2006) On Routing Information Protocol (rip) 2 Download 39.05 Kb. Share with your friends: |