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 |
+----------+
|