[하루한줄] CVE-2025-30216: CryptoLib의 Heap Buffer Overflow 취약점
URL
https://github.com/nasa/CryptoLib/security/advisories/GHSA-v3jc-5j74-hcjv
https://securityonline.info/cryptolib-vulnerability-heap-overflow-threatens-space-communications/
Target
- CryptoLib <= 1.3.3
Explain
항공우주 분야에서 사용되는 NASA의 오픈소스 라이브러리인 CryptoLib에서 발견된 취약점 CVE-2025-30216의 세부 정보가 공개되었습니다.
취약점은 CryptoLib이 TM 프로토콜 패킷을 파싱하는 과정에서 호출하는 src/core/crypto_tm.c
의 Crypto_TM_ProcessSecurity()
함수에 존재합니다.
TM 프로토콜(Telemetry Space Data Link Protocol) 은 우주선과 지상국 간 통신에 사용되는 CCSDS(Cosultative Committee for Space Data Systems) 프로토콜의 하위 데이터링크 계층 프로토콜로, 단일 우주 링크를 통해 데이터를 전송하는 기능을 제공함.
int32_t Crypto_TM_ProcessSecurity(uint8_t *p_ingest, uint16_t len_ingest, uint8_t **pp_processed_frame,
uint16_t *p_decrypted_length)
{
//...
status = Crypto_TM_Process_Setup(len_ingest, &byte_idx, p_ingest, &secondary_hdr_len);
//...
if (status == CRYPTO_LIB_SUCCESS)
{
// Allocate buffer
p_new_dec_frame = (uint8_t*)calloc(1, (len_ingest) * sizeof(uint8_t));
//..
}
if (status == CRYPTO_LIB_SUCCESS)
{
// Copy over TM Primary Header (6 bytes),Secondary (if present)
// If present, the TF Secondary Header will follow the TF PriHdr
memcpy(p_new_dec_frame, &p_ingest[0], 6 + secondary_hdr_len);
//..
}
해당 함수는 TM 프로토콜 패킷 파싱 시 총 패킷 길이인 len_ingest
만큼의 힙 버퍼 p_new_dec_frame
를 할당합니다.
이후 패킷 데이터를 p_new_dec_frame
버퍼로 복사하는데, 이때 복사할 크기는 6 bytes로 고정된 TM Primary Header와 가변 크기인 TF Secondary Header를 더해 계산됩니다. 이때 계산 결과가 p_new_dec_frame
버퍼 크기보다 큰지 검증하지 않아 Heap Buffer Overflow가 발생할 수 있습니다.
TF Secondary Header 크기인 secondary_hdr_len
은 Crypto_TM_Process_Setup()
함수에서 결정됩니다.
int32_t Crypto_TM_Process_Setup(uint16_t len_ingest, uint16_t *byte_idx, uint8_t *p_ingest, uint8_t *secondary_hdr_len)
{
// ...
if (status == CRYPTO_LIB_SUCCESS)
{
// Secondary Header flag is 1st bit of 5th byte (index 4)
*byte_idx = 4;
if ((p_ingest[*byte_idx] & 0x80) == 0x80)
{
#ifdef TM_DEBUG
printf(KYEL "A TM Secondary Header flag is set!\n");
#endif
// Secondary header is present
*byte_idx = 6;
// Determine length of secondary header
// Length coded as total length of secondary header - 1
// Reference CCSDS 132.0-B-2 4.1.3.2.3
*secondary_hdr_len = (p_ingest[*byte_idx] & 0x3F) + 1;
#ifdef TM_DEBUG
printf(KYEL "Secondary Header Length is decoded as: %d\n", *secondary_hdr_len);
#endif
// Increment from current byte (1st byte of secondary header),
// to where the SPI would start
*byte_idx += *secondary_hdr_len;
}
else
{
// No Secondary header, carry on as usual and increment to SPI start
*byte_idx = 6;
}
}
secondary_hdr_len
은 (p_ingest[*byte_idx] & 0x3F) + 1;
계산식을 통해 최대 크기를 0x3F+1 (64 bytes) 으로 제한하지만, 여전히 len_ingest
와 관련된 검사가 존재하지 않습니다.
따라서 len_ingest
가 6 + secondary_hdr_len
보다 작은 경우 복사 과정에서 p_new_dec_frame
버퍼에서 buffer overflow가 트리거됩니다.
해당 취약점이 악용될 경우 Denial of Service 공격을 통해 우주선과 지상국 간 통신 장애를 발생시키거나, RCE exploit을 통해 패킷을 수신한 우주선 또는 지상국 시스템을 제어할 수 있습니다.
if (status == CRYPTO_LIB_SUCCESS)
{
// Secondary Header flag is 1st bit of 5th byte (index 4)
*byte_idx = 4;
if ((p_ingest[*byte_idx] & 0x80) == 0x80)
{
#ifdef TM_DEBUG
printf(KYEL "A TM Secondary Header flag is set!\n");
#endif
// Secondary header is present
*byte_idx = 6;
// Determine length of secondary header
// Length coded as total length of secondary header - 1
// Reference CCSDS 132.0-B-2 4.1.3.2.3
*secondary_hdr_len = (p_ingest[*byte_idx] & 0x3F) + 1;
#ifdef TM_DEBUG
printf(KYEL "Secondary Header Length is decoded as: %d\n", *secondary_hdr_len);
#endif
// We have a secondary header length now, is it sane?
// Does it violate spec maximum?
// Reference CCSDS 1320b3 4.1.3.1.3
// TODO: Add a test
if (*secondary_hdr_len > TM_SECONDARY_HDR_MAX_VALUE)
{
status = CRYPTO_LIB_ERR_TM_SECONDARY_HDR_SIZE;
mc_if->mc_log(status);
return status;
}
// Does it 'fit' in the overall frame correctly?
// We can't validate it down to the byte yet,
// we don't know the variable lengths from the SA yet
// Protects from overruns on very short max frame sizes
// Smallest frame here is Header | Secondary Header | SPI | 1 byte data
// TODO: Add a test
if (len_ingest < (*byte_idx + *secondary_hdr_len + SPI_LEN + 1))
{
status = CRYPTO_LIB_ERR_TM_SECONDARY_HDR_SIZE;
mc_if->mc_log(status);
return status;
}
// Increment from current byte (1st byte of secondary header),
// to where the SPI would start
*byte_idx += *secondary_hdr_len;
@@ -1286,6 +1309,7 @@
// No Secondary header, carry on as usual and increment to SPI start
*byte_idx = 6;
}
}
https://github.com/nasa/CryptoLib/commit/4328a713c4a405a3271cf115e8e7bebfeeba3b95?diff=split
취약점의 패치는 len_ingest < (*byte_idx + *secondary_hdr_len + SPI_LEN + 1)
조건식을 추가해 len_ingest
보다 크면 CRYPTO_LIB_ERR_TM_SECONDARY_HDR_SIZE
에러를 발생시키는 것으로 이루어졌습니다.
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.