xorl %eax, %eax

CVE-2009-0845: MIT Kerberos V5 Remote DoS

leave a comment »

This vulnerability was reported by Richard Evans and affects MIT Kerberos V5 up to 1.6.3 release. Here is the code from this release of MIT Kerberos:

1156 /*ARGSUSED*/
1157 OM_uint32
1158 spnego_gss_accept_sec_context(void *ct,
1159                             OM_uint32 *minor_status,
1160                             gss_ctx_id_t *context_handle,
1161                             gss_cred_id_t verifier_cred_handle,
1162                             gss_buffer_t input_token,
1163                             gss_channel_bindings_t input_chan_bindings,
1164                             gss_name_t *src_name,
1165                             gss_OID *mech_type,
1166                             gss_buffer_t output_token,
1167                             OM_uint32 *ret_flags,
1168                             OM_uint32 *time_rec,
1169                             gss_cred_id_t *delegated_cred_handle)
1170 {
1171         OM_uint32 ret, tmpret, tmpmin, negState;
1172         send_token_flag return_token;
         ...
1206                 /* Can set negState to REQUEST_MIC */
1207                 ret = acc_ctx_new(minor_status, input_token,
1208                                   context_handle, verifier_cred_handle,
1209                                   &mechtok_in, &mic_in,
1210                                   &negState, &return_token);
1211                 if (ret != GSS_S_COMPLETE)
1212                         goto cleanup;
         ...
1250 cleanup:
1251         if (return_token != NO_TOKEN_SEND && return_token != CHECK_MIC)
1251 {
1252                 tmpret = make_spnego_tokenTarg_msg(negState, sc->internal_mech,
1253                                                    &mechtok_out, mic_out,
1254                                                    return_token,
1255                                                    output_token);
         ...
1281         return ret;
1282 }

This function is located at src/lib/gssapi/spnego/spnego_mech.c. This is part of the GSS-API (Generic Security Services Application Program Interface) library of MIT Kerberos Project. The above routine is responsible for manipulating and accepting the SPENGO (Simple and ProtEcted NeGOtiation) security context. At line 1172 it declares an uninitialized variable of type send_token_flag. This is an enumeration field defined at gssapiP_spnego.h like this:

52 /*
53  * send_token_flag is used to indicate in later steps what type
54  * of token, if any should be sent or processed.
55  * NO_TOKEN_SEND = no token should be sent
56  * INIT_TOKEN_SEND = initial token will be sent
57  * CONT_TOKEN_SEND = continuing tokens to be sent
58  * CHECK_MIC = no token to be sent, but have a MIC to check.
59  * ERROR_TOKEN_SEND = error token from peer needs to be sent.
60  */
61
62 typedef enum {NO_TOKEN_SEND, INIT_TOKEN_SEND, CONT_TOKEN_SEND,
63                 CHECK_MIC, ERROR_TOKEN_SEND} send_token_flag;

Now, if we move back to the vulnerable function and continue to line 1207 we’ll see a call to acc_ctx_new() routine. Here is what can this routine return:

875 /*
876  * Set negState to REJECT if the token is defective, else
877  * ACCEPT_INCOMPLETE or REQUEST_MIC, depending on whether initiator's
878  * preferred mechanism is supported.
879  */
880 static OM_uint32
881 acc_ctx_new(OM_uint32 *minor_status,
882             gss_buffer_t buf,
883             gss_ctx_id_t *ctx,
884             gss_cred_id_t cred,
885             gss_buffer_t *mechToken,
886             gss_buffer_t *mechListMIC,
887             OM_uint32 *negState,
888             send_token_flag *return_token)
889 {
         ...
902         *return_token = ERROR_TOKEN_SEND;
         ...
906         ret = get_negTokenInit(minor_status, buf, &der_mechTypes,
907                                &mechTypes, &req_flags,
908                                mechToken, mechListMIC);
         ...
913                 ret = gss_inquire_cred(minor_status, cred, NULL, NULL,
914                                        NULL, &supported_mechSet);
         ...
920                 ret = get_available_mechs(minor_status, GSS_C_NO_NAME,
921                                           GSS_C_ACCEPT, NULL,
922                                           &supported_mechSet);
         ...
966         return ret;
967 }

As you can see return_token is initialized to ERROR_TOKEN_SEND at line 902. If an error occurs on one of the above calls it will remain in this status. Then, back to spnego_gss_accept_sec_context() at line 1251 it checks it against NO_TOKEN_SEND (which is 0) and CHECK_MIC (which is 3), however, return_token as we already mention could be 4. This means that it will bypass the check even though it contains an error code and invoke make_spnego_tokenTarg_msg() at line 1252. Here is what this function is used for:

2444 /*
2445  * create the server side spnego token passed back to
2446  * gss_accept_sec_context and eventually up to the application program
2447  * and over to the client.
2448  */
2449 static int
2450 make_spnego_tokenTarg_msg(OM_uint32 status, gss_OID mech_wanted,
2451                           gss_buffer_t data, gss_buffer_t mechListMIC,
2452                           send_token_flag sendtoken,
2453                           gss_buffer_t outbuf)
2454 {


This function assumes that its sendtoken argument has a valid INIT_TOKEN_SEND or CONT_TOKEN_SEND value. This is where it fails. The patch was simple. Just update the if statement of line 1251 to this:

cleanup:
-            if (return_token != NO_TOKEN_SEND && return_token != CHECK_MIC) {
+            if (return_token == INIT_TOKEN_SEND ||
+                return_token == CONT_TOKEN_SEND) {
                   tmpret = make_spnego_tokenTarg_msg(negState, sc->internal_mech,

Written by xorl

April 6, 2009 at 13:10

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