[16909] in bugtraq
Format strings: bug #2: LPRng
daemon@ATHENA.MIT.EDU (Chris Evans)
Tue Sep 26 01:58:49 2000
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Message-Id: <Pine.LNX.4.21.0009252359560.25714-100000@ferret.lmh.ox.ac.uk>
Date: Tue, 26 Sep 2000 00:57:43 +0100
Reply-To: Chris Evans <chris@SCARY.BEASTS.ORG>
From: Chris Evans <chris@SCARY.BEASTS.ORG>
To: BUGTRAQ@SECURITYFOCUS.COM
Hi,
SUMMARY
-------
LPRng is almost certainly vulnerable to remote-root compromise on account
of a format string bug. The flaw is almost identical to the rpc.statd one
I found; namely a faulty syslog() wrapper. This is becoming a very common
flaw.
Details
-------
Here is a code excerpt from:
/LPRng-3.6.22/src/common/errormsg.c, use_syslog()
---
static void use_syslog(int kind, char *msg)
...
# ifdef HAVE_OPENLOG
/* use the openlog facility */
openlog(Name, LOG_PID | LOG_NOWAIT, SYSLOG_FACILITY );
syslog(kind, msg);
closelog();
# else
(void) syslog(SYSLOG_FACILITY | kind, msg);
# endif /* HAVE_OPENLOG */
...
---
Here we see two classic format string bugs. Both syslog() calls are
missing a "%s" format string argument.
But how exploitable is this? Does the daemon log any use supplied
data? Let's do a test on the extremely recently released RedHat7.0, which
has switched to LPRng.
[chris@localhost chris]$ telnet localhost printer
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
Mary had a little lamb.
Connection closed by foreign host.
...
grep lamb /var/log/messages
Sep 24 07:38:36 localhost SERVER[1282]: Dispatch_input: bad request line
'Mary had a little lamb.^M'
...
Well, how obliging of (my particular version) of LPRng to log any input
line I give it.
Just to confirm %'s cause trouble:
Client:
[chris@localhost chris]$ telnet localhost printer
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
%s%s%s%s%s%s%s%s%s%s
Server:
Program received signal SIGSEGV, Segmentation fault.
0x400f7c66 in _IO_vfprintf (s=0x80c53a0,
format=0xbffff190 "Dispatch_input: bad request line
'%s%s%s%s%s%s%s%s%s%s^M'", ap=0xbfffed0c) at
../sysdeps/i386/i486/bits/string.h:529
(gdb) bt
#0 0x400f7c66 in _IO_vfprintf (s=0x80c53a0,
format=0xbffff190 "Dispatch_input: bad request line
'%s%s%s%s%s%s%s%s%s%s^M'", ap=0xbfffed0c) at
../sysdeps/i386/i486/bits/string.h:529
#1 0x4017d60b in vsyslog (pri=6,
fmt=0xbffff190 "Dispatch_input: bad request line
'%s%s%s%s%s%s%s%s%s%s^M'", ap=0xbfffed08) at syslog.c:193
#2 0x4017d447 in syslog (pri=6,
fmt=0xbffff190 "Dispatch_input: bad request line
'%s%s%s%s%s%s%s%s%s%s^M'")
at syslog.c:102
...
The program has root privs at this time;
(gdb) print geteuid()
$1 = 4 <-- initially encouraging
(gdb) print getuid()
$2 = 0 <-- depressing
FIX
---
- Add "%s" arguments to the syslog() calls
- Firewall the printer port
Exploit
-------
Not my scene. I'm sure some friendly black hat will come out with one
soon, though. Perhaps remembering to credit me this time? ;-)
Cheers
Chris