This Old Vulnerability: Sendmail Debug Array
Dave G. | November 15th, 2006 | Filed Under: This Old Vulnerability
As we sit here, somewhere around the cusp of integer overflows (some will say we are past the peak) and signed/unsigned comparison bugs, I wanted to reflect back on the earliest one that I can remember. First, lets set the stage.
The year was 1994, which means it was likely that I was wearing flannel, Jeremy was listening to New York Hardcore (not unlike 2006), Dino wasn’t allowed to stay up past 11PM (not unlike 2006), and Tom was wearing all black (also not unlike 2006). March was actually a crazy month for vulnerability research. 8LGM posted their first 4 security advisories (predated back as far as 1991). And sendmail bugs would come out somewhere between weekly and monthly.
Let’s take a look at the first post:
I mailed to both CERT and the Sun security email addresses over a month back. Neither replied until I mailed again explicitely asking whether or not they’d even received my mail. Having heard nothing for a month now I’ve decided to mail here.
If people are wondering why the research community has had rocky relationships with vendors and CERT, this is one example of many from that time period that got us all off on the wrong foot.
There is a bug in many versions of sendmail to do with the -d command line option. This allows setting of arbitrary elements of the debug array. I first heard of the bug whilst examining the IDA sendmail source code 2-3 years back.
Wow, so this bug was known back in 1991. I was listening to heavy metal bands like Metallica, Iron Maiden, and Suicidal Tendencies (not unlike 2006). Sendmail+IDA is long gone, and was slightly easier to configure than sendmail.
To test if your sendmail has it, try using -d with a mumber greater than max signed int, and less than max unsigned int, that preferably is substantially far enough from either to be well outside normal address space ranges when used as an array index.Eg:
$ sendmail -d3294967296
Now this was in a time before buffer overflows and other memory trespasses were the technique du jour. Back then, normal exploitation techniques involved:
- IFS=/
- PATH=.:$PATH
- {|;} /bin/sh
- ln -s /tmp/something /.rhosts
Let’s see get some more detail and see how they tried to exploit it:
The problem is that with -d arguments between max signed int and max unsigned int pass the valid-range (0-99 inclusive) check. The result is that it is possible to write to areas of memory prior to the debug array. With a bit of trickery the pathname of the sendmail config can be deduced as an offset from the debug array. Hence the leading slash can then be changed to a ‘.’ to produce a relative pathname.
Not bad… with a one byte memory corruption, root is obtained. Alas, the exploit doesnt actually do the one byte change of a ‘/’ to a ‘.’, but instead writes out a whole new path, one -d at a time.
When this bug came out, I remember talking to Tim Newsham about it, and my head pretty much exploded. I had even logged the conversation, but alas, I think that disk is long gone.
Of course, we probably wouldn’t try something like that post memory trespass renaissance. I wonder what would happen if that bug had come out in a post buffer overflow world. It’s a shame that people learn from their mistakes.
[FAST FORWARD TO 2001]
I am still listening to heavy metal, jeremy is still listening to ny hardcore, tom still wears black, Dino is still in bed by 11PM and sendmail is still vulnerable to the exact same vulnerability.
This one vulnerability (implemented twice) was known about and exposed in sendmail for at least 4 years.
This one uses a more time appropriate exploitation technique, kickin’ it with the GOT.
| The Bugtraq Patch (1994) | The FreeBSD patch (2001) |
tTflag(s)
register char *s;
{
- int first, last;
- register int i;
+ unsigned int first, last;
+ register unsigned int i;
|
tTflag(s)
register char *s;
{
- int first, last;
+ unsigned int first, last;
register unsigned int i;
|
Of course, 8.10.2 to 8.11.0 was a big version jump for sendmail, they probably re-implemented a lot of functionality in the tracing subsystem, right?
$ diff sendmail-8.10.2/sendmail/trace.c sendmail-8.11.0/sendmail/trace.c
15c15
< static char id[] = "@(#)$Id: trace.c,v 8.20 1999/08/02 21:44:36 ca Exp $";
---
> static char id[] = "@(#)$Id: trace.c,v 8.20.22.1 2000/05/25 18:56:18 gshapiro Exp $";
66c66
< unsigned int first, last;
---
> int first, last;
Why would someone make that change? It is highly unlikely it was a source control problem, because:
- Who would accidentally be using the tTflags() function from 1994 in 2001?
- Even if they did, the variable underneath it was left as unsigned in 8.11.x
Can anyone think of a reason as to why someone would make this change? Because I am coming up with a blank other than gross incompetence or an intentional backdoor created by either a sendmail developer or someone who compromised the sendmail source code. Anyone from sendmail know why this change took place?
Am I being paranoid, or are they really out to get us? What other ways could this have happened?
Memorable Quotes
A quote from: Peter Wemm (petergecko.dialix.oz.au) on Mon, 28 Mar 1994 :
Oh. Joy! However, with the intense security that sendmail is getting at the moment, I can’t imagine that there’s too many undiscovered holes left now..
From Sendmail 8.6.7 dist:
SECURITY: it was possible to get root access by using wierd values to the -d flag. Thanks to Alain Durand of INRIA for forwarding me the notice from the bugtraq list.
From Perry Metzger:
So, does anyone know anything about this new Sendmail bug other than that it exists?
From “Evil Pete” Shipley
has anyone acutaly obtained root with the -d option?


Lucas Nelson
November 16th, 2006 10:41 am“The year was 1994, which means it was likely that I was wearing flannel, Jeremy was listening to New York Hardcore”
Actually, it is a little known fact that Jeremy was probably listening to the Gratefull Dead. Damn hippy.
Chase Venters
November 16th, 2006 3:16 pmThat reminds me of when someone tried to sneak a patch into Linux that changed a uid == 0 check to uid = 0. It was caught in a diff before it ever got released… not sure they ever figured out who the real source was.
Jesse Ruderman
April 4th, 2007 6:17 pmPerhaps CVS blame + CVS commit messages could give you a hint as to why it was changed back to signed, and who changed it.
Leave a reply