Harlan Stenn wrote:
In article <[EMAIL PROTECTED]>, [EMAIL PROTECTED] (Luc Pardon) writes:

Lots of good stuff.

Luc>     Case in point #1: back in 2001, there was a bug in - yes - (x)ntpd
Luc> that allowed remote root access. See, for example:
Luc> http://archive.cert.uni-stuttgart.de/archive/bugtraq/2001/04/msg00064.html

First, please compare this history to other root-running processes and tell
me how (x)ntpd compares.  Especially given the length of time (x)ntpd has
been in the field.


We wouldn't be having this discussion if I was of the opinion that (x)ntpd had a lousy track record. I wouldn't bother.

I mentioned this only to show that there can be buffer overflow bugs in otherwise correct code.

To put it another way: if I want to serve a web site, I _must_ have something listening at tcp/80. In that case, the track record _is_ relevant: I'll select a server with a good one, hope for the best and prepare for the worst. Sooner or later, there _will_ be an exploit and then I have to patch as fast as I can. It is a risk, but I have no choice. In return for taking the risk, I have a website. Now, if I don't need a website on that machine, why run a web server, no matter how good its track record?

To keep the time (in my setup, which I believe to be typical for the majority of users), there is no need to have a server on a public interface. Taking the risk buys me nothing and therefore I am not prepared to accept it, no matter how good the track record of the daemon.

 > Luc>     Case in point #2: only last week, my logs were being flooded
Luc> because somebody sent icmp port unreachable packets to udp/123.
Fair point, and Real Soon Now we're going to have better configuration
control over logfiles.

The problem is that you can't distinguish between real and fake packets. If you suppress the fake "connection refused", you may be wiping real problems under the carpet as well.

> And I thought syslog() was pretty good about "Last
message repeated N times".

Point taken, I did forget that. It issues a "repeated" every second, so our attacker would not be ready by Sunday. Unless he can find another way - preferably with (x)ntpd - to generate a syslog entry and alternate that with the port unreachable packets. A "grep syslog *.c | grep LOG_ERR" yields some promising candidates.

   Out of curiosity, I had a quick look at the ntp-dev-4.2.3p39 code.

  <black hat on>

At first sight, it seems possible to craft a packet that will end up in process_private() in ntp_request.c and trigger the sanity check in there.

   In ntp_proto.c(388), it says:

        hismode = (int)PKT_MODE(pkt->li_vn_mode);
        hisstratum = PKT_TO_STRATUM(pkt->stratum);
        if (hismode == MODE_PRIVATE) {
                if (restrict_mask & RES_NOQUERY) {
                        sys_restricted++;
                        return;                 /* no query private */
                }
                process_private(rbufp, ((restrict_mask &
                    RES_NOMODIFY) == 0));
                return;
        }

So I'd set the li_vn_mode to PRIVATE (whatever that means <g>) and I'd fake the source address to 127.0.0.1 to steer it past the restrict rules in most setups. If and when I make it into process_private(), I have a choice of 4 fields in the packet that I can load with invalid values, or I could make it too long or too short. In ntp_request.c(433) my malicious eyes see the following code that makes me drool:

        /*
         * Do some sanity checks on the packet.  Return a format
         * error if it fails.
         */
        ec = 0;
        if (   (++ec, ISRESPONSE(inpkt->rm_vn_mode))
            || (++ec, ISMORE(inpkt->rm_vn_mode))
            || (++ec, INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION)
            || (++ec, INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION)
            || (++ec, INFO_SEQ(inpkt->auth_seq) != 0)
            || (++ec, INFO_ERR(inpkt->err_nitems) != 0)
            || (++ec, INFO_MBZ(inpkt->mbz_itemsize) != 0)
            || (++ec, rbufp->recv_length < REQ_LEN_HDR)
                ) {
msyslog(LOG_ERR, "process_private: INFO_ERR_FMT: test %d failed, pkt from %s", ec, stoa(srcadr));
                req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
                return;
        }

Too bad the restrict rules are in front of it, otherwise I could use my own IP (or that of one of my zombies) and I'd get an ack if I succeeded, then start faking source IP's.

  <black hat off>

Again: this is just the result of a quick look at unfamiliar code. More likely than not, I'm missing something obvious so that this won't fly. But it sure looks promising and if it should work, I have my siege engine complete. By alternating one of these with an icmp packet, I can flood the log just fine.

Again, this would not be an issue at all if (x)ntpd didn't take candy from strangers.


Regardless, I would like to see all these issues resolved, and I'm happy to
work cooperatively with anybody to see this happen.

H

_______________________________________________
questions mailing list
[email protected]
https://lists.ntp.isc.org/mailman/listinfo/questions
_______________________________________________
questions mailing list
[email protected]
https://lists.ntp.isc.org/mailman/listinfo/questions

Reply via email to