Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/icicle-emu/icicle
Embedded Systems SecurityDynamic Analysis (Sandboxing)Vulnerability AnalysisFuzzingBinary AnalysisFirmware Analysis
GitHubicicle-emu/icicle

icicle

에뮬레이션 기반 MSP430 펌웨어 퍼저로, 메모리 손상 버그를 찾아 분석하고 상세한 크래시 리포트와 재현 가능한 입력을 제공합니다.

저장소 보기
1921442년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

MSP430 크래시 분석

Icicle이 MSP430 바이너리에서 발견한 크래시.

#Target설명
I03Goodwatchdmesg_buffer에 쓸 때의 잘못된 비교
I04Goodwatch길이가 0인 메시지
I05GoodwatchRNG 오버플로
I06Goodwatchook keypress에서 범위를 벗어난 액세스
I07Goodwatch스톱워치에서 범위를 벗어난 액세스
I08Goodwatch요일(DOW) 표시 시 범위를 벗어난 액세스
I09GoodwatchHex viewer 애플리케이션
I10GoodwatchPEEK/POKE 모니터 명령
I11H4_PacketProtocolGet Descriptor의 검사되지 않은 인터페이스 인덱스
I12H4_PacketProtocolSet Report의 버퍼 오버플로

Goodwatch

I03: dmesg buffer에 쓸 때의 잘못된 비교

  • putchar의 off-by-one 오류로 인해 0x2c00에서 1바이트 OOB 쓰기가 발생합니다.
  • 참고: 퍼징 중에는 이 버그가 트리거되지 않도록 버퍼가 포함된 메모리 영역의 크기를 늘려 회피합니다.

크래시 시 호출 스택 예시:

root@kitploit:~
UnhandledException(code=WriteUnmapped, value=0x2c00):
0x000000c81a: putchar+0x1c
0x000000c832: dmesg_putc+0x6
0x0000009706: tfp_format+0x22
0x000000ad9c: tfp_printf+0x12
0x000000b924: key_scan.part.0+0x68
0x000000cd3c: PORT2_ISR+0x1a
0x0000008e04: <unknown>

I04: 길이가 0인 메시지

  • 길이 필드가 0으로 설정된 메시지가 UART 인터페이스로 전송되면 잘못 처리됩니다. MSG 상태에서는 방금 수신한 바이트를 uart_buffer의 현재 index에 저장한 후 index를 증가시키고 그 값이 length와 같은지 확인합니다. 그러나 index의 저장과 증가가 length와의 비교보다 먼저 수행되므로, 길이가 0인 메시지의 경우 index == length 조건이 결코 참이 될 수 없습니다.

  • 결국 index가 uart_buffer 배열을 초과하게 되어 uart_buffer 뒤에 저장된 전역 변수를 수정할 수 있게 됩니다. 이로 인해 일반적으로 stdout_putf 또는 stdout_putp 함수 포인터가 덮어써지고 디버그 메시지가 출력될 때 프로그램이 충돌합니다.

크래시 입력:

root@kitploit:~
./run_goodwatch.sh I04a

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=InvalidInstruction)
0x000000d3d3: <unknown>
0x0000009648: putchw+0x40
0x0000009826: tfp_format+0x142
0x000000ad9c: tfp_printf+0x12
0x000000b924: key_scan.part.0+0x68
0x000000cd3c: PORT2_ISR+0x1a
0x0000008e04: <unknown>
  • 프로그램이 충돌하는 또 다른 경로는 appindex(또는 subindex)가 덮어써져서 다음에 appindex를 사용해 applet이 로드될 때(예: app_draw에서) 크래시가 발생하는 것입니다.

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=InvalidInstruction)
0x000000531c: <unknown>
0x0000009a96: app_init+0xe
0x000000c0a8: settime_draw+0x28
0x0000009b0a: app_draw+0x3e
0x000000ce78: watchdog_timer+0x6a
0x0000008e04: <unknown>

I05: RNG 오버플로:

  • RANDINT 모니터 명령은 펌웨어가 난수 목록을 생성하여 전송하도록 합니다. 그러나 생성할 난수 값의 개수는 수신된 명령에 의해 제어됩니다. 생성할 값의 개수가 너무 많으면 rints가 스택에 예약된 공간을 초과하여 OOB 쓰기가 발생합니다.

크래시 입력:

