xorl %eax, %eax

CVE-2009-0021: NTP SSL/TLS Validation Bypass

leave a comment »

NTP is one of the most popular implementations used on the internet for network time protocol. This issue was made public on 8 January 2009. It affects NTP 4.2.4 up to 4.2.4p5 of the production release and 4.2.5 up to 4.2.5p150 which is the development release. The following code is from 4.2.4p5 release of the popular NTP. The bug is located at ntpd/ntp_crypto.c:

1483  /*
1484   * crypto_verify - parse and verify the extension field and value
1485   *
1486   * Returns
1487   * XEVNT_OK     success
1488   * XEVNT_LEN    bad field format or length
1489   * XEVNT_TSP    bad timestamp
1490   * XEVNT_FSP    bad filestamp
1491   * XEVNT_PUB    bad or missing public key
1492   * XEVNT_SGL    bad signature length
1493   * XEVNT_SIG    signature not verified
1494   * XEVNT_ERR    protocol error
1495   */
1496  static int
1497  crypto_verify(
1498          struct exten *ep,       /* extension pointer */
1499          struct value *vp,       /* value pointer */
1500          struct peer *peer       /* peer structure pointer */
1501          )
1502  {
1503          EVP_PKEY *pkey;         /* server public key */
1504          EVP_MD_CTX ctx;         /* signature context */
1505          tstamp_t tstamp, tstamp1 = 0; /* timestamp */
1506          tstamp_t fstamp, fstamp1 = 0; /* filestamp */
1507          u_int   vallen;         /* value length */
1508          u_int   siglen;         /* signature length */
1509          u_int   opcode, len;
1510          int     i;
        ...
1607          /*
1608           * Darn, I thought we would never get here. Verify the
1609           * signature. If the identity exchange is verified, light the
1610           * proventic bit. If no client identity scheme is specified,
1611           * avoid doing the sign exchange.
1612           */
1613          EVP_VerifyInit(&ctx, peer->digest);
1614          EVP_VerifyUpdate(&ctx, (u_char *)&ep->tstamp, vallen + 12);
1615          if (!EVP_VerifyFinal(&ctx, (u_char *)&ep->pkt[i], siglen, pkey))
1616                  return (XEVNT_SIG);
1617
        ...
1623          return (XEVNT_OK);
1624  }
1625
1626

As you can clearly see, this function is used to verify some fields of the signature. At line 1613 we can see that it uses an OpenSSL routine. This is used to set up the verification context (in this case ctx). Then, using another EVP routine at line 1614 it updates the context. Finally, it uses EVP_VerifyFinal() to verify the context ctx against the public key pkey and also siglen bytes of the second argument which is a buffer containing the signature. By reading the OpenSSL documentation page of these calls. we can see the following:

RETURN VALUES
EVP_VerifyInit_ex() and EVP_VerifyUpdate() return 1 for success and 0 for failure.
EVP_VerifyFinal() returns 1 for a correct signature, 0 for failure and -1 if some other error occurred.

However, at line 1615 we can see that NTP only fails (XEVNT_SIG = Signature Not Verified) if the return value is 0 which means failure. If any other error occurs (which means -1) then it passes the check and returns (XEVNT_OK = Signature is OK) assuming that it is dealing with a valid SSL/TLS connection (line 1623)! If you can setup a connection with an NTP server and have an invalid signature which makes EVP_VerifyFinal() fail then you can bypass the signature validation check. This was patched simply by doing the following at 4.2.4p6:

        EVP_VerifyUpdate(&ctx, (u_char *)&ep->tstamp, vallen + 12);
-       if (!EVP_VerifyFinal(&ctx, (u_char *)&ep->pkt[i], siglen, pkey))
+       if (EVP_VerifyFinal(&ctx, (u_char *)&ep->pkt[i], siglen, pkey) <= 0)
                return (XEVNT_SIG);

Now it checks for both failure and other errors. And here is some trolling:
Did you read the Vupen advisory? It says:
“This issue is caused due to various functions not properly checking the result of the OpenSSL “EVP_VerifyFinal()”
What the fuck? The only place where this bug was present was at ntpd/ntp_crypto.c, function crypto_verify(). I challenge you to find another instance! According to the patch, NTP developers didn’t find any. Vupen found or didn’t even bother reading the damn code?

Written by xorl

March 11, 2009 at 16:19

Posted in bugs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s