bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug binutils/21720] New: Malicious ELF32 with invalid program table ent


From: jgj212 at gmail dot com
Subject: [Bug binutils/21720] New: Malicious ELF32 with invalid program table entry count can cause memory exhaustion
Date: Thu, 06 Jul 2017 07:42:19 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=21720

            Bug ID: 21720
           Summary: Malicious ELF32 with invalid program table entry count
                    can cause memory exhaustion
           Product: binutils
           Version: 2.29
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: jgj212 at gmail dot com
  Target Milestone: ---

Created attachment 10248
  --> https://sourceware.org/bugzilla/attachment.cgi?id=10248&action=edit
poc

version: objdump 2.29.51

-----------------------
$objdump -x $FILE
-----------------------


critical code in fcuntion 'elf_object_p' in file 'elfcode.h' :
```
      amt = i_ehdrp->e_phnum * sizeof (*i_phdr);   
      elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
```

'i_ehdrp->e_phnum' is initialized in fcuntion 'elf_object_p' as follow:
```
  i_ehdrp = elf_elfheader (abfd);
  elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
```

And elf32 header as follow: 
```
/* 32-bit ELF file header.  */

typedef struct {
  unsigned char e_ident[16];    /* ELF "magic number" */
  unsigned char e_type[2];    /* Identifies object file type */
  unsigned char e_machine[2];   /* Specifies required architecture */
  unsigned char e_version[4];   /* Identifies object file version */
  unsigned char e_entry[4];   /* Entry point virtual address */
  unsigned char e_phoff[4];   /* Program header table file offset */
  unsigned char e_shoff[4];   /* Section header table file offset */
  unsigned char e_flags[4];   /* Processor-specific flags */
  unsigned char e_ehsize[2];    /* ELF header size in bytes */
  unsigned char e_phentsize[2];   /* Program header table entry size */
  unsigned char e_phnum[2];   /* Program header table entry count */
  unsigned char e_shentsize[2];   /* Section header table entry size */
  unsigned char e_shnum[2];   /* Section header table entry count */
  unsigned char e_shstrndx[2];    /* Section header string table index */
} Elf32_External_Ehdr;

```

So normally, 'i_ehdrp->e_phnum' must smaller than 0xffff
But there is code in fcuntion 'elf_object_p' as follow:
```
      /* And program headers.  */
      if (i_ehdrp->e_phnum == PN_XNUM && i_shdr.sh_info != 0)
  {
    i_ehdrp->e_phnum = i_shdr.sh_info;
    if (i_ehdrp->e_phnum != i_shdr.sh_info)
      goto got_wrong_format_error;
  }
```

It means that if (i_ehdrp->e_phnum==0xffff) is true, i_ehdrp->e_phnum will be
computed user another way:
1)read the first section header
2)use the field named 'sh_info' of the fist section header to replace the 
i_ehdrp->e_phnum

Because sh_info of sectionHeader32 is a unsigned int from file, so
i_ehdrp->e_phnum can be controlled from 0 to 0xffffffff.

```
/* Section header */
typedef struct elf_internal_shdr {
  unsigned int  sh_name;    /* Section name, index in string tbl */
  unsigned int  sh_type;    /* Type of section */
  bfd_vma sh_flags;   /* Miscellaneous section attributes */
  bfd_vma sh_addr;    /* Section virtual addr at execution */
  file_ptr  sh_offset;    /* Section file offset */
  bfd_size_type sh_size;    /* Size of section in bytes */
  unsigned int  sh_link;    /* Index of another section */
  unsigned int  sh_info;    /* Additional section information */
  bfd_vma sh_addralign;   /* Section alignment */
  bfd_size_type sh_entsize;   /* Entry size if section holds table */

  /* The internal rep also has some cached info associated with it. */
  asection *  bfd_section;    /* Associated BFD section.  */
  unsigned char *contents;    /* Section contents.  */
} Elf_Internal_Shdr;

/* Section header */
typedef struct {
  unsigned char sh_name[4];   /* Section name, index in string tbl */
  unsigned char sh_type[4];   /* Type of section */
  unsigned char sh_flags[4];    /* Miscellaneous section attributes */
  unsigned char sh_addr[4];   /* Section virtual addr at execution */
  unsigned char sh_offset[4];   /* Section file offset */
  unsigned char sh_size[4];   /* Size of section in bytes */
  unsigned char sh_link[4];   /* Index of another section */
  unsigned char sh_info[4];   /* Additional section information */
  unsigned char sh_addralign[4];  /* Section alignment */
  unsigned char sh_entsize[4];    /* Entry size if section holds table */
} Elf32_External_Shdr;
```

'i_ehdrp->e_phnum' is a unsigned int, it can be controlled as 0xffffffff.
This could cause memory exhaustion to DOS.

Credit:The bug was discovered by ADLab of Venustech

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]