SEConference 2013 - Maciej Kotowicz / @maciekkotowicz
Daive Aitel:
Occasionally, or "all the time", depending on how often you hack and what you hack, you'll run into a system or situation where you can't upload and execute your kernel exploit! Selinux? Non-exec mounts? This is very frustrating! You pound the table, gnash your teeth, and curse in the little Mandarin you know.
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size */
Elf32_Half e_phnum; /* Program header table entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;
[mak@asdf pyload]$ readelf -h foo-64 ELF Header: Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - GNU ABI Version: 0 Type: EXEC (Executable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x400e30 Start of program headers: 64 (bytes into file) Start of section headers: 768280 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 5 Size of section headers: 64 (bytes) Number of section headers: 31 Section header string table index: 28
typedef struct
{
Elf32_Word p_type; /* Segment type */
Elf32_Off p_offset; /* Segment file offset */
Elf32_Addr p_vaddr; /* Segment virtual address */
Elf32_Addr p_paddr; /* Segment physical address */
Elf32_Word p_filesz; /* Segment size in file */
Elf32_Word p_memsz; /* Segment size in memory */
Elf32_Word p_flags; /* Segment flags */
Elf32_Word p_align; /* Segment alignment */
} Elf32_Phdr;
#define PT_NULL 0 /* Program header table entry unused */
#define PT_LOAD 1 /* Loadable program segment */
#define PT_DYNAMIC 2 /* Dynamic linking information */
#define PT_INTERP 3 /* Program interpreter */
#define PT_NOTE 4 /* Auxiliary information */
#define PT_SHLIB 5 /* Reserved */
#define PT_PHDR 6 /* Entry for header table itself */
#define PT_TLS 7 /* Thread-local storage segment */
#define PT_NUM 8 /* Number of defined types */
#define PT_LOOS 0x60000000 /* Start of OS-specific */
#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
[mak@asdf pyload]$ readelf -l foo-64 Elf file type is EXEC (Executable file) Entry point 0x400e30 There are 5 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x00000000000b9ee8 0x00000000000b9ee8 R E 200000 LOAD 0x00000000000ba000 0x00000000006ba000 0x00000000006ba000 0x0000000000001790 0x0000000000003f98 RW 200000 NOTE 0x0000000000000158 0x0000000000400158 0x0000000000400158 0x0000000000000044 0x0000000000000044 R 4 TLS 0x00000000000ba000 0x00000000006ba000 0x00000000006ba000 0x0000000000000020 0x0000000000000050 R 8 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 8
[mak@asdf pyload]$ readelf -l /usr/bin/id Elf file type is EXEC (Executable file) Entry point 0x40204c There are 9 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040 0x00000000000001f8 0x00000000000001f8 R E 8 INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238 0x000000000000001c 0x000000000000001c R 1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x0000000000006e3c 0x0000000000006e3c R E 200000 LOAD 0x0000000000007e08 0x0000000000607e08 0x0000000000607e08 0x0000000000000498 0x00000000000006c0 RW 200000 DYNAMIC 0x0000000000007e20 0x0000000000607e20 0x0000000000607e20 0x00000000000001d0 0x00000000000001d0 RW 8 NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254 0x0000000000000044 0x0000000000000044 R 4 GNU_EH_FRAME 0x00000000000061cc 0x00000000004061cc 0x00000000004061cc 0x000000000000026c 0x000000000000026c R 4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 8 GNU_RELRO 0x0000000000007e08 0x0000000000607e08 0x0000000000607e08 0x00000000000001f8 0x00000000000001f8 R 1
RTFS - /usr/include/elf.h
ABI V - www.sco.com/developers/gabi/
the_grugq
http://grugq.github.io/docs/ul_exec.txtPluf & Ripe
phrack-0x3f-0x0b
[ Autoloadable and Autoexecutable Object ] .------------------------------------------------ | | [ Static Executable File (1) ] | .--------------------------------. | | | | | .----------------------. | | | | ELF Header )---------|----|--. | | |----------------------| | | Shellcode Elf loader (3) | | | Program Header Table | | | hdr->e_ident[9] | | | | | | | | | + PT_LOAD0 | | | | | | + PT_LOAD1 | | | | | | ... | | | | | | ... | | | | | | + PT_STACK )---------|----|--|--. | | | | | | | Stack Context (2) | | |----------------------| | | | | | | Sections (code/data) | | | | | '--> |----------------------| <--' | | | .--> |######################| <-----' | | | |## SHELLCODE LOADER ##| | | P | |######################| | | A | | | | | G | | ....... | | | E | | ....... | | | | | | | | | |######################| <--------' | | |#### STACK CONTEXT ###| | | |######################| | '--> '----------------------' | '-----------------
ELF - AUXV
typedef struct
{
uint32_t a_type; /* Entry type */
union
{
uint32_t a_val; /* Integer value */
/* We use to have pointer elements added here. We cannot do that,
though, since it does not work when using 32-bit definitions
on 64-bit platforms and vice versa. */
} a_un;
} Elf32_auxv_t;
.a_type: AT_SYSINFO_EHDR | .a_val: 0x7ffff7ffa000
.a_type: AT_HWCAP | .a_val: 0xbfebfbff
.a_type: AT_PAGESZ | .a_val: 0x1000
.a_type: AT_CLKTCK | .a_val: 0x64
.a_type: AT_PHDR | .a_val: 0x400040
.a_type: AT_PHENT | .a_val: 0x38
.a_type: AT_PHNUM | .a_val: 0x9
.a_type: AT_BASE | .a_val: 0x7ffff7ddb000
.a_type: AT_FLAGS | .a_val: 0x0
.a_type: AT_ENTRY | .a_val: 0x40204c
.a_type: AT_UID | .a_val: 0x3e8
.a_type: AT_EUID | .a_val: 0x3e8
.a_type: AT_GID | .a_val: 0x3e8
.a_type: AT_EGID | .a_val: 0x3e8
.a_type: AT_SECURE | .a_val: 0x0
.a_type: AT_RANDOM | .a_val: 0x7fffffffebf9
.a_type: AT_EXECFN | .a_val: 0x7fffffffefec
.a_type: AT_PLATFORM | .a_val: 0x7fffffffec09
import sys,os
from ctypes import *
libc = CDLL("libc.so.6")
CFUNC = CFUNCTYPE(c_int,c_void_p)
MYSELF = os.path.abspath(os.path.expanduser(__file__))
sys.path.append(os.path.dirname(MYSELF))
from builder import Builder
b = Builder('./foo'+sys.argv[1],['a','b','c'],["PATH=/tmp/",'EVIL=dupa'])
payload = b.payload()
lpayload = (len(payload) + 0x1000) & ~(0x1000-1)
libc.mmap.restype = c_void_p
addr = libc.mmap(0,lpayload,7,0x22,0,0)
addr = c_void_p(addr)
libc.memcpy(addr,payload,len(payload))
cfun = cast(addr,CFUNC)
cfun(addr)
exit()
+------------------------+ | | | SHELLCODE x86/x64 | | | +------------------------+ | +---------------+ | | | chunk0 type | | | +---------------+ | | | |<--+ | | | chunk0 data | | | | | |chunk0| | +---------------+ | | | chunk1 type | | | +---------------+ | | | + | | | | + | | | | | | | | + | | | | + | | | | | | | | + | | | | + +| | | |+--------------+ | | | chunkN type | | | +---------------+ | | | |<--+ | | | chunkN data | | | | | |chunkN| | +---------------+ | +-----------------------+ |
LOAD_TYPE = 1 STACK_TYPE = 2 ENTRY_TYPE = 3 +----------+ +---------+ |STACK_TYPE| |LOAD_TYPE| +----------+ +---------+ |STACK_PROT| |LOAD_PROT| +----------+ +---------+ |ARGV_SIZE | +----------+ | SIZE | +----------+ |ENTRY_TYPE| +---------+ |ENVP_SIZE | +----------+ | VADDR | +----------+ | E_ENTRY | +---------+ | OFFSETS | +----------+ | | +----------+ | DATA | | AUXVEC | | | | | | | +----------+ +---------+ | | | ARGV | | + | | ENVP | +----------+ |