[AMF/MME] NAS message in an invaild state (#3131)

In InitialUEMessage, send a NAS message with a message type
other than Registration Request, Deregistration Request, or Service Request,
the following messages from UE will not be accepted.

We found this issue in not only the initial state but multiple states.
We believe if an attacker has the ability to inject a NAS message to the core,
it can perform a DoS attack on the victim UE.

So, I've fixed that The MME/AMF deletes MME_UE_S1AP_ID/AMF_UE_NGAP_ID,
and will not accept any following messages from the UE.
This commit is contained in:
Sukchan Lee 2024-04-13 13:22:19 +09:00
parent cd76dc641d
commit 3cfa8ba301
5 changed files with 77 additions and 8 deletions

View File

@ -200,6 +200,7 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
default:
ogs_error("Not implemented(security header type:0x%x)",
sh->security_header_type);
ran_ue_remove(ran_ue);
return OGS_ERROR;
}
@ -207,12 +208,39 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
if (nas_5gs_security_decode(ran_ue->amf_ue,
security_header_type, nasbuf) != OGS_OK) {
ogs_error("nas_eps_security_decode failed()");
ran_ue_remove(ran_ue);
return OGS_ERROR;
}
}
h = (ogs_nas_5gmm_header_t *)nasbuf->data;
ogs_assert(h);
if (procedureCode == NGAP_ProcedureCode_id_InitialUEMessage) {
if (h->extended_protocol_discriminator !=
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM) {
ogs_error("Invalid extended_protocol_discriminator [%d]",
h->extended_protocol_discriminator);
ogs_pkbuf_free(nasbuf);
ran_ue_remove(ran_ue);
return OGS_ERROR;
}
if (h->message_type != OGS_NAS_5GS_REGISTRATION_REQUEST &&
h->message_type != OGS_NAS_5GS_SERVICE_REQUEST &&
h->message_type != OGS_NAS_5GS_DEREGISTRATION_REQUEST_FROM_UE) {
ogs_error("Invalid 5GMM message type [%d]", h->message_type);
ogs_pkbuf_free(nasbuf);
ran_ue_remove(ran_ue);
return OGS_ERROR;
}
}
if (h->extended_protocol_discriminator ==
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM) {
e = amf_event_new(AMF_EVENT_5GMM_MESSAGE);
@ -247,7 +275,10 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
} else {
ogs_error("Unknown NAS Protocol discriminator 0x%02x",
h->extended_protocol_discriminator);
ogs_pkbuf_free(nasbuf);
ran_ue_remove(ran_ue);
return OGS_ERROR;
}
}

View File

@ -586,10 +586,8 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, ogs_s1ap_message_t *message)
enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id,
enb_ue->saved.tai.tac, enb_ue->saved.e_cgi.cell_id);
r = s1ap_send_to_nas(enb_ue,
S1AP_ProcedureCode_id_initialUEMessage, NAS_PDU);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
ogs_expect(OGS_OK == s1ap_send_to_nas(
enb_ue, S1AP_ProcedureCode_id_initialUEMessage, NAS_PDU));
}
void s1ap_handle_uplink_nas_transport(
@ -777,10 +775,8 @@ void s1ap_handle_uplink_nas_transport(
ogs_error("No UE Context in UplinkNASTransport");
}
r = s1ap_send_to_nas(enb_ue,
S1AP_ProcedureCode_id_uplinkNASTransport, NAS_PDU);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
ogs_expect(OGS_OK == s1ap_send_to_nas(
enb_ue, S1AP_ProcedureCode_id_uplinkNASTransport, NAS_PDU));
}
void s1ap_handle_ue_capability_info_indication(

View File

@ -207,6 +207,7 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
default:
ogs_error("Not implemented(security header type:0x%x)",
sh->security_header_type);
enb_ue_remove(enb_ue);
return OGS_ERROR;
}
@ -214,12 +215,42 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
if (nas_eps_security_decode(enb_ue->mme_ue,
security_header_type, nasbuf) != OGS_OK) {
ogs_error("nas_eps_security_decode failed()");
enb_ue_remove(enb_ue);
return OGS_ERROR;
}
}
h = (ogs_nas_emm_header_t *)nasbuf->data;
ogs_assert(h);
if (procedureCode == S1AP_ProcedureCode_id_initialUEMessage) {
if (h->protocol_discriminator != OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM) {
ogs_error("Invalid protocol_discriminator [%d]",
h->protocol_discriminator);
ogs_pkbuf_free(nasbuf);
enb_ue_remove(enb_ue);
return OGS_ERROR;
}
if (h->security_header_type !=
OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE &&
h->message_type != OGS_NAS_EPS_ATTACH_REQUEST &&
h->message_type != OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST &&
h->message_type != OGS_NAS_EPS_EXTENDED_SERVICE_REQUEST &&
h->message_type != OGS_NAS_EPS_DETACH_REQUEST) {
ogs_error("Invalid EMM message type [%d]", h->message_type);
ogs_pkbuf_free(nasbuf);
enb_ue_remove(enb_ue);
return OGS_ERROR;
}
}
if (h->protocol_discriminator == OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM) {
int rv;
e = mme_event_new(MME_EVENT_EMM_MESSAGE);
@ -255,7 +286,10 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
} else {
ogs_error("Unknown/Unimplemented NAS Protocol discriminator 0x%02x",
h->protocol_discriminator);
ogs_pkbuf_free(nasbuf);
enb_ue_remove(enb_ue);
return OGS_ERROR;
}
}

View File

@ -1862,6 +1862,7 @@ static void issues_2287_v264_func(abts_case *tc, void *data)
test_ue_remove_all();
}
#if 0 /* Deprecated to resolve issue #3131 */
static void pull_3122_v270_func(abts_case *tc, void *data)
{
int rv;
@ -1973,6 +1974,7 @@ static void pull_3122_v270_func(abts_case *tc, void *data)
test_ue_remove(test_ue);
}
#endif
abts_suite *test_issues(abts_suite *suite)
{
@ -1981,7 +1983,9 @@ abts_suite *test_issues(abts_suite *suite)
abts_run_test(suite, issues_1431_func, NULL);
abts_run_test(suite, issues_2287_v263_func, NULL);
abts_run_test(suite, issues_2287_v264_func, NULL);
#if 0 /* Deprecated to resolve issue #3131 */
abts_run_test(suite, pull_3122_v270_func, NULL);
#endif
return suite;
}

View File

@ -354,6 +354,7 @@ static void test1_func(abts_case *tc, void *data)
test_ue_remove(test_ue);
}
#if 0 /* Deprecated to resolve issue #3131 */
static void pull_3122_v270_func(abts_case *tc, void *data)
{
int rv;
@ -469,13 +470,16 @@ static void pull_3122_v270_func(abts_case *tc, void *data)
/* Clear Test UE Context */
test_ue_remove(test_ue);
}
#endif
abts_suite *test_identity(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test1_func, NULL);
#if 0 /* Deprecated to resolve issue #3131 */
abts_run_test(suite, pull_3122_v270_func, NULL);
#endif
return suite;
}