herm1t LIVE!ng room - CVE-2012-0056 [entries|archive|friends|userinfo]
herm1t

[ website | twilight corner in the herm1t's cave ]
[ userinfo | ljr userinfo ]
[ archive | journal archive ]

CVE-2012-0056 [Apr. 5th, 2013|12:23 pm]
Previous Entry Add to Memories Tell A Friend Next Entry
[Tags|, , , , , ]

Вот такие штуки меня раздражают:
unsigned long objdump_address()
{
        FILE *command = popen("objdump -d /bin/su|grep '<exit@plt>' ........
        if (!command) {
                perror("[-] popen");
                return 0;
        }
        char result[32];
        fgets(result, 32, command);
        pclose(command);
        return strtoul(result, NULL, 16);
}
Можно заменить на вот такую жуть ;-)
uint64_t get_elf_symbol(char *filename)
{
	uint64_t ret = 0;
	int h = open(filename, 0);
	if (h < 0)
		return 0;
	int l = lseek(h, 0, 2);
	if (l <= sizeof(Elf64_Ehdr))
		goto _error_close;
	uint8_t *m = mmap(NULL, l, PROT_READ, MAP_SHARED, h, 0);
	if (m == MAP_FAILED)
		goto _error_close;
	if (*(uint64_t*)m != 0x00010102464c457f)
		goto _error_unmap;
	Elf64_Ehdr *ehdr = (Elf64_Ehdr*)m;
	if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(Elf64_Phdr)) > l)
		goto _error_unmap;
	if ((ehdr->e_shoff + ehdr->e_shnum * sizeof(Elf64_Shdr)) > l)
		goto _error_unmap;
	if (ehdr->e_shstrndx > ehdr->e_shnum)
		goto _error_unmap;
	Elf64_Shdr *shdr = (Elf64_Shdr*)(m + ehdr->e_shoff);
	char *strtab = (char*)(m + shdr[ehdr->e_shstrndx].sh_offset);
	Elf64_Rel *rel = NULL, *r;
	Elf64_Sym *sym = NULL;
	char *str = NULL, *plt = NULL;
	int i, plt_size = 0, rel_size = 0, rel_sz = 16;
	uint64_t plt_addr = 0;
	for (i = 0; i < ehdr->e_shnum; i++) {
		char *sname = shdr[i].sh_name + strtab;
		int stype = shdr[i].sh_type;
		if ((stype == SHT_REL || stype == SHT_RELA) && strstr(sname, ".plt")) {
			rel = (Elf64_Rel*)(m + shdr[i].sh_offset);
			rel_size = shdr[i].sh_size;
			if (shdr[i].sh_type == SHT_RELA)
				rel_sz = 24;
		}
		if (stype == SHT_DYNSYM) {
			sym = (Elf64_Sym*)(m + shdr[i].sh_offset);
			str = (char*)(m + shdr[shdr[i].sh_link].sh_offset);
		}
		if (!strcmp(sname, ".plt")) {
			plt = (char*)(m + shdr[i].sh_offset);
			plt_size = shdr[i].sh_size;
			plt_addr = shdr[i].sh_addr;
		}
	}
	if (rel == NULL || sym == NULL || str == NULL || plt == NULL)
		goto _error_unmap;
#define	C(x, y)	((char*)x - (char*)y)
	for (r = rel; C(r, rel) < rel_size; r = (Elf64_Rel*)(C(r, 0) + rel_sz))
		if (! strcmp("exit", sym[ELF64_R_SYM(r->r_info)].st_name + str))
			for (i = 16; i < plt_size; i += 16)
				if (*((uint32_t*)(plt + i + 7)) == C(r, rel) / rel_sz) {
					ret = i + plt_addr;
					goto _error_unmap;
				}
#undef	C
_error_unmap:
	munmap(m, l);
_error_close:
	close(h);
	return ret;
}
И там еще есть неприятность с блокирующим recv, но это уже совсем другая история.
LinkLeave a comment