* * * * *

                        Sploits, upgrades and updates

I avoid upgrading, not so much to avoid version fatigue [1] as that what I
have works and as the saying goes, “if it ain't broke, don't fix it!”

So it was rather surprising to find myself upgrading two important packages
this week. The first being Apache. [2] In looking over the security bulletin
[3], while it wouldn't allow one to get remote access on my particular
platform (a 32 bit operating system) it could lead to a denial of service
attack so I decided for performance reasons to upgrade (unlike most sysadmins
I know, I'm not so paranoid about people gaining access that my systems are
unusable but that's a rant for another time).

The Apache upgrade went smoothly.

The other package I needed to upgrade however …

I received word from Mark [4] about an upcoming OpenSSH [5] exploit [6] that
will allow remote root access! While I may be relaxed about security, I'm not
stupid either.

Reading up on it, no patches are available, but if you run the latest version
with a certain option, the bug that allows the exploit is still there, but it
can't be exploited.

Okay …

So I download the latest version of OpenSSH, configure, compile and install
the code on my development server (I'm not about to install it untested on my
colocated box—if I screw up it's a long and painful process [7] to fix).
Install and run the new sshd server. Okay, seems to be running. Attempt to
log in.

Apparently it accepts incoming network connections, then promptly drops the
connection. I can't log in.

Odd …

I check the log files and for every attempt I made to log in, find the
following entry:

-----[ data ]-----
Jun 25 04:14:56 linus sshd[13062]: fatal: mmap(65536): Invalid argument
-----[ END OF LINE ]-----

The number being fed to mmap(), 65536, is suspicious but given the platform
I'm on, shouldn't be invalid. Time to check the source to OpenSSH:

-----[ C ]-----
address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, -1, 0);
if (address == MAP_FAILED)
       fatal("mmap(%lu): %s", (u_long)size, strerror(errno));

-----[ END OF LINE ]-----

openssh-3.3p1/monitor_mm.c:88-90

This is the only place in OpenSSH that calls mmap() so I have the right
location. And since mmap() is complaining about getting an invalid argument,
it's time to determine just which argument mmap() is complaining about.

Now, normally, mmap() is used to map files into memory, but it does have its
other uses (such as here, which seems to be allocating a section of memory to
be shared with something else). Going through the paramters, the first is the
starting address, which here is NULL but that's allowed; it just tells mmap()
to use any available address that matches the criteria. The length (65536)
should be okay for this platform. The protection of the memory region
(PROT_WRITE and PROT_READ) look good, as to the options (a shared, anonymous
region of memory). The file to be used (-1) looks odd; the man page doesn't
say anything about not specifying a file, but the offset to use in the file
(which isn't specified) looks good.

Now, since the man page doesn't mention anything about not specifying a file,
now it's time to check the kernel sources to see what Linux might be
rejecting.

-----[ C ]-----
if (file != NULL) {
       ...

} else if ((flags & MAP_TYPE) != MAP_PRIVATE)
       return -EINVAL;
-----[ END OF LINE ]-----

linux-2.0.36/mm/mmap.c:171-198

Here, file is NULL so the else clause kicks in, and well … there you go.
OpenSSH is asking for MAP_SHARED but Linux 2.0.36 doesn't support that
option. Neither does Linux 2.0.39 (what my colocated server and firewall
run).

Linux 2.4 however (at least 2.4.18 which I had immediate access to) does
support the usage of mmap() than OpenSSH requires.

But due to a lot of reasons, upgrading my servers from Linux 2.0 to 2.4 is
pretty much out of the question (at least for any reasonable amount of time
and effort), and taking out the offending code in Linux 2.0 is out, until I
can test it and make sure it works, so in the mean time, my only real hope is
security through obsolescense. [8]

I recompiled the version of OpenSSH I am using with different compiler
options to make an exploit less likely to work, since exploits are quite
dependant upon both the architecture and code layout (and operating system,
plus maybe kernel versions of said operating system) this should be good
enough to keep all but the most dedicated off my systems.

[1] http://www.techcentralstation.com/1051/techwrapper.jsp?PID=1051-250&CID=1051-061902B
[2] http://httpd.apache.org/
[3] http://httpd.apache.org/info/security_bulletin_20020617.txt
[4] http://www.conman.org/people/myg/
[5] http://www.openssh.org/
[6] http://www.linuxweeklynews.com/Articles/3322/
[7] gopher://gopher.conman.org/0Phlog:2002/03/20.1
[8] http://www.theregister.co.uk/content/55/25608.html

Email author at [email protected]