[SEC] Several vulnerabilities have been resolved.

1. Reachable assertion in ogs_nas_5gmm_decode

Location: lib/nas/5gs/decoder.c:4445

```c
int ogs_nas_5gmm_decode(ogs_nas_5gs_message_t *message, ogs_pkbuf_t *pkbuf)
{
    int size = 0;
    int decoded = 0;

    ogs_assert(pkbuf);
    ogs_assert(pkbuf->data);
    ogs_assert(pkbuf->len);
```

When a NAS payload is received over `src/amf/context.c:1675`NGAP that has no data, the ogs_assert(pkbuf->len) assertion will be triggered.

2.Reachable assertion in ogs_nas_emm_decode

```
int ogs_nas_emm_decode(ogs_nas_eps_message_t *message, ogs_pkbuf_t *pkbuf)
{
    int size = 0;
    int decoded = 0;

    ogs_assert(pkbuf);
    ogs_assert(pkbuf->data);
    ogs_assert(pkbuf->len);
```

Nearly identical to (1), but for LTE.

3. Reachable assertion in nas_eps_send_emm_to_esm

```
int nas_eps_send_emm_to_esm(mme_ue_t *mme_ue,
        ogs_nas_esm_message_container_t *esm_message_container)
{
    int rv;
    ogs_pkbuf_t *esmbuf = NULL;

    if (!mme_ue_cycle(mme_ue)) {
        ogs_error("UE(mme-ue) context has already been removed");
        return OGS_NOTFOUND;
    }

    ogs_assert(esm_message_container);
    ogs_assert(esm_message_container->length);
```

The ESM message payload may be 0-length, as the length is determined by a field in the NAS payload (which can be chosen arbitrarily by an attacker). This leads to the length assertion above being triggered.

5. Reachable assertion and incorrect hash calculation in ogs_kdf_hash_mme

```
void ogs_kdf_hash_mme(const uint8_t *message, uint8_t message_len, uint8_t *hash_mme)
{
    uint8_t key[32];
    uint8_t output[OGS_SHA256_DIGEST_SIZE];

    ogs_assert(message);
    ogs_assert(message_len);
    ogs_assert(hash_mme);

    memset(key, 0, 32);
    ogs_hmac_sha256(key, 32, message, message_len,
            output, OGS_SHA256_DIGEST_SIZE);

    memcpy(hash_mme, output+24, OGS_HASH_MME_LEN);
}
```

When handling NAS attach requests or TAU requests, the ogs_kdf_hash_mme function is passed the NAS payload. However, the length field is represented as an unsigned 8-bit integer, which the passed length of the packet may overflow. This leads to the passed value being truncated.

When the passed value is a multiple of 256, the above assertion (ogs_assert(message_len)) is triggered. Otherwise, the hash is computed on only the first n bits of the message (where n = actual_message_len % 256).
This commit is contained in:
Sukchan Lee 2024-02-03 10:37:36 +09:00
parent be12610fb6
commit d1d3ec6fcb
15 changed files with 36 additions and 39 deletions

View File

