Questions about this topic? Sign up to ask in the talk tab.


From NetSec
Jump to: navigation, search
<hatter> so
<hatter> I guess I'll get started
<hatter> THe ELF format or Executable and Linkable format 
<hatter> is the binary executable format for Linux distributions
<hatter> This format is what you get after assembling and linking a binary
<hatter> Anything compiled usually ends up in this format (using make or gcc)
<hatter> and shared object libraries are also in this format
<hatter> Shared object libraries end in the .so extension and do not contain start or main function routines.
<hatter> If you're on linux, go ahead and make sure you have the following commands available :
<hatter> readelf objdump hexdump 
<hatter> if you do not have these, you can get them with your package manager usually by installing binutils
<hatter> at times you may need to install hexdump separately
<hatter> sorry guys irl happening to me
<hatter> Hold on
<hatter> ok so back
<hatter> this is the format of 
<hatter> an elf binary
<hatter> Each of these segments is organized
<hatter> The ELF header defines a few things, such as the number of bytes in its header, the number of bytes in the other headers, number of section headers, 
<hatter> entry point (location of _start in the binary)
<hatter> All of this is stored in hex
<hatter> We will be working primarily with 64 bit systems today
<hatter> I'm gonna just paste this shit
<hatter>     Diagram of a 64-bit ELF Header: 
<hatter>        0x0 - 0xf                   = "ELF Format Information"
<hatter>        Entry-point                 = 0x18 - 0x1f
<hatter>        Start of section headers    = 0x28 - 0x2f
<hatter>        Size of each section        = 0x3a - 0x3b
<hatter>        Number of section headers   = 0x3c - 0x3d
<hatter>     Diagram of a 64-bit section header: (length defined in ELF header) 
<hatter>          [0x0-0x3]     shstrtab offset for section name.
<hatter>                        shstrtab is defined between the end of
<hatter>                        .text and the beginning of the section
<hatter>                        headers
<hatter>          [0x4-0x7]     section type - 0 is null, 1 is progbits, 2 is symtab, 3 is strtab
<hatter>          [0x8-0xf]     section flags
<hatter>          [0x10-0x17]   section address
<hatter>          [0x18-0x1f]   section offset
<hatter>          [0x20-0x27]   section size
<hatter>          [0x28-0x2b]   Section Link
<hatter>          [0x2c-0x2f]   Section Info
<hatter>          [0x30-0x37]   Section Align
<hatter>          [0x38-0x3f]   Section EntSize
<hatter>     Diagram of a 64-bit symbol table entry: (0x18 bytes in length) 
<hatter>          [0x0-0x3]    Name offset from next string table
<hatter>          [0x4-0x5]    Bind
<hatter>          [0x6-0x7]    Ndx
<hatter>          [0x8-0xf]    Symbol pointer (Function pointer, data pointer, etc)
<hatter>          [0x10-0x17]  Null barrier
<hatter> Tell me when
<hatter> all that is done pasting
<hatter> because I will have
<hatter> no way of knowing 
<hatter> please.
<hatter> lol
<zzzzzZZZZzzz> h
* #CSIII :You must have a registered nick (+r) to talk on this channel (#CSIII)
<ackit> it is
<hatter> Ah thanks
<hatter> So
<hatter> I wrote kinda a hacky 64 bit assembly application
<hatter> but before we get to that
<hatter> check out readelf
<hatter> readelf -a $(which ls)
<hatter> you'll notice that it will automatically dump out
<hatter> section names
<hatter> linked libraries
<hatter> function names
<hatter> all that fun stuff
<hatter> it'll show the import and export tables for the application as well
<hatter> You can retrieve similar output in conjunction with a full disassembly of the application using 
<hatter> objdump -Ttd $(which ls)
<hatter> For those who don't know, we're using bash to analyze the "ls" executable
<hatter> you'll also notice that if you
<hatter> hexdump $(which ls)
<hatter> you'll be able to find the bytes referenced by readelf
<hatter> and the values
<hatter> at particular predictable offsets
<hatter> according to the format specification
<hatter> So, I wrote this rightly hacky assembly 
<hatter> This takes the entry point at runtime, migrates backwards until the characters ELF are found (the first 3 bytes of any ELF file)
<hatter> then uses that as the base pointer to parse the rest of the binary
<hatter> it migrates through to its symbol table 
<hatter> finds corresponding strings
<hatter> and prints all of the sections out
<hatter> also
<hatter> if it segfaults just ignore that, there is no number of sections check 
<hatter> so it is expected to segfault
<hatter> you could easily fix this by implementing a proper counter
* Tsunami has quit (Ping timeout)
<hatter> Any questions so far
<hatter> If there are questions you really should ask now
<hatter> I have about 15 minutes left and about 5-10 minutes of useful info after this that if you are having a hard time with 
<hatter> these basics
<hatter> you will not understand
<hatter> So 
<hatter> I'll take 5 for you guys to ask questions
<hatter> before proceeding
<ackit> all good so far, wish i was on a 64bit machine
<hatter> ackit: remind me later like this weekend maybe and I'll hack ya up a port 
<hatter> for 32 bit
<hatter> Now, essentially we have a method to pass the base pointer of a loaded ELF 
<hatter> which will parse out the functions within that ELF
<hatter> Now, that's great, but it doesn't get us much
<hatter> This does eventually have a practical application.
<hatter> Suppose for one moment that we do not know the version of the kernel running on a target system
<hatter> interrupts won't work in your shellcode bec ause you won't know 
<hatter> if the interrupt corresponds to the right functions or not
<hatter> so
<hatter> To get around this and stay compatible
<hatter> that's where code like this comes in
<hatter> create a one way hashing algorithm
<hatter> (I made one on the shellcode talk page)
<hatter> go ahead and hash each function name as you iterate through the loop
<hatter> then compare it to the hash of your desired function
<hatter> if you find that the hashes are equal in value, you can then find the offset to this function from its base pointer
<hatter> er
<hatter> the library's base pointer
<hatter> This will allow you to link to shared objects at *runtime*
<hatter> rather than at link or assemble time
<hatter> so your shellcode will be ensured compatibility 
<hatter> across a variety of builds and versions
<hatter> Everyone get that?
<m4> aye
<hatter> cool so
<hatter> when constructing shellcode
<foo> I'm still with ya
<hatter> you could easily integrate runtime linking
<hatter> and solve a whole slew of compatibility issues