root@kitploit:~
./run_goodwatch.sh I05

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=WriteUnmapped, value=0x6e6a)
0x000000cbd4: USCI_A0_ISR+0x24c (inlined `send_randint`)
0x0000008e04: <unknown>

I06: ook keypress에서 범위를 벗어난 액세스:

  • OOK 애플리케이션은 숫자 키(0-9) 중 하나가 눌리면 button_array에서 사전 구성된 OOK 패킷을 전송합니다. 그러나 ook_keypress는 눌린 키가 button_array 배열의 범위 내에 있는지 검증하지 않습니다. 숫자 버튼은 10개(0-9)이지만 button_array에는 9개의 항목만 들어 있습니다.

  • button_array에는 포인터 배열이 들어 있습니다. OOK 애플리케이션에서 9 버튼을 누르면 프로그램의 setrate 함수가 button_array의 범위를 벗어난 포인터를 읽어 역참조하므로 프로그램이 충돌합니다.

  • 이때 읽는 포인터는 ook_settings(0x3012)의 첫 번째 값이며, 이는 메모리에 존재하지 않습니다.

크래시 입력:

root@kitploit:~
./run_goodwatch.sh I06

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=ReadUnmapped, value=0x3012)
0x000000b87a: ook_keypress+0x2c
0x000000cd7e: PORT2_ISR+0x5c
0x0000008e04: <unknown>

I07: 스톱워치 60시간 후 범위를 벗어난 액세스:

  • 펌웨어는 룩업 테이블을 사용하여 정수를 2진화 10진수(BCD)로 변환합니다. 그러나 룩업 테이블(bcdtable)에는 0에서 59까지의 정수 변환 값만 들어 있습니다. 초와 분은 카운트할 때 60에서 순환하므로 문제가 없지만, hour 변수는 60을 초과할 수 있어 인덱스가 범위를 벗어나게 됩니다.

  • 이 버그는 길이가 0인 메시지(Zero length message) 버그로 인한 메모리 손상의 부수 효과로 퍼저에 의해서만 발견되었습니다. 퍼저가 발견한 크래시에서는 uart_buffer가 오버플로될 때 min 및 hour 전역 변수가 모두 손상됩니다.

크래시 입력:

root@kitploit:~
./run_goodwatch.sh I07

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=ReadUnmapped, value=0x4b57)
0x000000a3e4: stopwatch_draw+0x9e
0x0000009b0a: app_draw+0x3e
0x000000ce78: watchdog_timer+0x6a
0x0000008e04: <unknown>

I08: 요일 표시 시 범위를 벗어난 액세스:

  • 퍼저가 RTCDOW 주변 장치에 큰 값을 생성하여 발생하는 오탐(false positive) 버그입니다.

  • 시계 애플리케이션에서 9 버튼을 누르면 LCD에 현재 요일을 그리려고 시도합니다. 요일은 RTC 주변 장치의 RTCDOW 레지스터에서 직접 읽습니다. 이 레지스터의 데이터시트에 따르면 반환 값은 0-6 사이로 지정되어 있지만, 퍼징 중에는 이 레지스터의 값에 제약이 없습니다. 이 값은 dayofweek 배열의 인덱스로 사용되므로, 퍼저가 RTCDOW 레지스터에 6보다 큰 값을 생성하면 프로그램이 daysofweek 배열 밖의 포인터를 읽어 (오탐) 크래시가 발생합니다.

  • 이 크래시는 clock_keypress와 hebrew_keypress 모두에서 발생할 수 있습니다.

크래시 입력:

root@kitploit:~
./run_goodwatch.sh I08a

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=ReadUnmapped, value=0x5150)
0x0000009e6e: lcd_string+0x8
0x000000c1dc: clock_keypress+0x6c
0x000000cd7e: PORT2_ISR+0x5c
0x0000008e04: <unknown>

크래시 입력:

root@kitploit:~
./run_goodwatch.sh I08b

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=ReadPerm, value=0x1006)
0x0000009e6e: lcd_string+0x8
0x000000b2aa: hebrew_keypress+0x116
0x000000c48c: clock_keypress+0x31c
0x000000cd7e: PORT2_ISR+0x5c
0x0000008e04: <unknown>

I09: Hex viewer 애플리케이션:

  • Hex Viewer 애플리케이션은 사용자가 제어하는 주소부터 메모리를 볼 수 있게 해줍니다. Hex Viewer를 매핑되지 않은 주소로 이동시키면 에뮬레이터가 크래시를 보고합니다.

