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