TUCoPS :: Unix :: General :: jidentd.txt

Jidentd and other identd daemons contain several bugs.


[ http://www.rootshell.com/ ]

Date:         Thu, 10 Sep 1998 20:23:42 -0500
From:         Mitchell Blank Jr <mitch@EXECPC.COM>
Subject:      security problems with jidentd

On the Linux Security Audit Project mailing list there has been some
discussion about anecdotal evidence of machines being exploited
via various identd daemons.  Chris Evans looked over some of the
commonly used identd daemons and found a likely remote-exploitable
buffer overrun in jidentd 1.0 by Josh Lehan.  I've looked over the code
and found several other potential problems - some serious, some not.
Included is a patch for all the problems Chris and I spotted.  Aleph
requested that I share them with bugtraq.  Sorry kiddies, no exploits
included.

Jidentd is linux-specific.  I do not know of any distributions that
include jidentd, however there is a copy in the contrib area of
RedHat's FTP site.  It is apparently popular among the irc crowd due
to its ability to provide fake responses to queries.  It is believed
that it often is run as root.  When run in standalone mode it provides
no mechanism to drop privilege after binding its socket.

The code is, frankly, pretty messy.  I can not be sure that I have fixed
every problem or have not introduced new ones.  I have given it a moderate
amount of testing on one machine and it seems to work, but I may very well
may have broken something.

I would recommend not using jidentd if possible.  If you must run it
consider applying this patch.  Also, run it from inetd and NOT AS ROOT!

No warranty provided.

-Mitch

Bug fixes in this patch:
  * serious overrun in Dsyslog function (as pointed out by Chris Evans)
    Impact: almost certainly a remote-exploitable overrun - easy remote shell
            Exploit attempts are now logged.

  * serious overruns in the parsing of /etc/jidentd.hidden file (again,
    Chris Evans noticed this one)
    Impact: any user that can edit jidentd.hidden can gain the privilege of
            the uid jidentd is running as.  This file is commonly left writable
            by users who run irc.

  * many other overruns, some probably exploitable.  I didn't determine
    the exploitability of each one, I just tried to fix them all.  I also
    changed a lot of coded-in buffer lengths to use the 'sizeof' operator
    to avoid mistakes.  Again, no guarantee I got them all the overruns.

  * parser was broken subtlety due to misused memmove() call.  This might
    have lead to corrupted memory.
    Impact: possible exploit.  probably just incorrect responses in the case
            of multiple queries sent at once (which nothing uses)

  * for each request up to three files are opened, but never closed.  If
    multiple requests are sent, the remote side can use file descriptors
    until the process hits its rlimit
    Impact: denial of service

  * logging code made assumptions about endian-ness and 32-bit-ness
    Impact: might log incorrect IP address for connecting machine when
            run on non-Intel architectures

  * socket was opened without setsockopt(SO_REUSEADDR)
    Impact: daemon would not start if there were old connections in TIME_WAIT
            Minor denial-of-service

  * SIGCHLD handler wasn't entirely robust
    Impact: under strange circumstances, daemon might have left zombie
            processes

  * in debugging mode, optarg was passed to printf without checking if
    it were NULL.
    Impact: daemon could mysteriously dump core if run in debugging mode.
            libc usually saves you here

  * select on listening socket didn't handle some cases where it might
    return prematurely.
    Impact: daemon would mysteriously die if backgrounded or traced.

  * accept was performed after fork
    Impact: race condition on accept which could conceivably cause multiple
            children to be spawned for one connection.  No clear security
            threat.

  * the documentation lists an erroneous default location for the "hidefile".
    Impact: daemon could be misconfigured, leaving users the impression that
            their identity was being hidden when in fact it was not.

begin 664 jidentd.patch.gz
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
E93A(KACD("7H"9QZD%D7L`>A682F'H182V<O`@`&=/`+#U@`````
`
end

------------------------------------------------------------------------

From:         Scott Fuhrman <scru@TECHNOTRONIC.COM>
Subject:      Re: security problems with jidentd

I believe this has been discussed before, but it wasnt given much attention

At 08:23 PM 9/10/98 -0500, you wrote:
>Jidentd is linux-specific.  I do not know of any distributions that
>include jidentd, however there is a copy in the contrib area of
>RedHat's FTP site.  It is apparently popular among the irc crowd due
>to its ability to provide fake responses to queries.  It is believed
>that it often is run as root.  When run in standalone mode it provides
>no mechanism to drop privilege after binding its socket.

Another identd popular amongst irc patrons that falls into this category is
cidentd.  It offers the ability to fake responses via a user defined string,
and the function that reads this string is vulnerable to buffer overflows. 
To my knowledge the program is not distributed with any Linux distro, but it
was(might be now) once recommended in the ircii-pana(BitchX) documentation.
There is also a non public exploit floating around for cidentd1.2b(I
believe) which will drop a local user into a root shell.  The program is
available somewhere on sunsites labyrinth of an ftp server.


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH