Ejemplo n.º 1
0
static void svc_process_smtp_id(char *hostname, int port, char *buf)
{
	char *id, *t;

	id = strstr(buf, "SMTP ") + 5;
	if((t = strchr(id, ';')) != NULL)
		*t = '\0';

	svc_display_type(hostname, port, "SMTP server", guess_version(id));
}
Ejemplo n.º 2
0
int do_extract(const char *output, int argc, char **argv)
{
    if(argc != 1)
    {
        printf("You need to specify exactly one input file to extract from.\n");
        return 3;
    }
    FILE *fout = NULL;
    if(output)
    {
        fout = fopen(output, "w");
        if(fout == NULL)
        {
            printf("Cannot open output file '%s'\n", output);
            return 4;
        }
    }
    /* read elf file */
    g_elf_buf = read_file(argv[0], g_elf_size);
    if(g_elf_buf == nullptr)
    {
        printf("Cannot open input file '%s'\n", argv[0]);
        return 1;
    }
    if(!elf_init())
    {
        printf("This is not a valid ELF file\n");
        return 1;
    }
    if(g_elf_symtab == nullptr)
    {
        printf("This ELF file does not have a symbol table\n");
        return 1;
    }
    /* look for symbol 'AreaInfo' */
    Elf32_Sym *sym_AreaInfo = elf_get_symbol_by_name("AreaInfo");
    if(sym_AreaInfo == nullptr)
    {
        printf("Cannot find symbol 'AreaInfo'\n");
        return 1;
    }
    printf("AreaInfo:\n");
    if(g_verbose)
    {
        printf("[%u bytes at address %#x in section %u (%s)]\n",
            (unsigned)sym_AreaInfo->st_size, (unsigned)sym_AreaInfo->st_value,
            (unsigned)sym_AreaInfo->st_shndx, elf_get_section_name(sym_AreaInfo->st_shndx));
    }
    /* guess version */
    int ver = guess_version(elf_get_symbol_ptr(sym_AreaInfo, sizeof(area_info_v1_t)));
    if(g_verbose)
        printf("[guessed version: %d]\n", ver);
    size_t sizeof_area_info = (ver == 1) ? sizeof(area_info_v1_t) : sizeof(area_info_v2_t);
    size_t sizeof_zone_info = (ver == 1) ? sizeof(zone_info_v1_t) : sizeof(zone_info_v2_t);
    /* sanity check AreaInfo */
    size_t area_count = sym_AreaInfo->st_size / sizeof_area_info;
    if(!g_unsafe && (sym_AreaInfo->st_size % sizeof_area_info) != 0)
    {
        printf("AreaInfo size (%u) is a not a multiple of area_info_t size (%zu).\n",
            (unsigned)sym_AreaInfo->st_size, sizeof_area_info);
        printf("Use unsafe option to override this check\n");
        return 1;
    }
    area_info_v1_t *AreaInfo_v1 = (area_info_v1_t *)elf_get_symbol_ptr(sym_AreaInfo,
        sym_AreaInfo->st_size);
    area_info_v2_t *AreaInfo_v2 = (area_info_v2_t *)AreaInfo_v1;
    if(AreaInfo_v1 == nullptr)
    {
        printf("Symbol does not point to a valid address\n");
        return 1;
    }
    for(size_t i = 0; i < area_count; i++)
    {
        uint32_t type;
        uint32_t *zoneinfo_ptr;
        uint32_t zonecount;
        uint32_t *name_ptr;

        if(ver == 1)
        {
            type = AreaInfo_v1[i].type;
            zoneinfo_ptr = &AreaInfo_v1[i].zoneinfo;
            zonecount = AreaInfo_v1[i].zonecount;
            name_ptr = &AreaInfo_v1[i].name;
        }
        else
        {
            type = AreaInfo_v2[i].type;
            zoneinfo_ptr = &AreaInfo_v2[i].zoneinfo;
            zonecount = AreaInfo_v2[i].zonecount;
            name_ptr = &AreaInfo_v2[i].name;
        }

        if(g_verbose)
        {
            printf("  [type=%u info=%#x count=%u name=%#x]\n", type, *zoneinfo_ptr,
                zonecount, *name_ptr);
        }
        /* translate name address */
        const char *name = (const char *)elf_reloc_addr32_ptr(name_ptr);
        if(name == nullptr || !elf_is_str_ptr_safe(name))
        {
            printf("  Entry name is not a string\n");
            continue;
        }
        /* skip reserved entries */
        if(*zoneinfo_ptr == 0)
        {
            printf("  %s\n", name);
            continue;
        }
        /* relocate the zoneinfo pointer */
        void *Zone = elf_reloc_addr32_ptr(zoneinfo_ptr);;
        if(Zone == nullptr)
        {
            printf("  %s\n", name);
            printf("  Zone info pointer is not valid\n");
            continue;
        }
        /* in safe mode, make sure the zone info pointer is a symbol */
        Elf32_Sym *zoneinfo_sym = elf_get_symbol_by_ptr((void *)Zone);
        const char *zoneinfo_sym_name = "<no symbol>";
        if(zoneinfo_sym)
            zoneinfo_sym_name = elf_get_symbol_name(zoneinfo_sym);
        printf("  %s (%s)\n", name, zoneinfo_sym_name);
        if(!g_unsafe && !zoneinfo_sym)
        {
            printf("  Zone info pointer does not correspond to any symbol.\n");
            printf("  Use unsafe option to override this check\n");
            continue;
        }
        /* if we have the symbol, make sure the claimed size match */
        if(!g_unsafe && zoneinfo_sym)
        {
            if(zoneinfo_sym->st_size != sizeof_zone_info * zonecount)
            {
                printf("  Zone info symbol size (%u) does not match expected size (%zu)\n",
                    (unsigned)zoneinfo_sym->st_size, sizeof_zone_info * zonecount);
                printf("  Use unsafe option to override this check\n");
                continue;
            }
        }
        /* sanity check */
        if(!elf_is_ptr_safe((void *)Zone, sizeof_zone_info * zonecount))
        {
            printf("  Zone info pointer is not valid\n");
            continue;
        }
        /* read zone */
        zone_info_v1_t *Zone_v1 = (zone_info_v1_t *)Zone;
        zone_info_v2_t *Zone_v2 = (zone_info_v2_t *)Zone;
        for(size_t j = 0; j < zonecount; j++)
        {
            uint32_t node, start, count, size;
            uint32_t *name_ptr;

            if(ver == 1)
            {
                node = Zone_v1[j].node;
                start = Zone_v1[j].start;
                count = Zone_v1[j].count;
                size = Zone_v1[j].size;
                name_ptr = &Zone_v1[j].name;
            }
            else
            {
                node = Zone_v2[j].node;
                start = Zone_v2[j].start;
                count = Zone_v2[j].count;
                size = Zone_v2[j].size;
                name_ptr = &Zone_v2[j].name;
            }

            if(g_verbose)
            {
                printf("    [node=%u start=%#x count=%u size=%u name=%#x]\n",
                    node, start, count, size, *name_ptr);
            }
            /* translate name address */
            const char *name = (const char *)elf_reloc_addr32_ptr(name_ptr);
            if(name == nullptr || !elf_is_str_ptr_safe(name))
            {
                printf("    Entry name is not a string\n");
                continue;
            }
            printf("    %s: node %03u, size %u\n", name, node, size);
            if(fout)
                fprintf(fout, "%u,%u,%s\n", node, size, name);
        }
    }
    if(fout)
        fclose(fout);
    /* success */
    return 0;
}
Ejemplo n.º 3
0
static void svc_process_reply(int fd, char *hostname, int port)
{
	FILE *sock;
	char buf[512], *t;

	if((sock = fdopen(fd, "r")) == NULL) {
		reply("Couldn't buffer socket: %s", strerror(errno));
		close(fd);

		return;
	}

	fgets(buf, 512, sock);
	if(!strncmp(buf, "HTTP/", 5)) {
		while(strncmp(buf, "Server: ", 8)) {
			if(!fgets(buf, 512, sock)) {
				svc_display_type(hostname, port, "Non-RFC compliant HTTP server", NULL);
				return;
			}
		}

		chop_crlf(buf);
		svc_display_type(hostname, port, "HTTP server", buf + 8);
	}
	else if(!strncmp(buf, "200 ", 4)) 
		svc_display_type(hostname, port, "NNTP server", NULL);

	else if(!strncmp(buf, "220 ", 4) || !strncmp(buf, "220-", 4)) {
		chop_crlf(buf);
		if(strstr(buf, " ESMTP ")) 
			svc_process_smtp_id(hostname, port, buf);
		else if(!strstr(buf, "ESMTP")) 
			svc_display_type(hostname, port, "FTP server", guess_version(buf + 4));
		else {
			write(fd, "HELP\n", 5);
			fgets(buf, 512, sock);

			chop_crlf(buf);

			if((t = strchr(buf, ' ')) == NULL)
				t = buf;
			else
				t++;

			svc_display_type(hostname, port, "SMTP server", t);
		}
	}
	else if(!strncmp(buf, "SSH-", 4)) 
		svc_process_ssh_id(hostname, port, buf);

	else if(!strncmp(buf, "* OK ", 5)) {
		chop_crlf(buf);
		svc_display_type(hostname, port, "IMAP server", guess_version(buf + 5));
	}

	else if(!strncmp(buf, "+OK ", 4)) {
		chop_crlf(buf);
		svc_display_type(hostname, port, "POP server", guess_version(buf + 4));
	}

	else if(!strncmp(buf, "0 , 0 :", 7) || !strncmp(buf, "0, 0 :", 6) ||
	        !strncmp(buf, "0,0 :", 5) || !strncmp(buf, "0,0:", 4)) 
		svc_display_type(hostname, port, "IDENT server", NULL);

	else if(!strncmp(buf, "lpd ", 4) || strstr(buf, "lpd: ") != NULL) 
		svc_display_type(hostname, port, "LPD server", NULL);

	else if(!strncmp(buf, "HEAD / HTTP/1.0", 15)) 
		svc_display_type(hostname, port, "ECHO server", NULL);

	else if(strstr(buf, "NOTICE AUTH"))
		svc_display_type(hostname, port, "IRC server", NULL);

	else
		svc_display_type(hostname, port, "Active server of unknown type", NULL);

	fclose(sock);
}