Maciej Kotowicz
- Principal Malware Researcher @ CERT.pl
- DragonSector CTF
- RE/Exploit dev
- Automatization / Formal methods
- @maciekkotowicz
Maciej Kotowicz
Maciej Kotowicz
/* Type for a 16-bit quantity. */ typedef uint16_t Elf32_Half; typedef uint16_t Elf64_Half; /* Types for signed and unsigned 32-bit quantities. */ typedef uint32_t Elf32_Word; typedef int32_t Elf32_Sword; typedef uint32_t Elf64_Word; typedef int32_t Elf64_Sword; /* Types for signed and unsigned 64-bit quantities. */ typedef uint64_t Elf32_Xword; typedef int64_t Elf32_Sxword; typedef uint64_t Elf64_Xword; typedef int64_t Elf64_Sxword;
/* Type of addresses. */ typedef uint32_t Elf32_Addr; typedef uint64_t Elf64_Addr; /* Type of file offsets. */ typedef uint32_t Elf32_Off; typedef uint64_t Elf64_Off;
#define EI_NIDENT (16) 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;
#define EI_NIDENT (16) typedef struct { unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ Elf64_Half e_type; /* Object file type */ Elf64_Half e_machine; /* Architecture */ Elf64_Word e_version; /* Object file version */ Elf64_Addr e_entry; /* Entry point virtual address */ Elf64_Off e_phoff; /* Program header table file offset */ Elf64_Off e_shoff; /* Section header table file offset */ Elf64_Word e_flags; /* Processor-specific flags */ Elf64_Half e_ehsize; /* ELF header size in bytes */ Elf64_Half e_phentsize; /* Program header table entry size */ Elf64_Half e_phnum; /* Program header table entry count */ Elf64_Half e_shentsize; /* Section header table entry size */ Elf64_Half e_shnum; /* Section header table entry count */ Elf64_Half e_shstrndx; /* Section header string table index */ } Elf64_Ehdr;
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;
typedef struct { Elf64_Word p_type; /* Segment type */ Elf64_Word p_flags; /* Segment flags */ Elf64_Off p_offset; /* Segment file offset */ Elf64_Addr p_vaddr; /* Segment virtual address */ Elf64_Addr p_paddr; /* Segment physical address */ Elf64_Xword p_filesz; /* Segment size in file */ Elf64_Xword p_memsz; /* Segment size in memory */ Elf64_Xword p_align; /* Segment alignment */ } Elf64_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
typedef struct { Elf32_Word sh_name; /* Section name (string tbl index) */ Elf32_Word sh_type; /* Section type */ Elf32_Word sh_flags; /* Section flags */ Elf32_Addr sh_addr; /* Section virtual addr at execution */ Elf32_Off sh_offset; /* Section file offset */ Elf32_Word sh_size; /* Section size in bytes */ Elf32_Word sh_link; /* Link to another section */ Elf32_Word sh_info; /* Additional section information */ Elf32_Word sh_addralign; /* Section alignment */ Elf32_Word sh_entsize; /* Entry size if section holds table */ } Elf32_Shdr;
typedef struct { Elf64_Word sh_name; /* Section name (string tbl index) */ Elf64_Word sh_type; /* Section type */ Elf64_Xword sh_flags; /* Section flags */ Elf64_Addr sh_addr; /* Section virtual addr at execution */ Elf64_Off sh_offset; /* Section file offset */ Elf64_Xword sh_size; /* Section size in bytes */ Elf64_Word sh_link; /* Link to another section */ Elf64_Word sh_info; /* Additional section information */ Elf64_Xword sh_addralign; /* Section alignment */ Elf64_Xword sh_entsize; /* Entry size if section holds table */ } Elf64_Shdr;
#define SHT_NULL 0 /* Section header table entry unused */ #define SHT_PROGBITS 1 /* Program data */ #define SHT_SYMTAB 2 /* Symbol table */ #define SHT_STRTAB 3 /* String table */ #define SHT_RELA 4 /* Relocation entries with addends */ #define SHT_HASH 5 /* Symbol hash table */ #define SHT_DYNAMIC 6 /* Dynamic linking information */ #define SHT_NOTE 7 /* Notes */ #define SHT_NOBITS 8 /* Program space with no data (bss) */ #define SHT_REL 9 /* Relocation entries, no addends */ #define SHT_SHLIB 10 /* Reserved */ #define SHT_DYNSYM 11 /* Dynamic linker symbol table */ #define SHT_INIT_ARRAY 14 /* Array of constructors */ #define SHT_FINI_ARRAY 15 /* Array of destructors */ #define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ ... #define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
typedef struct { Elf32_Sword d_tag; /* Dynamic entry type */ union { Elf32_Word d_val; /* Integer value */ Elf32_Addr d_ptr; /* Address value */ } d_un; } Elf32_Dyn;
typedef struct { Elf64_Sxword d_tag; /* Dynamic entry type */ union { Elf64_Xword d_val; /* Integer value */ Elf64_Addr d_ptr; /* Address value */ } d_un; } Elf64_Dyn;
/* Legal values for d_tag (dynamic entry type). */ #define DT_NULL 0 /* Marks end of dynamic section */ #define DT_NEEDED 1 /* Name of needed library */ #define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ #define DT_PLTGOT 3 /* Processor defined value */ #define DT_HASH 4 /* Address of symbol hash table */ #define DT_STRTAB 5 /* Address of string table */ #define DT_SYMTAB 6 /* Address of symbol table */ ... #define DT_SONAME 14 /* Name of shared object */ #define DT_RPATH 15 /* Library search path (deprecated) */ ... #define DT_PLTREL 20 /* Type of reloc in PLT */ #define DT_DEBUG 21 /* For debugging; unspecified */ #define DT_TEXTREL 22 /* Reloc might modify .text */ #define DT_JMPREL 23 /* Address of PLT relocs */ ...
typedef struct { Elf32_Word st_name; /* Symbol name (string tbl index) */ Elf32_Addr st_value; /* Symbol value */ Elf32_Word st_size; /* Symbol size */ unsigned char st_info; /* Symbol type and binding */ unsigned char st_other; /* Symbol visibility */ Elf32_Section st_shndx; /* Section index */ } Elf32_Sym;
typedef struct { Elf64_Word st_name; /* Symbol name (string tbl index) */ unsigned char st_info; /* Symbol type and binding */ unsigned char st_other; /* Symbol visibility */ Elf64_Section st_shndx; /* Section index */ Elf64_Addr st_value; /* Symbol value */ Elf64_Xword st_size; /* Symbol size */ } Elf64_Sym;
mak@phun> readelf -d x
Dynamic section at offset 0xbb340 contains 29 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libgmp.so.10]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libffi.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
[..]
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x6bb568
0x0000000000000002 (PLTRELSZ) 2760 (bytes)
[..]
0x0000000000000000 (NULL) 0x0
Dynamic section at offset 0xbb340 contains 29 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libgmp.so.10]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libffi.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
[..]
import sys, elf from struct import unpack, pack e = elf.Elf(sys.argv[1]) for p in e.phdrs: if p.type == 'PT_DYNAMIC': break dyva = p.p_vaddr strtab = e.dynamic['DT_STRTAB'] dstrtab_off = dyva + 0x10 * (e.dynamic.off - 1) strtab_d = e.read(strtab,0x100) x = e.dynamic['DT_DEBUG'] ddebug = dyva + 0x10 * ( e.dynamic.off - 1) print 'your new lib', strtab_d[3:].split("\x00")[0] e.write(ddebug, pack('QQ', 1, 3)) e.save(sys.argv[1] + '.l.bin')
$ cat >>a.c<<\EOT int main(int a, char **b) { printf(b[1]); } EOT $ gcc -O0 -o a a.c $ python2 rename.py a $ chmod +x ./a.r.bin $ objdump -d ./a.r.bin 00000000004004e6 <main>: 4004e6: 55 push %rbp ... 400508: e8 b3 fe ff ff callq 4003c0 <printf@plt> 40050d: b8 00 00 00 00 mov $0x0,%eax 400512: c9 leaveq 400513: c3 retq $ ./a.r.bin id uid=1000(mak) gid=1000(mak) groups=1000(mak),78(kvm),92(audio),150(wireshark)
import sys, elf from struct import unpack, pac e = elf.Elf(sys.argv[1]) for p in e.phdrs: if p.type == 'PT_DYNAMIC': break dyva = p.p_vaddr strtab = e.dynamic['DT_STRTAB'] dstrtab_off = dyva + 0x10 * (e.dynamic.off-1) strtab_d = e.read(strtab, 0x100).replace('printf', 'system') e.insert_phdr(p_type = 1, p_flags = 6, p_vaddr = 0x500000, data = strtab_d ) e.write(dstrtab_off + 8, pack('Q', 0x500000)) e.save(sys.argv[1] + '.r.bin')
This is ridiculous but only @vector_35 's binary ninja can read ELF's both IDA and @radareorg failed at my binary. pic.twitter.com/RLHtbB5UCa
— mak (@maciekkotowicz) September 1, 2016
void good() { puts("good");} int main() { good(); }
$ readelf -e a1
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
...
[14] .text PROGBITS 00000000004003f0 000003f0
0000000000000192 0000000000000000 AX 0 0 16
...
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
...
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000006ec 0x00000000000006ec R E 200000
[BITS 64] jmp a b: pop rsi push rdx mov rdx,4 xor rax,rax inc rax mov rdi,rax syscall pop rdx push 0x4003f0 ret a: call b db "bad",0xa
nasm x.asm -o x.bin dd if=x.bin of=a1 seek=$((0x880)) oflag=seek_bytes conv=notrunc echo -ne "\x80\x08" | dd of=a1 seek=24 oflag=seek_bytes conv=notrunc
$ cat ~/sbs/web.py | grep dual-elf dual-elf : sbs{98b18715f67b4091cbb85fda71f18cc3fe3a4009} tasks_id = {1:'coq',2:'small-elf',3:'dual-elf',4:'hask-pwn',5:'green-stego'} $ cat ~/sbs/tasks/3 <br> Get the flag!: <a href="/static/3">file
$ cat ~/sbs/web.py | grep dual-elf dual-elf : sbs{98b18715f67b4091cbb85fda71f18cc3fe3a4009} tasks_id = {1:'coq',2:'small-elf',3:'dual-elf',4:'hask-pwn',5:'green-stego'} $ cat ~/sbs/tasks/3 <br> Get the flag!: <a href="/static/3">file
Just a simple crackme. File: [shiz]({{resource("re200")}})
http://bit.do/PWN-Praktyczna-inzynieria-wsteczna
mak mak@cert.pl
mak mak@lokalhost.pl
mak @maciekkotowicz