<<< Date Index >>>     <<< Thread Index >>>

Re: smail remote and local root holes (no, not really ;-)



Sean you can't send me mail because hotpop.com is blacklisted:

    $ host -a hotpop.com.postmaster.rfc-ignorant.org  
    hotpop.com.postmaster.rfc-ignorant.org  A       127.0.0.3
    hotpop.com.postmaster.rfc-ignorant.org  TXT     "Not supporting 
postmaster@xxxxxxxxxx"

You'll have to find a different mail domain to send from.  All of my
addresses will refuse all mail with a sender address @hotpop.com and I'm
not going to whitelist a domain like that one.


Your report was forwarded to me successfully though.  (Thanks Bruce!)

(I really should try to fix my BUGTRAQ subscription though....  or
rather get securityfocus to properly fix their DNS so I don't have to
bounce random messages from the list....)


You have indeed found a really old heap buffer overflow (it is in code
that's been there effectively unchanged since long before I took over
maintenance).

Don't worry though -- it's definitely not exploitable.  It's just
tripping one of smail's own self-defense mechanisms.

If you fix your debugger (and/or recompile with -g) to give a proper
backtrace you'll find that the failure comes in xfree(), and it's
killing itself on purpose because it has detected your heap overflow
attempt.

(gdb) where
#0  abort () at /work/woods/m-NetBSD-1.6/lib/libc/stdlib/abort.c:84
#1  0x136c4 in xfree (region=0x132c44 'A' <repeats 54 times>, "!A>")
    at alloc.c:153
#2  0x10960 in preparse_address_1 (
    address=0x135c0f "A!@", 'A' <repeats 54 times>, ":A>", error=0xeffff0f8, 
    rest=0xeffff0f4) at addr.c:235
#3  0x4087c in receive_smtp (in=0xe2778, out=0xe27d0, peer=0xeffff2b8)
    at smtprecv.c:787
#4  0x30498 in do_smtp (in=0xe2778, out=0xe27d0, peer=0xd6c00) at modes.c:2853
#5  0x2e48c in do_daemon_accept (ls=4, fd=6, from=0xeffff2b8) at modes.c:1725
#6  0x2ddd0 in daemon_mode () at modes.c:1524
#7  0x27290 in main (argc=3, argv=0xeffff500) at main.c:932
#8  0x1030c in ___start (argc=3, argv=0xeffff4fc, envp=0xd58e0, cleanup=0, 
    obj=0x0, ps_strings=0xeffffff0)
    at /work/woods/m-NetBSD-1.6/lib/csu/sparc_elf/crt0.c:97
#9  0x10238 in _start ()
    at /work/woods/m-NetBSD-1.6/lib/csu/sparc_elf/../common_elf/crtbegin.c:167


Also if you check your smail paniclog you'll find entries like:

2005/03/25 14:21:30: [3521] X_CHECK failed!  ptr=0x8153c84, line=153, 
file=alloc.c
2005/03/25 14:21:30: [27057] smtpd PID 3521 killed by signal SIGABRT and dumped 
core: Abort trap

Since the call to xfree() comes so soon after the buffer is overflowed,
there's no chance to even try an exploit.  The best you can do is kill
your own connection, leaving lots of evidence about your attempt and
where you connected from, including enough info to find and fix the bug.  ;-)


BTW, why do you go to so much trouble to write a bug exerciser in C
though?  A little text file fed to "nc localhost 25" is all you need in
this case, for example:

        HELO localhost
        MAIL FROM:<A!@BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:C>

(and with the right version of "nc" you can use '-i 10' or similar to
give yourself time to attach the debugger to the server process before
the second line of text is sent to the sever)


Your proposed fix isn't quite right, but it's very close.  Thanks!

(exercising that old code also revealed a logic bug in it too! :-)

(you'll find my exact changes in the next release....  due soon :-)


However your analysis of the signal handler missed one very critical
point:  That signal handler never returns, and so making use of any
possible malloc(), etc., reentry bug is going to be damn near
impossible.

Further the write_log() call may not even call malloc() or realloc()
since the storage it allocates reused in subsequent calls, so you would
have to be very lucky to manage to interrupt some other early malloc()
call that happens before all other write_log() calls, and do so in such
a way that a subsequent call to malloc() via write_log() could ever do
any damage, and you would probably have to use a stack overflow right
then and there in malloc() because otherwise there won't be any other
chance before the exit() call that happens immediately upon return from
write_log().  I don't think any modern implementations of malloc() are
even potentially vulnerable to stack buffer overflows due to reentrant
calls in the first place either.  If you do ever manage to even get a
core dump though let me know where, how, and on what platform!  :-)

(but please be sure to always compile with '-g' so the backtrace is useful)


-- 
                                                Greg A. Woods

H:+1 416 218-0098  W:+1 416 489-5852 x122  VE3TCP  RoboHack <woods@xxxxxxxxxxx>
Planix, Inc. <woods@xxxxxxxxxx>          Secrets of the Weird <woods@xxxxxxxxx>