크래시 입력:

root@kitploit:~
./run_goodwatch.sh I09

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=ReadUnmapped, value=0x7000)
0x0000009c74: hex_draw.part.0+0x3c
0x0000009c88: hex_draw+0x8
0x0000009b0a: app_draw+0x3e
0x000000cd8c: PORT2_ISR+0x6a
0x0000008e04: <unknown>

I10: PEEK 및 POKE 모니터 명령:

  • 모니터의 PEEK/POKE 명령은 각각 임의의 메모리에 대한 읽기/쓰기를 허용합니다. 그러나 이 동작은 버그가 아닌 의도된 기능입니다(모니터 인터페이스는 디버깅용으로 설계되었기 때문입니다).

PEEK에 대한 크래시 입력:

root@kitploit:~
./run_goodwatch.sh I10a

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=ReadUnmapped, value=0x5100)
0x000000cb00: USCI_A0_ISR+0x178
0x0000008e04: <unknown>

POKE에 대한 크래시 입력:

root@kitploit:~
./run_goodwatch.sh I10b

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=WritePerm, value=0x4b00)
0x000000cb32: USCI_A0_ISR+0x1aa
0x0000008e04: <unknown>

H4_PacketParser

I11: Get Descriptor의 검사되지 않은 인터페이스 인덱스:

  • 여러 Get_Descriptor 핸들러에서 인터페이스 인덱스가 검사되지 않습니다. 이로 인해 범위를 벗어난 액세스가 발생할 수 있습니다. 예를 들어:

GetHidDescriptor:

root@kitploit:~
./run_H4_PacketProtocol.sh I11a

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=ReadUninitialized, value=0xe90e)
0x0000011176: usbSendNextPacketOnIEP0 at ./USB_API/USB_Common/usb.c:1082.13
0x0000011c12: usbGetHidDescriptor at ./USB_API/USB_HID_API/UsbHidReq.c:78.5
0x0000010fb0: usbDecodeAndProcessUsbRequest at ./USB_API/USB_Common/usb.c:1655.5
0x0000011724: SetupPacketInterruptHandler at ./USB_config/UsbIsr.c:250.5
0x0000004410: iUsbInterruptHandler at ./USB_config/UsbIsr.c:88.9
0x0000004572: _c_int00_noargs

GetReportDescriptor:

root@kitploit:~
./run_H4_PacketProtocol.sh I11b

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=ReadUninitialized, value=0xa44c)
0x0000011c28: usbGetReportDescriptor at ./USB_API/USB_HID_API/UsbHidReq.c:85.5
0x0000010fb0: usbDecodeAndProcessUsbRequest at ./USB_API/USB_Common/usb.c:1655.5
0x0000011724: SetupPacketInterruptHandler at ./USB_config/UsbIsr.c:250.5
0x00000044fe: iUsbInterruptHandler at ./USB_config/UsbIsr.c:166.9
0x0000004572: _c_int00_noargs

I12: Set Report의 버퍼 오버플로:

  • Set_Report 패킷을 수신한 후 펌웨어는 리포트를 저장할 버퍼를 pbOEP0Buffer에 할당하고, 리포트의 길이를 wBytesRemainingOnOEP0에 할당합니다. 그러나 펌웨어는 리포트가 할당된 버퍼에 들어맞는지 확인하지 않으므로, 이후 usbReceiveNextPacketOnOEP0에서 버퍼에 쓰기를 수행할 때 버퍼 오버플로가 발생합니다.

아래의 크래시 입력에서는 8바이트 배열(0x24a4: abUsbRequestIncomingData)의 주소가 pbOEP0Buffer에 할당됩니다. 배열이 오버플로된 후 함수 포인터(0x24b4: USB_RX_memcpy)가 손상되어, 나중에 해당 함수 포인터가 호출될 때 크래시가 발생합니다.

root@kitploit:~
./run_H4_PacketProtocol.sh I12

크래시 시 호출 스택:

root@kitploit:~
UnhandledException(code=InvalidInstruction, value=0xf95b7)
0x00000f95b7: <unknown>
0x0000011066: HidCopyUsbToBuff at ./USB_API/USB_HID_API/UsbHid.c:417.5
0x0000010172: USBHID_receiveData at ./USB_API/USB_HID_API/UsbHid.c:577.13
0x000001026a: main at ./main.c:115.25
0x0000004572: _c_int00_noargs
도구 다운로드