@ -463,7 +463,8 @@ void ogs_kdf_ck_ik_idle_mobility(
* TS33.401 Annex I Hash Functions
* Use the KDF given in TS33.220
*/
void ogs_kdf_hash_mme(const uint8_t *message, uint8_t message_len, uint8_t *hash_mme)
void ogs_kdf_hash_mme(
const uint8_t *message, uint32_t message_len, uint8_t *hash_mme)
{
uint8_t key[32];
uint8_t output[OGS_SHA256_DIGEST_SIZE];

View File

@ -121,7 +121,8 @@ void ogs_kdf_ck_ik_idle_mobility(
* TS33.401 Annex I Hash Functions
* Use the KDF given in TS33.220
*/
void ogs_kdf_hash_mme(const uint8_t *message, uint8_t message_len, uint8_t *hash_mme);
void ogs_kdf_hash_mme(
const uint8_t *message, uint32_t message_len, uint8_t *hash_mme);
/*
* TS33.102

View File

@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.2.0
* Please do not modify this file but regenerate it via script.
* Created on: 2023-03-04 20:50:00.889117 by acetcom
* Created on: 2024-01-21 18:47:47.827076 by acetcom
* from 24501-h90.docx
******************************************************************************/
@ -4449,15 +4449,14 @@ int ogs_nas_5gmm_decode(ogs_nas_5gs_message_t *message, ogs_pkbuf_t *pkbuf)
ogs_assert(pkbuf);
ogs_assert(pkbuf->data);
ogs_assert(pkbuf->len);
memset(message, 0, sizeof(ogs_nas_5gs_message_t));
size = sizeof(ogs_nas_5gmm_header_t);
if (ogs_pkbuf_pull(pkbuf, size) == NULL) {
ogs_error("ogs_pkbuf_pull() failed [size:%d]", (int)size);
return OGS_ERROR;
}
memset(message, 0, sizeof(ogs_nas_5gs_message_t));
memcpy(&message->gmm.h, pkbuf->data - size, size);
decoded += size;
@ -4710,15 +4709,14 @@ int ogs_nas_5gsm_decode(ogs_nas_5gs_message_t *message, ogs_pkbuf_t *pkbuf)
ogs_assert(pkbuf);
ogs_assert(pkbuf->data);
ogs_assert(pkbuf->len);
memset(message, 0, sizeof(ogs_nas_5gs_message_t));
size = sizeof(ogs_nas_5gsm_header_t);
if (ogs_pkbuf_pull(pkbuf, size) == NULL) {
ogs_error("ogs_pkbuf_pull() failed [size:%d]", (int)size);
return OGS_ERROR;
}
memset(message, 0, sizeof(ogs_nas_5gs_message_t));
memcpy(&message->gsm.h, pkbuf->data - size, size);
decoded += size;

View File

@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.2.0
* Please do not modify this file but regenerate it via script.
* Created on: 2023-03-04 20:50:00.898995 by acetcom
* Created on: 2024-01-21 18:47:47.837341 by acetcom
* from 24501-h90.docx
******************************************************************************/

View File

@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.2.0
* Please do not modify this file but regenerate it via script.
* Created on: 2023-03-04 20:50:00.874596 by acetcom
* Created on: 2024-01-21 18:47:47.812038 by acetcom
* from 24501-h90.docx
******************************************************************************/

View File

@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.2.0
* Please do not modify this file but regenerate it via script.
* Created on: 2023-03-04 20:50:00.872007 by acetcom
* Created on: 2024-01-21 18:47:47.809393 by acetcom
* from 24501-h90.docx
******************************************************************************/

View File

@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.2.0
* Please do not modify this file but regenerate it via script.
* Created on: 2023-03-04 20:50:00.882958 by acetcom
* Created on: 2024-01-21 18:47:47.820801 by acetcom
* from 24501-h90.docx
******************************************************************************/

View File

@ -732,15 +732,14 @@ f.write("""int ogs_nas_5gmm_decode(ogs_nas_5gs_message_t *message, ogs_pkbuf_t *
ogs_assert(pkbuf);
ogs_assert(pkbuf->data);
ogs_assert(pkbuf->len);
memset(message, 0, sizeof(ogs_nas_5gs_message_t));
size = sizeof(ogs_nas_5gmm_header_t);
if (ogs_pkbuf_pull(pkbuf, size) == NULL) {
ogs_error("ogs_pkbuf_pull() failed [size:%d]", (int)size);
return OGS_ERROR;
}
memset(message, 0, sizeof(ogs_nas_5gs_message_t));
memcpy(&message->gmm.h, pkbuf->data - size, size);
decoded += size;
@ -779,15 +778,14 @@ f.write("""int ogs_nas_5gsm_decode(ogs_nas_5gs_message_t *message, ogs_pkbuf_t *
ogs_assert(pkbuf);
ogs_assert(pkbuf->data);
ogs_assert(pkbuf->len);
memset(message, 0, sizeof(ogs_nas_5gs_message_t));
size = sizeof(ogs_nas_5gsm_header_t);
if (ogs_pkbuf_pull(pkbuf, size) == NULL) {
ogs_error("ogs_pkbuf_pull() failed [size:%d]", (int)size);
return OGS_ERROR;
}
memset(message, 0, sizeof(ogs_nas_5gs_message_t));
memcpy(&message->gsm.h, pkbuf->data - size, size);
decoded += size;

View File

@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2023-03-02 22:57:51.860294 by acetcom
* Created on: 2024-01-21 18:50:03.417367 by acetcom
* from 24301-h90.docx
******************************************************************************/
@ -4691,15 +4691,14 @@ int ogs_nas_emm_decode(ogs_nas_eps_message_t *message, ogs_pkbuf_t *pkbuf)
ogs_assert(pkbuf);
ogs_assert(pkbuf->data);
ogs_assert(pkbuf->len);
memset(message, 0, sizeof(ogs_nas_eps_message_t));
size = sizeof(ogs_nas_emm_header_t);
if (ogs_pkbuf_pull(pkbuf, size) == NULL) {
ogs_error("ogs_pkbuf_pull() failed [size:%d]", (int)size);
return OGS_ERROR;
}
memset(message, 0, sizeof(ogs_nas_eps_message_t));
memcpy(&message->emm.h, pkbuf->data - size, size);
decoded += size;
@ -4975,15 +4974,14 @@ int ogs_nas_esm_decode(ogs_nas_eps_message_t *message, ogs_pkbuf_t *pkbuf)
ogs_assert(pkbuf);
ogs_assert(pkbuf->data);
ogs_assert(pkbuf->len);
memset(message, 0, sizeof(ogs_nas_eps_message_t));
size = sizeof(ogs_nas_esm_header_t);
if (ogs_pkbuf_pull(pkbuf, size) == NULL) {
ogs_error("ogs_pkbuf_pull() failed [size:%d]", (int)size);
return OGS_ERROR;
}
memset(message, 0, sizeof(ogs_nas_eps_message_t));
memcpy(&message->esm.h, pkbuf->data - size, size);
decoded += size;

View File

@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2023-03-02 22:57:51.871237 by acetcom
* Created on: 2024-01-21 18:50:03.428897 by acetcom
* from 24301-h90.docx
******************************************************************************/

View File

@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2023-03-02 22:57:51.846548 by acetcom
* Created on: 2024-01-21 18:50:03.402793 by acetcom
* from 24301-h90.docx
******************************************************************************/

View File

@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2023-03-02 22:57:51.844510 by acetcom
* Created on: 2024-01-21 18:50:03.400537 by acetcom
* from 24301-h90.docx
******************************************************************************/

View File

@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2023-03-02 22:57:51.852650 by acetcom
* Created on: 2024-01-21 18:50:03.409367 by acetcom
* from 24301-h90.docx
******************************************************************************/

View File

@ -747,15 +747,14 @@ f.write("""int ogs_nas_emm_decode(ogs_nas_eps_message_t *message, ogs_pkbuf_t *p
ogs_assert(pkbuf);
ogs_assert(pkbuf->data);
ogs_assert(pkbuf->len);
memset(message, 0, sizeof(ogs_nas_eps_message_t));
size = sizeof(ogs_nas_emm_header_t);
if (ogs_pkbuf_pull(pkbuf, size) == NULL) {
ogs_error("ogs_pkbuf_pull() failed [size:%d]", (int)size);
return OGS_ERROR;
}
memset(message, 0, sizeof(ogs_nas_eps_message_t));
memcpy(&message->emm.h, pkbuf->data - size, size);
decoded += size;
@ -806,15 +805,14 @@ f.write("""int ogs_nas_esm_decode(ogs_nas_eps_message_t *message, ogs_pkbuf_t *p
ogs_assert(pkbuf);
ogs_assert(pkbuf->data);
ogs_assert(pkbuf->len);
memset(message, 0, sizeof(ogs_nas_eps_message_t));
size = sizeof(ogs_nas_esm_header_t);
if (ogs_pkbuf_pull(pkbuf, size) == NULL) {
ogs_error("ogs_pkbuf_pull() failed [size:%d]", (int)size);
return OGS_ERROR;
}
memset(message, 0, sizeof(ogs_nas_eps_message_t));
memcpy(&message->esm.h, pkbuf->data - size, size);
decoded += size;

View File

@ -50,14 +50,17 @@ int nas_eps_send_emm_to_esm(mme_ue_t *mme_ue,
int rv;
ogs_pkbuf_t *esmbuf = NULL;
ogs_assert(esm_message_container);
if (!esm_message_container->length) {
ogs_error("Invalid ESM Message Container");
return OGS_ERROR;
}
if (!mme_ue_cycle(mme_ue)) {
ogs_error("UE(mme-ue) context has already been removed");
return OGS_NOTFOUND;
}
ogs_assert(esm_message_container);
ogs_assert(esm_message_container->length);
/* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM.
* When calculating AES_CMAC, we need to use the headroom of the packet. */
esmbuf = ogs_pkbuf_alloc(NULL,