[하루한줄] CVE-2024-45064: X-CUBE-AZRTOS에서 발생한 Buffer Overflow 취약점

URL

Target

  • STMicroelectronics X-CUBE-AZRT-H7RS 1.0.0
  • STMicroelectronics X-CUBE-AZRTOS-F7 1.1.0
  • STMicroelectronics X-CUBE-AZRTOS-F4 1.1.0
  • STMicroelectronics X-CUBE-AZRTOS-G0 1.1.0
  • STMicroelectronics X-CUBE-AZRTOS-G4 2.0.0
  • STMicroelectronics X-CUBE-AZRTOS-L4 2.0.0
  • STMicroelectronics X-CUBE-AZRTOS-L5 2.0.0
  • STMicroelectronics X-CUBE-AZRTOS-WB 2.0.0
  • STMicroelectronics X-CUBE-AZRTOS-WL 2.0.0
  • STMicroelectronics X-CUBE-AZRTOS-H7 3.3.0

Explain

STMicroelectronics 사의 X-CUBE-AZRTOS 제품에서 buffer overflow 취약점이 발생했습니다.

취약점은 RAM 디스크를 설정할 때 실제 할당되는 RAM 디스크 size와 섹터 수를 검증하지 않아서 발생했습니다.

status = fx_media_format(&ram_disk,
    fx_stm32_sram_driver,                // Driver entry
                demo.ram_disk_memory,    // RAM disk memory pointer   /*[1] size 4096*/
                DataBuffer,              // Media buffer pointer
                sizeof(DataBuffer),      // Media buffer size
                "MY_RAM_DISK",                // Volume Name
                1,                            // Number of FATs
                32,                           // Directory Entries
                0,                            // Hidden sectors
                256,                          // Total sectors    /*[2]*/
                512,                          // Sector size      /*[3]*/
                8,                            // Sectors per cluster
                1,                            // Heads
                1);                           // Sectors per track

애플리케이션이 시작될 때, RAM 디스크 드라이버를 fx_media_format 함수를 통해 초기화합니다.

이때 RAM 디스크 size를 계산하면 [2] Total sectors(256) x [3] Sector size(512) = 131,072 byte이지만, 실제 할당은 [1] size 4096 byte 만큼 할당됩니다.

File: nx_web_http_server.c
4213: VOID  _nx_web_http_server_put_process(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr)
4214: {
...
4481:         /* Write the content found in this packet.  */
4482:         status =  fx_file_write(&(server_ptr -> nx_web_http_server_file), (packet_ptr -> nx_packet_prepend_ptr + offset),
4483:                                 ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) - offset));

NetXDuo HTTP 서버는 PUT 요청을 받으면, 파일 내용을 write 하기 위해 fx_file_write 함수를 호출합니다.

File: fx_stm32_sram_driver.c
81:         case FX_DRIVER_WRITE:
82:         {
83: 
84:             /* Calculate the RAM disk sector offset */
85:             destination_buffer =  (UCHAR *)FX_SRAM_DISK_BASE_ADDRESS +  // [4]
86:                                   ((media_ptr->fx_media_driver_logical_sector +  media_ptr->fx_media_hidden_sectors) * media_ptr->fx_media_bytes_per_sector);   
87: 
88:             /* Copy the source to the RAM sector.  */
89:             _fx_utility_memory_copy(media_ptr->fx_media_driver_buffer, destination_buffer,
90:                                     media_ptr->fx_media_driver_sectors * media_ptr->fx_media_bytes_per_sector); 
91: 
92:             /* Successful driver request.  */
93:             media_ptr -> fx_media_driver_status =  FX_SUCCESS;
94:             break;
95:         }

fx_file_write 함수 내부에서 fx_stm32_sram_driver.c 파일에 있는 RAM 디스크 드라이버의 FX_DRIVER_WRITE을 호출합니다.

FX_DRIVER_WRITE은 destination_buffer을 계산해 파일 데이터를 RAM 디스크에 write 합니다.

취약점은 [4] destination_buffer 주소를 계산할 때, media_ptr->fx_media_driver_logical_sector 값이 Total sectors 수(256) 만큼 증가하기 때문에 [1]에서 할당된 4096 byte를 넘어 buffer overflow 취약점이 발생합니다.

File: fx_utility_memory_copy.c
82: VOID  _fx_utility_memory_copy(UCHAR *source_ptr, UCHAR *dest_ptr, ULONG size)
83: {
84: 
85:     /* Copy the memory.  */
86:     memcpy(dest_ptr, source_ptr, size); /* Use case of memcpy is verified. */
87: }

_fx_utility_memory_copy 함수에서도 검증 없이 memcpy 함수를 사용하는 것을 확인할 수 있습니다.

Program received signal SIGTRAP, Trace/breakpoint trap.
MemManage_Handler () at ../Core/Src/stm32f7xx_it.c:102
102	{
bt
#0  MemManage_Handler () at ../Core/Src/stm32f7xx_it.c:102
#1  <signal handler called>
#2  0x41414140 in ?? ()
#3  0x0802662e in webserver_request_notify_callback (server_ptr=0x20004330 <HTTPServer>, request_type=1, resource=0x2000433c <HTTPServer+12> "/test.txt", packet_ptr=0x20064558 <nx_byte_pool_buffer+9560>) at ../NetXDuo/App/app_netxduo.c:477
#4  0x08012158 in _nx_web_http_server_get_process (server_ptr=0x20004330 <HTTPServer>, request_type=1, packet_ptr=0x20064558 <nx_byte_pool_buffer+9560>) at ../Middlewares/ST/netxduo/addons/web/nx_web_http_server.c:3778
#5  0x08011a08 in _nx_web_http_server_receive_data (tcpserver_ptr=0x20004578 <HTTPServer+584>, session_ptr=0x200047e4 <HTTPServer+1204>) at ../Middlewares/ST/netxduo/addons/web/nx_web_http_server.c:3128
#6  0x080110b2 in _nx_tcpserver_data_process (server_ptr=0x20004578 <HTTPServer+584>) at ../Middlewares/ST/netxduo/addons/web/nx_tcpserver.c:1048
#7  0x08011284 in _nx_tcpserver_thread_entry (tcpserver_address=536888696) at ../Middlewares/ST/netxduo/addons/web/nx_tcpserver.c:1307
#8  0x08023ff4 in _tx_thread_shell_entry () at ../Middlewares/ST/threadx/common/src/tx_thread_shell_entry.c:114
#9  <signal handler called>
i r
r0             0x2d                45
r1             0x8028742           134383426
r2             0x74                116
r3             0x41414141          1094795585
r4             0x200781e4          537362916
r5             0x0                 0
r6             0x0                 0
r7             0x200781d8          537362904
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x0                 0
r12            0x80000000          -2147483648
sp             0x2007ffc8          0x2007ffc8
lr             0xfffffffd          -3
pc             0x80011f0           0x80011f0 <MemManage_Handler>
xpsr           0x21000004          553648132
fpscr          0x0                 0
msp            0x2007ffc8          0x2007ffc8
psp            0x20078198          0x20078198 <nx_byte_pool_buffer+90520>
primask        0x0                 0
basepri        0x0                 0
faultmask      0x0                 0
control        0x0                 0

따라서, 공격자는 많은 put 요청을 통해 섹터 수를 증가시켜 buffer overflow 취약점을 트리거 할 수 있습니다.