Week 2: Buffer Overflow Part 1
Outline Buffer overflow introduction – continued Understanding x86 executables X86 assembly – overview Calling conventions Buffer overflow techniques Change variables by overflowing them Change the control flow by overflowing return address on the stack Ret2libc (0x6b0) Return oriented programming (ROP)
Buffer Overflow Example
x86 Assembly Registers Memory and addressing modes Instructions Static data regions using .DATA directives Memory addressing modes Size directives (BYTE, WORD, DWORD) Instructions Calling convention
x86 Registers
Additional Registers QQ
x86 FLAGS Registers
x86 FLAGS Registers
Bit and Byte Ordering
Intel Assembly Each instruction is represented by Label: mnemonic argument1, argument2, argument3 Where label presents the line A mnemonic is a reserved name for a class of instruction opcodes which have the same function. The operands argument1, argument2, and argument3 are optional. There may be from zero to three operands, depending on the instruction
Memory Modes
Addressing The processors use byte addressing Intel processors support segmented addressing Each address is specified by a segment register and byte address within the segment
Basic Program Execution Registers General purpose registers There are eight registers (note that they are not quite general purpose as some instructions assume certain registers) Segment registers They define up to six segment selectors EIP register – Effective instruction pointer EFLAGS – Program status and control register
General Purpose and Segment Registers
General Purpose Registers EAX — Accumulator for operands and results data EBX — Pointer to data in the DS segment ECX — Counter for string and loop operations EDX — I/O pointer ESI — Pointer to data in the segment pointed to by the DS register; source pointer for string operations EDI — Pointer to data (or destination) in the segment pointed to by the ES register; destination pointer for string operations ESP — Stack pointer (in the SS segment) EBP — Pointer to data on the stack (in the SS segment)
Alternative General Purpose Register Names
Registers in IA-64
Segment Registers
Operand Addressing Immediate addressing Register addressing Maximum value allowed varies among instructions and it can be 8-bit, 16-bit, or 32-bit Register addressing Register addressing depends on the mode (IA-32 or IA-64)
Register Addressing
Memory Operand Memory operand is specified by a segment and offset
Offset Displacement - An 8-, 16-, or 32-bit value. Base - The value in a general-purpose register. Index — The value in a general-purpose register. Scale factor — A value of 2, 4, or 8 that is multiplied by the index value.
Effective Address
Effective Address Common combinations Displacement Base Base + displacement (Index * scale) + displacement Base + index + displacement Base + (Index * scale) + displacement
Addressing Mode Encoding
Fundamental Data Types
Example
Note Note that a number can be written and saved in different ways For example, number 1234 can be represented as “1234” (as a string) number 1234 can be represented as a two’s complement integer
Number 1234 in Memory
Pointer Data Types Near pointer Far pointer
128-bit SIMD Data Types
BCD Integers Intel also supports BCD integers, where each digit (0-9) is represented by 4 bits
Floating Point Numbers
General Purpose Instructions Data transfer Instructions
Data Transfer Instructions
Data Transfer Instructions
Binary Arithmetic Instructions
Decimal Arithmetic Instructions
Logic Instructions
Shift and Rotate Instructions
Bit and Byte Instructions
Bit and Byte Instructions
Control Transfer Instructions
String Instructions
I/O Instructions These instructions move data between the processor’s I/O ports and a register or memory
Enter and Leave Instructions These instructions provide machine-language support for procedure calls in block structured languages
Segment Register Instructions The segment register instructions allow far pointers (segment addresses) to be loaded into the segment registers
Procedure Call Types The processor supports procedure calls in the following two different ways: CALL and RET instructions. ENTER and LEAVE instructions, in conjunction with the CALL and RET instructions
Stack
Calling Procedures using CALL and RET Near call (within the current code segment) Near return
Far Call and Far Return Far Call Far Return
Stack During Call and Return
Stack for Calling and Called Procedure
Parameter Passing Passing parameters through the general-purpose registers Can pass up to six parameters by copying the parameters to the general-purpose registers Passing parameters on the stack Stack can be used to pass a large number of parameters and also return a large number of values Passing parameters in an argument list Place the parameters in an argument list A pointer to the argument list can then be passed to the called procedure
Saving Procedure State Information The processor does not save general purpose registers A calling procedure should explicitly save the values in any of the general-purpose registers that it will need when it resumes execution after a return One can use PUSHA and POPA to save and restore all the general purpose registers (except ESP)
Calls to Other Privilege Levels
Procedure Calls for Block-Structured Languages ENTER and LEAVE instructions automatically create and release, respectively, stack frames for called procedures The ENTER instruction creates a stack frame compatible with the scope rules typically used in block-structured languages The LEAVE instruction, which does not have any operands, reverses the action of the previous ENTER instruction
Enter Instruction
IA-32 and IA-64 Instruction Format
Examples of Instruction Formats
ADD Instructions
Add Instructions
ADD Instruction Description
SCAS/SCASB/SCASW/SCASD – Scan String
Compilation and Linking
Linking
File Format - ELF
Executable and Linking Format .init - Startup .text - String .fini - Shutdown .rodata - Read Only .data - Initialized Data .tdata - Initialized Thread Data .tbss - Uninitialized Thread Data .ctors - Constructors .dtors - Destructors .got - Global Offset Table .bss - Uninitialized Data See http://linux.die.net/man/5/elf for further information about the sections
Memory Layout (LINUX)
Stack Organization
Stack Organization
Changing Local Variables by Overflowing the buffer After all the “hard” work, we are ready to deploy the exploitation Local variable auth_flag is at ebp-12 and the buffer is at ebp-28 We can use Perl to generate the string we need
Can we now call I_am_the_King function using buffer_overflow?
Can we now call I_am_the_King function using buffer_overflow? How can we do it? We just need to find out the address of the function? In gdb, we can simply use x/x I_am_the_King We can also find the address using objdump We then need to overflow the return address
Can we now call I_am_the_King function using buffer_overflow? How can we do it? We just need to find out the address of the function? In gdb, we can simply use x/x I_am_the_King We can also find the address using objdump We then need to overflow the return address Before we do it, think about what happens after printing out the message “I am on the way to become the King of Penetration Testing.”
Can we now call I_am_the_King function using buffer_overflow? How can we do it? We just need to find out the address of the function? In gdb, we can simply use x/x I_am_the_King We can also find the address using objdump We then need to overflow the return address Before we do it, think about what happens after printing out the message “I am on the way to become the King of Penetration Testing.” Why? Can we fix the problem?
Calling a Function with a Parameter by Buffer Overflow How about a function with a parameter? 0 1 2 3 4 5 6 7 8 9 10 11 12
Calling a function with a parameter? How about a function with a parameter? 0 1 2 3 4 5 6 7 8 9 10 11 12
Comments Please note the instructions used and generated are system and compiler dependent The instructions depend on the libraries available in the system The compiler can apply optimization techniques, which can change the order of variables allocated Some of the local variables can even be optimized away (such as using registers only, which will be much faster)
Ret2LibC See 0x6b0 in the Art textbook Also 0x331 Note that we can overflow the return address, causing the program to call other functions in the program Note that we can also cause the program to jump into any address that is executable Can we also call other functions (the ones in libraries and so on)?
Ret2LibC Note that we can overflow the return address, causing the program to call other functions in the program Note that we can also cause the program to jump into any address that is executable Can we also call other functions (the ones in libraries and so on)? Yes. A common way is to return to libc (the most commonly used C/C++ library functions) In particular, we can try to call the system function, which can create a shell
Ret2LibC System function System can be used to run programs For example, system(“/bin/sh ”) will create a shell How can we do it?
Ret2LibC System function System can be used to run programs System(“/bin/sh ”) will create a shell How can we do it?
Ret2LibC from auth_overflow example
Return Oriented Programming
ROP
ROP
ROP
CVE-2013-3893 Internet Explorer Zero Day
CVE-2013-3893 Internet Explorer Zero Day Q
Summary By exploiting a buffer overflow vulnerability, we can always overflow the return address Therefore we can always change the control flow We can call other functions in the executable file We can jump to other instructions in the executable file We can call functions in libraries (such as return to libc) We can also change the values of local variables allocated higher than the buffer on the stack If the stack is executable, we can also inject (malicious) instructions on the stack We will cover it next time (Sections 0x330, 0x510, 0x511, 0x520, and 0x530)
Before Class Discussion
Before Class Discussion 2015 Chrysler 200 - Next Generation Midsize Sedan.
Before Class Discussion
Before Class Discussion
Citations https://en.wikipedia.org/wiki/FLAGS_register