Mark MagerEric Forte

지평선 위의 폭풍우: AJCloud IoT 에코시스템의 내부

Wi-Fi 카메라는 저렴한 가격과 편리함 때문에 인기가 많지만, 종종 보안 취약점이 있어 악용될 수 있습니다.

27분 읽기보안 연구, 관점
위기의 전조: AJCloud IoT 생태계를 들여다보다

서문

Wi-Fi 카메라는 가정, 기업 및 기타 공공장소에서 가장 흔히 볼 수 있는 IoT 디바이스 중 하나입니다. 가격이 매우 저렴하고 사용자가 전 세계 어디에서나 모바일 디바이스로 실시간 동영상 스트림에 쉽게 액세스할 수 있습니다. IoT 기기의 경우 종종 그렇듯이, 이러한 카메라에서는 보안이 간과되는 경향이 있어 심각한 취약점에 노출되는 경우가 많습니다. 이러한 취약점이 악용될 경우 카메라와 카메라가 배포된 네트워크에 치명적인 영향을 미칠 수 있습니다. 사용자의 민감한 PII가 유출될 수 있습니다.

최근 Elastic ON Week를 통해 이러한 유형의 기기의 공격 표면을 탐색하여 어떻게 침해되고 있는지에 대해 더 깊이 이해할 수 있는 기회를 가졌습니다. 저희는 주로 아마존에서 판매되는 가장 인기 있고 저렴한 카메라 중 하나인 Wansview Q5 (거의 동일한 Q6와 함께)에 대한 취약성 조사를 수행하는 데 중점을 두었습니다. Wansview는 중국 심천에 본사를 둔 보안 제품 공급업체로, 아마존에서 가장 유명한 Wi-Fi 카메라 유통업체 중 하나입니다.

Q5는 대부분의 카메라에서 볼 수 있는 기본 기능 세트를 제공합니다:

  • 팬/틸트/줌
  • 야간 투시
  • 양방향 오디오
  • SD 카드에 동영상 녹화
  • 스마트 홈 AI 어시스턴트와 통합(예 알렉사)
  • 다른 보안 제품과의 상호 운용성을 위한 ONVIF
  • LAN 내에서 비디오 피드에 직접 액세스하기 위한 RTSP
  • 클라우드에서 자동 펌웨어 업데이트
  • 원격 기술 지원
  • 다른 계정과 디바이스 액세스 공유
  • 클라우드 스토리지 및 모션 감지를 위한 월별 구독 옵션

대부분의 다른 Wi-Fi 카메라와 마찬가지로 이러한 모델은 기본 작동을 위해 공급업체 클라우드 인프라에 활성 연결이 필요하며, 인터넷에 액세스하지 않으면 작동하지 않습니다. 카메라를 사용하려면 먼저 Wansview의 공식 모바일 앱을 통해 등록된 사용자 계정과 페어링하고 표준 QR코드 기반 설정 프로세스를 거쳐야 합니다. 이 프로세스가 완료되면 카메라가 완전히 온라인 상태가 되어 작동합니다.

AJCloud: 간단한 소개

완스뷰는 2009년부터 운영되어 왔지만, 현재는 주로 중국 난징에 위치한 별도의 회사에서 만든 카메라 제품의 리셀러로 보입니다: AJCloud.

AJCloud는 공급업체에게 제조된 보안 장치, 필요한 펌웨어, 모바일 및 데스크톱 사용자 애플리케이션, 클라우드 관리 플랫폼, 모든 것을 연결하는 서비스에 대한 액세스를 제공합니다. 2018년에 설립된 이후 AJCloud는 다음과 같은 크고 작은 여러 공급업체와 파트너십을 맺었습니다:

구글 플레이, 애플의 앱 스토어, 마이크로소프트 스토어에서 AJ클라우드가 개발 및 게시한 모바일 및 데스크톱 애플리케이션을 살펴보면 각 공급업체와의 관계를 알 수 있습니다. 이러한 애플리케이션은 표면적인 회사 브랜딩 외에도 형태와 기능이 동일하며 모두 AJCloud 관리 플랫폼과의 연결이 필요합니다.

카메라의 경우, 이러한 공급업체는 카메라 하우징과 기본 하드웨어를 약간만 수정한 유사한 모델을 판매하고 있는 것으로 보입니다.

Faleemi 886과 Wansview Q6 (1080p )의 유사점은 분명합니다.

하드웨어 제조 및 소프트웨어 개발 리소스를 재사용하면 AJCloud와 리셀러의 비용을 관리하고 물류를 간소화하는 데 도움이 될 것입니다. 하지만 이렇게 자산을 간소화하면 한 카메라 모델에서 발견된 보안 취약점이 AJCloud와 관련된 모든 제품에 스며들 수 있습니다.

이러한 디바이스를 소비자에게 제공하는 데 중요한 역할을 하고 있음에도 불구하고 AJCloud는 상대적으로 대중의 인지도가 낮습니다. 하지만 최근 IPVM 연구원들이 AJCloud의 GitLab 리포지토리에서 중요한 취약점(현재는 해결됨)에 대한 연구를 발표했습니다. 이 취약점으로 인해 모든 사용자가 인증 없이 소스 코드, 자격 증명, 인증서 및 기타 민감한 데이터에 액세스할 수 있습니다.

Wansview와 Wi-Fi 카메라 분야의 다른 공급업체에 대한 총 판매 수치를 도출하기는 어렵지만, IPVM은 보고서 발행 시점에 최소 100만 대의 디바이스가 AJCloud 플랫폼에 연결된 것으로 추정했습니다. 카메라 판매량이 수억 대로 급증함에 따라 앞으로 몇 년 동안 전 세계 가정에서 더 많은 AJCloud의 디바이스가 연결될 것으로 예상할 수 있습니다.

초기 취약점 연구 노력

Wansview Q5의 보안 상태를 심층적으로 파악하기 위해 다양한 각도에서 분석했습니다:

처음에는 주로 카메라의 능동 및 수동 네트워크 정찰과 Wansview의 공식 모바일 앱인 Wansview Cloud의 안드로이드 버전에 집중했습니다. 열린 포트를 검색하고, 중간자(MitM) 공격을 통해 네트워크 통신을 도청하고, 앱의 의도적인 잘못된 구성을 통해 카메라에서 예측할 수 없는 동작을 강요하고, QR코드 형식을 악용하고 카메라와 물리적으로 상호작용하여 카메라의 작동을 방해했습니다. 디바이스와 인프라는 이러한 유형의 표면 공격에 놀라울 정도로 탄력적이었으며, 초기에는 주목할 만한 성공을 거두지 못했습니다.

특히 카메라와 앱 모두에서 네트워크 통신을 가로채는 데 성공하지 못했다는 사실에 놀랐습니다. 강력한 보안 기능(예: 인증서 고정, 앱 및 OS 버전 제한, 적절하게 보안된 TLS 연결)으로 인해 시도를 방해하는 문제가 반복적으로 발생했습니다.

리버스 엔지니어링 도구를 사용하면 APK를 훨씬 더 면밀히 분석할 수 있었지만, 디컴파일된 Java 소스 코드에서 관찰된 코드 난독화의 복잡성으로 인해 완전히 파악하는 데 오랜 시간이 필요했습니다.

초기 성공이 제한적이었기 때문에 Q5와 그 작동 방식에 대해 더 미묘한 통찰력을 제공할 수 있는 추가 옵션을 모색해야 했습니다.

초기 하드웨어 해킹

카메라의 작동 방식에 대한 더 많은 인사이트를 얻기 위해 카메라 펌웨어를 자세히 살펴보기로 했습니다. 일부 펌웨어 패키지는 온라인으로 제공되지만, 저희는 코드를 직접 살펴보고 카메라가 작동하는 동안 코드와 그 결과 로그를 모니터링할 수 있기를 원했습니다. 이를 위해 먼저 시스템 온 칩(SoC)의 하드웨어 다이어그램을 살펴보고 활용할 수 있는 하드웨어 수단이 있는지 확인했습니다. Wansview Q5의 시스템 블록 다이어그램은 아래와 같으며, Ingenic Xburst T31 SoC를 사용합니다.

그 중 눈에 띄는 것은 I2Cx3/UARTx2/SPIx2 SPI I/O 블록이었습니다. 액세스할 수 있는 경우 이러한 I/O 블록은 로그 출력 인터페이스 및/또는 셸 인터페이스를 제공하여 디버깅 및 SoC와의 상호 작용에 사용할 수 있습니다. 유망해 보이는 카메라의 하드웨어를 분해한 결과, 아래와 같이 SoC에 대한 UART 직렬 인터페이스로 보이는 것을 발견했습니다.

다음으로 로직 분석기를 연결하여 이 핀을 통해 어떤 프로토콜이 사용되고 있는지 확인했고, 디코딩 결과 신호는 실제로 UART였습니다.

이제 노출된 UART 인터페이스에 액세스할 수 있으므로 UART를 통해 SoC에 셸 연결을 설정하려고 했습니다. 이를 위한 다양한 소프트웨어 메커니즘이 있지만, 저희는 로직 분석기에서 감지된 전송 속도를 사용하여 Unix 유틸리티( screen )를 사용했습니다.

부팅 시퀀스를 열고 모니터링한 결과, 보안 부팅이 SoC에서 지원됨에도 불구하고 활성화되지 않은 것을 발견했습니다. 그런 다음 아래와 같이 초기화 프로세스가 수행되기 전에 펌웨어를 검사하는 데 사용할 루트 셸을 제공하는 단일 사용자 모드로 부팅하도록 구성을 수정했습니다.

단일 사용자 모드에서 아래 그림과 같이 binwalk 유틸리티를 사용하여 정적 분석을 위해 펌웨어 파일을 가져올 수 있었습니다.

이 단계에서 파일 시스템은 일반적으로 읽기 전용이지만, 필요에 따라 펌웨어 초기화의 특정 부분만 편집하고 인스턴스화할 수 있기를 원했기 때문에 단일 사용자 모드 액세스 외에 추가적인 지속성을 위해 몇 가지 빠른 설정을 수행했습니다. 이 작업은 여러 가지 방법으로 수행할 수 있지만 크게 두 가지 방법을 사용할 수 있습니다. 일반적으로 두 가지 접근 방식 모두 기존 구성을 가능한 한 적게 수정하는 것이 좋습니다. 런타임 환경에 미치는 영향이 가장 적기 때문에 일반적으로 동적 분석을 실행할 때는 가능하면 이 방법을 선호합니다. 이 접근 방식에 사용한 방법 중 하나는 메모리에 읽기/쓰기 액세스를 위한 tmpfs 파티션을 만들고 fstab 을 통해 마운트하는 것입니다. 저희의 경우 fstab 이미 이를 지원하는 방식으로 고려하고 있었기 때문에 변경을 최소화했습니다. 아래에서 이 접근 방식에 대한 명령과 결과를 확인하세요.

또 다른 방법은 기존 사용자 자격 증명을 가져와 이를 사용하여 로그인을 시도하는 것입니다. 이 접근 방식도 성공적이었습니다. 루트 사용자의 비밀번호 해시는 etc/passwd 파일에서 찾을 수 있으며, 존 더 리퍼와 같은 도구를 사용하여 해독할 수 있습니다. 위의 예에서는 전적으로 직렬 연결을 통해 데이터와 파일을 전송했습니다. 카메라에는 파일을 마운트하고 전송하는 데 사용할 수 있는 SD 카드 슬롯도 있습니다. 앞으로는 대역폭이 더 빠르고 쉽게 전송할 수 있는 SD 카드 또는 로컬 네트워크를 파일 이동에 사용할 예정이지만, 원하는 경우 하드웨어 설정 및 디버깅을 위한 모든 통신에는 직렬을 계속 사용할 수 있습니다.

이제 소프트웨어가 실행되는 동안 카메라에 루트 레벨로 액세스하여 펌웨어 및 dmesg 로그에 액세스할 수 있습니다. 그런 다음 펌웨어와 로그를 모두 참고하여 카메라의 사용자 인터페이스를 자세히 살펴보고 추가 인사이트를 얻기 위해 사용할 수 있는 좋은 진입점이 있는지 살펴봤습니다.

Windows용 Wansview 클라우드

모바일 앱이 당초 예상했던 것보다 더 안전한 것으로 판명된 후, 저희는 Windows 7용으로 구축된 이전 버전의 Wansview Cloud 애플리케이션으로 초점을 전환했습니다. 아직 다운로드할 수 있는 이 앱을 사용하면 AJCloud 플랫폼에 연결된 카메라와 관련된 네트워크 통신에 대한 직접적인 통찰력을 얻을 수 있습니다.

개발자의 과도한 디버그 로깅 덕분에 Windows 앱은 상용 소프트웨어에서는 거의 볼 수 없는 무모한 방식으로 비밀을 유출하고 있습니다. 문제가 있다는 첫 번째 징후는 사용자 로그인 자격 증명이 일반 텍스트로 로그인되어 있다는 것입니다.

고유 문자열이 포함된 장황한 로그 메시지를 자주 사용했기 때문에 메인 실행 파일과 DLL(Wansview Cloud APK와 달리 패킹되지 않음)을 리버스 엔지니어링하는 것이 빨라졌습니다. 기본 코드베이스 내의 특정 파일과 줄에 대한 참조를 식별하면 애플리케이션의 핵심 구성 요소를 신속하게 매핑하고 높은 수준의 제어 흐름을 설정하는 데 도움이 되었습니다.

Android에서 가로채기 어려웠던 네트워크 통신은 여전히 TLS를 통해 전송되지만, 클리어텍스트로 디스크에 편리하게 기록됩니다. 모든 HTTP POST 요청 및 응답 데이터(JSON 객체로 패킹된)에 대한 전체 액세스 권한이 있으므로 애플리케이션 측에서 더 이상 MitM 공격을 추구할 필요가 없습니다.

POST 응답에서 카메라의 위치, 네트워크 구성, 펌웨어 버전에 대한 정보와 함께 공개적으로 액세스할 수 있는 화면 캡처 링크 등 민감한 메타데이터를 발견했습니다.

로그 데이터에서 발견된 모든 POST 요청과 응답을 문서화한 후, 카메라나 계정과 관련이 없는 데이터에 액세스하기 위해 각 요청에서 서로 다른 필드를 조작하는 실험을 시작했습니다. 결국 디버거를 사용하여 현재 로그인한 계정과 페어링되지 않은 대상 카메라의 디바이스아이디로 변경합니다. 카메라 디바이스아이디는 일련번호로도 사용되며 카메라 뒷면이나 하단에 있는 스티커 라벨에 인쇄되어 있습니다.

저희는 https://sdc-us.ajcloud.net/api/v1/dev-config 으로의 POST 요청에서 deviceId가 처음 전송되는 코드 섹션에서 공격에 가장 적합한 타겟을 찾았습니다:

저희의 계획은 위 스크린샷에 강조 표시된 명령어에 중단점을 설정하고 메모리 내에서 deviceId를 교체한 다음 앱이 실행을 재개하도록 허용하는 것이었습니다.

놀랍게도 이 순진한 접근 방식은 대상 카메라와 연결된 계정과 관련된 AJCloud 플랫폼에 저장된 민감한 데이터를 검색하는 데 성공했을 뿐만 아니라 카메라 자체에도 연결되었습니다. 이를 통해 비디오 및 오디오 스트림에 액세스하고 앱을 통해 마치 자신의 카메라처럼 원격으로 제어할 수 있었습니다.

이 취약점을 악용하고 다양한 공급업체의 여러 모델을 대상으로 테스트한 결과, AJCloud 플랫폼에 연결된 모든 디바이스가 이러한 방식으로 원격으로 액세스 및 제어될 수 있음을 확인했습니다. 저희는 이 프로세스를 자동화하고 AJCloud 인프라 내의 액세스 제어 취약점이 얼마나 쉽게 악용될 수 있는지 효과적으로 보여주기 위해 PoC 익스플로잇 스크립트를 작성했습니다.

네트워크 통신 살펴보기

AJCloud 플랫폼의 중요한 취약점에 대한 익스플로잇을 구축하고 안정적으로 트리거할 수 있었지만 앱, 카메라 펌웨어 및 클라우드 인프라의 내부 작동을 더 잘 이해하려면 더 자세히 조사해야 합니다.

로그인 프로세스 전반에 걸쳐 관찰된 POST 요청과 응답을 넘어 다양한 IP에서 수많은 UDP 요청과 응답이 발생하는 것을 발견했습니다. 이러한 통신에서 식별 가능한 일반 텍스트 데이터는 거의 발견되지 않았으며 아웃바운드 요청의 대상 UDP 포트 번호는 다양해 보였습니다. 추가 조사 결과, 이 UDP 활동은 폴 마라페세가 DEF CON 28에서 발표하는 동안 광범위하게 분석하고 시연했던 IoT P2P(피어투피어) 프로토콜인 PPPP를 나타내는 것으로 밝혀졌습니다. 나중에 저희가 발견한 취약점을 악용하는 방식이 수정된 P2P 요청을 통해 용이하다는 결론을 내렸고, 이를 통해 AJCloud 플랫폼에서 P2P의 중요한 역할에 대해 더 자세히 알아보게 되었습니다.

P2P의 주요 목적은 관련된 네트워크 구성에 관계없이 애플리케이션과 IoT 디바이스 간의 통신을 원활하게 하는 것입니다. P2P는 주로 UDP 홀 펀칭을 기반으로 하는 접근 방식을 사용하여 요청이 직접 또는 더 접근하기 쉬운 네트워크 환경에 위치한 릴레이 서버를 통해 대상에 도달할 수 있는 임시 통신 경로를 생성합니다. AJCloud 앱에 통합된 P2P 명령의 핵심 세트는 비디오 및 오디오 스트림은 물론 마이크와 팬/틸트/줌에 대한 액세스를 제공합니다.

고급 하드웨어 해킹

P2P 통신에 대한 추가적인 이해를 바탕으로 이제 디버거에서 카메라 소프트웨어를 실행하는 등 P2P 대화 중에 카메라 자체를 더 면밀히 살펴볼 차례였습니다. 먼저 아래 그림과 같이 앞서 설정한 UART 직렬 연결을 통해 라이브 로깅 출력으로 카메라를 설정합니다.

이를 통해 애플리케이션의 로그 메시지와 필요한 추가 로깅 소스를 실시간으로 확인할 수 있었습니다. 이 정보를 통해 카메라와 클라우드 간의 통신을 설정하고 P2P를 통해 카메라에 액세스할 수 있는 인터페이스를 제공하는 데 사용되는 기본 바이너리를 식별했습니다.

이 바이너리는 로컬에서 initApp이라고 불리며 카메라가 완전히 초기화되고 부팅 순서가 완료되면 실행됩니다. 이를 감안하여 로컬 함수를 더 잘 평가하기 위해 디버거로 이 바이너리를 실행해 보았습니다. 이 작업을 시도하는 과정에서 initApp이 실행 중이 아닐 때를 감지하고 문제를 감지하면 카메라를 강제로 다시 시작하는 커널 워치독을 발견했습니다. 이 워치독은 /dev/watchdog 에 대한 쓰기를 확인하고, 쓰기가 중단되면 타이머를 트리거하여 쓰기가 재개되지 않으면 카메라를 재부팅합니다. 이렇게 하면 initApp 실행을 일시 중지하면 워치독에 대한 쓰기 작업도 일시 중지되므로 디버깅이 더 어려워집니다. 이 중지 동작의 예는 아래와 같습니다:

이를 방지하려면 initApp이 중지될 때마다 워치독에 글을 써서 재부팅을 방지할 수 있습니다. 그러나 또 다른 깔끔한 옵션은 Linux 커널 감시 드라이버 API의 매직 클로즈 기능을 사용하는 것입니다. 간단히 말해, 특정 마법 문자 'V' /dev/watchdog 를 쓰면 감시 기능이 비활성화됩니다. 워치독을 무력화하는 다른 방법도 있지만, 저희는 워치독을 마음대로 활성화 및 비활성화하기 쉽다는 점에서 이 방법을 연구용으로 선택했습니다.

워치독을 비활성화한 상태에서 initApp 디버깅을 설정하는 것은 매우 간단합니다. 가능하면 에뮬레이터를 사용하지 않고 카메라에서 직접 코드를 실행하고 싶었습니다. 카메라의 아키텍처는 리틀 엔디안 밉스(MIPSEL)입니다. 다행히 사전 빌드된 GDB와 GDBServer 바이너리는 수정 없이 작동할 수 있었지만, 처음에는 이 사실을 몰랐기 때문에 카메라 전용으로 GDBServer를 컴파일하는 툴체인도 설정했습니다. 비슷한 상황에 처한 경우 유용할 수 있는 한 가지 기술은 gcc와 같은 컴파일 도구를 사용하여 의심되는 대상 아키텍처에 소스 코드를 컴파일하고 실행되는지 확인하는 것입니다(아래 예제 참조).

저희의 경우 SoC를 이미 알고 있었기 때문에 타깃 아키텍처를 상당히 확신하고 있었지만, 특정 상황에서는 이를 발견하기가 쉽지 않을 수 있으며, 헬로 월드 바이너리로 작업하는 것이 초기 이해도를 높이는 데 유용할 수 있습니다. 바이너리를 컴파일할 수 있게 되면 카메라용 GDBServer를 컴파일한 다음 이를 사용하여 initApp을 연결하고 실행했습니다. 그런 다음 카메라와 동일한 로컬 네트워크에 있는 다른 컴퓨터에서 카메라에 연결했습니다. 이에 대한 예는 아래와 같습니다:

위 예제에서는 편의를 위해 -x 매개변수를 사용하여 일부 명령을 전달하고 있지만 디버깅에는 필요하지 않습니다. 파일이나 명령에 대한 자세한 내용은 elastic/camera-hacks GitHub 리포지토리를 참조하세요. initApp이 제대로 로드되려면 바이너리가 사용하는 라이브러리가 PATHLD_LIBARY_PATH 환경 변수를 통해 액세스할 수 있는지 확인해야 했습니다. 이 설정을 통해 필요에 따라 바이너리를 디버깅할 수 있었습니다. 앞서 마법 캐릭터로 감시자를 물리치는 방법도 사용했기 때문에 감시자가 다시 활성화될 수 있는 인스턴스도 제어해야 합니다. 대부분의 경우 이런 일이 발생하지 않기를 바랍니다. 따라서 아래와 같이 디버깅하는 동안 워치독이 다시 활성화되지 않도록 initApp의 워치독 호출을 덮어썼습니다.

다음 동영상은 부팅부터 GDBServer 실행까지 전체 설정 과정을 보여줍니다. 비디오에서는 새 initApp 프로세스도 시작하므로 원래 프로세스와 이 프로세스가 종료되면 새 initApp 프로세스를 생성하는 daemon.sh 셸 스크립트를 모두 종료해야 합니다.

P2P 클라이언트 구축

P2P가 AJCloud IoT 디바이스에 제공하는 모든 기능과 공격자가 이를 악용하는 방법을 자세히 알아보기 위해 자체 독립형 클라이언트 구축에 착수했습니다. 이 접근 방식을 사용하면 펌웨어를 리버스 엔지니어링하여 도출한 명령을 보다 빠르게 카메라에 연결하고 테스트할 수 있는 동시에 Wansview Cloud Windows 앱을 조작하는 오버헤드를 제거할 수 있습니다.

앞서 Windows 앱 로그에서 얻은 구성 데이터를 통해 클라이언트가 연결 프로세스의 일부로 최대 3개의 서로 다른 서버에 요청을 발행한다는 것을 알 수 있었습니다. 이러한 서버는 특정 카메라에 액세스하기 위해 트래픽이 라우팅되어야 하는 위치에 대한 지침을 클라이언트에 제공합니다. 공개적으로 이러한 서버를 더 많이 발견하려면 포트 60722 에서 다음 4바이트 UDP 페이로드를 사용하여 인터넷을 검색할 수 있습니다. 폴 마라페즈는 이 기법을 자신의 연구에 매우 효과적으로 사용했습니다.

P2P 연결을 제대로 설정하려면 먼저 클라이언트가 간단한 헬로 메시지(MSG_HELLO)를 보내야 하며, 피어투피어 서버가 이를 확인(MSG_HELLO_ACK)해야 합니다. 그런 다음 클라이언트는 서버(MSG_P2P_REQ)에 특정 deviceId를 쿼리합니다. 서버가 해당 장치를 인식하면 대상 IP 주소와 UDP 포트 번호 쌍으로 클라이언트에 응답(MSG_PUNCH_TO)합니다. 그런 다음 클라이언트는MSG_PUNCH_PKT UDP 홀 펀칭 루틴의 일부로 미리 정해진 범위 내의 다른 포트와 함께 IP 및 포트 쌍에 연결()을 시도합니다. 성공하면 대상은 연결이 설정되었음을 확인하는 최종 메시지(MSG_P2P_RDY)와 함께 클라이언트에게 메시지(MSG_PUNCH_PKT)를 다시 보냅니다.

카메라에 연결한 후에는 주로 다양한 MSG_DRW 패킷을 전송하고 그 동작을 관찰하는 데 관심이 있습니다. 이러한 패킷에는 카메라를 물리적으로 조작하고, 비디오 및 오디오 스트림을 보고 듣고, 카메라에 저장된 데이터에 액세스하거나 구성을 변경할 수 있는 명령이 포함되어 있습니다. 가장 간단한 명령으로 시작한 것은 카메라를 시계 반대 방향으로 패닝하는 것이었는데, 이는 하나의 메시지 전송으로 쉽게 식별할 수 있었습니다.

카메라의 디버그 로그 메시지를 통해 펌웨어 내에서 이 명령이 처리된 위치를 쉽게 찾을 수 있었습니다.

이 특정 메시지의 소스를 찾음으로써 MSG_DRW 메시지 처리를 처리하는 메인 루틴을 파악할 수 있었고, 이 명령이 호출되는 방식과 펌웨어에서 지원하는 다른 명령에 대한 중요한 통찰력을 얻을 수 있었습니다.

광범위한 리버스 엔지니어링과 테스트를 통해 사용자가 디바이스아이디에 액세스할 수 있는 경우 AJCloud 플랫폼의 모든 카메라에 연결할 수 있는 PoC P2P 클라이언트를 구축할 수 있었습니다. 클라이언트에서 지원하는 기본 명령에는 카메라 패닝 및 틸팅, 재부팅, 재설정, 오디오 클립 재생, 펌웨어 충돌 등이 있습니다.

우리가 구현할 수 있었던 가장 위험한 기능은 핵심 장치 구성 파일을 수정하는 명령( /var/syscfg/config_default/app_ajy_sn.ini)을 통해 구현할 수 있었습니다. 테스트 카메라에서 파일의 원래 내용은 다음과 같았습니다:

[common]
product_name=Q5
model=NAV
vendor=WVC
serialnum=WVCD7HUJWJNXEKXF
macaddress=
wifimacaddress=

이 파일에는 기본적인 디바이스 메타데이터가 포함되어 있는 것처럼 보이지만, 카메라가 자신을 식별하는 유일한 수단입니다. 카메라가 시작되면 이 파일의 내용을 읽은 다음 다양한 API 엔드포인트에 대한 일련의 컬 요청을 통해 AJCloud 플랫폼에 연결을 시도합니다. 이러한 컬 요청은 INI 파일에서 추출한 제품 이름, 카메라 모델, 공급업체 코드 및 일련 번호 값을 쿼리 문자열 인수로 전달합니다. 저희는 클라이언트를 사용하여 다음과 같이 콘텐츠를 덮어쓰는 메시지를 전달했습니다:

[common]
product_name=
model=OPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~HH01
vendor=YZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~HH01
serialnum=defghijklmnopqrstuvwxyz{|}~HH01
macaddress=
wifimacaddress=

카메라가 재설정된 후, 시작 루틴의 일부로 AJCloud 플랫폼 API 엔드포인트에 발행되는 모든 컬 요청은 INI 파일에 포함된 잘못된 데이터로 인해 실패합니다. 이러한 요청은 주기적으로 계속 전송되지만 성공하지 못하며 카메라는 비활성 상태로 유지되고 어떤 앱에서도 액세스할 수 없게 됩니다. 안타깝게도 카메라 초기화, 펌웨어 업데이트 또는 공장 설정 복원을 통해 이전 파일 내용을 복원할 수 있는 간단한 방법은 없습니다. 이 명령을 통해 파일을 수정하면 카메라가 사실상 망가져 쓸모 없게 됩니다.

app_ajy_sn.ini 에 저장된 값을 덮어쓰는 디컴파일된 함수(syscfg_setAjySnParams)를 자세히 살펴보면 MSG_DRW 명령에서 추출한 입력 파라미터가 파일의 모델, 공급업체 및 일련 번호 필드를 덮어쓰는 데 사용될 문자열 데이터를 전달하는 데 사용됨을 알 수 있습니다. memset은 이러한 입력 문자열을 저장하기 위한 3개의 전역 변수를 널 바이트로 덮어쓰는 데 사용됩니다. 그런 다음 입력 매개변수를 이러한 전역으로 전송하는 데 strcpy를 사용합니다. 이렇게 하면 각 인스턴스에서 null 문자를 만날 때까지 MSG_DRW 명령 버퍼에서 바이트가 직접 복사됩니다.

명령에서 추출된 이러한 입력 매개변수의 길이에 대한 유효성 검사가 적용되지 않기 때문에 버퍼 오버플로를 트리거할 충분한 길이의 메시지를 작성하는 것은 간단합니다. 이 취약점을 공격의 일부로 활용하여 카메라를 파괴하지는 않았지만, 공격자가 카메라에서 원격 코드 실행을 달성할 수 있는 익스플로잇을 개발할 수 있는 사례로 보입니다.

영향

AJCloud와 관련된 여러 공급업체와 여러 펌웨어 버전에 걸쳐 광범위한 디바이스가 이러한 취약점과 결함의 영향을 받는 것으로 확인되었습니다. 전반적으로 Wansview, Galayou, Cinnado, Faleemi의 15가지 카메라 제품에 대한 공격을 성공적으로 시연했습니다. 조사 결과에 따르면 AJCloud 펌웨어를 작동하고 AJCloud 플랫폼에 연결하는 모든 디바이스가 영향을 받는다고 가정해도 안전합니다.

이러한 취약점과 결함을 공개하기 위해 AJCloud와 Wansview에 연락을 시도했지만 모두 실패했습니다.

공급업체가 잘한 점은 무엇인가요?

앞서 발견하고 논의한 취약점에도 불구하고 AJCloud와 카메라 공급업체가 잘 구현한 보안 제어 기능이 많이 있습니다. 이렇게 저렴한 디바이스를 위해 많은 모범 사례가 구현되었습니다. 첫째, 인증서 기반 웹소켓 인증을 사용하여 네트워크 통신이 잘 보호됩니다. 암호화를 추가하는 것 외에도 많은 API 엔드포인트를 인증서 인증 뒤에 두면 중간자 공격이 훨씬 더 어려워집니다. 또한 모바일 앱의 APK는 서명되고 난독화되어 있어 앱을 조작하는 데 많은 시간이 소요됩니다.

또한 공급업체는 카메라 하드웨어 및 펌웨어에 대해서도 올바른 결정을 내렸습니다. 카메라의 로컬 OS는 제품에 필요한 기능에만 집중하여 효과적으로 제한됩니다. 파일 시스템은 로깅을 제외한 읽기 전용으로 구성되며, 커널 워치독은 가동 시간을 보장하고 장애 상태에 갇힐 위험을 줄이는 효과적인 방법입니다. 보안 부팅, 전원 켜기 리셋(POR) 워치독, 카메라 입력에 대한 초보적인 머신 러닝을 실행할 수 있는 별도의 RISC-V 프로세서 등 다양한 지원을 제공하는 Ingenic Xburst T31 SoC는 유능한 플랫폼입니다.

공급업체가 무엇을 잘못했나요?

안타깝게도 이러한 기능을 사용할 수 있는 기회를 놓친 경우가 많았습니다. 잠재적으로 가장 심각한 문제는 인증되지 않은 클라우드 액세스입니다. 많은 엔드포인트에 대해 설정된 API 액세스 제어를 고려할 때, 카메라 사용자가 인증 없이 일련번호를 통해 엔드포인트에 액세스하도록 하는 것은 피할 수 있는 큰 실수입니다. P2P 프로토콜도 앞서 살펴본 것처럼 취약하지만, 즉시 수정이 가능한 API 액세스와 비교하면 프로토콜을 수정하는 데 시간이 더 걸릴 수 있습니다. 매우 위험한 취약점이지만 발견과 수정에 상당한 시간을 투자해야 하므로 조금 더 이해할 수 있는 취약점입니다.

애플리케이션 측면에서는 공개적으로 출시하기 전에 제거했어야 하는 광범위한 디버그 로깅이 있는 Windows 앱이 주요 문제입니다. 하드웨어의 경우, 물리적 액세스(노출된 리셋 버튼 등)를 통해 쉽게 조작할 수 있습니다. 타겟 소비자층을 고려할 때 이는 그리 큰 문제가 되지 않습니다. 특히 기기에 대한 물리적 액세스를 고려할 때 보안보다는 사용성 측면에서 오류가 발생할 것으로 예상됩니다. 마찬가지로 보안 부팅도 활성화해야 하며, 특히 T31 SoC가 이를 지원한다는 점을 고려해야 합니다. 꼭 필요한 것은 아니지만, 이렇게 하면 디바이스의 소스 코드와 펌웨어를 직접 디버깅하기가 훨씬 더 어려워져 존재할 수 있는 취약점을 발견하기가 더 어려워집니다. 이상적으로는 부트로더가 서명되지 않은 OS를 계속 로드할 수 있도록 구현하여 손질과 개발을 용이하게 하되 부트로더 구성이 복원될 때까지 서명된 OS를 로드하지 못하도록 하는 것이 좋습니다. 그러나 현재 펌웨어의 한 가지 중요한 결함은 시스템이 실행되는 동안 읽기 전용 마운트 지점에 저장되지 않은 원래 일련 번호에 의존한다는 것입니다. 일련번호를 조작해도 디바이스가 영구적으로 고장 나지 않아야 합니다. 일련 번호를 덮어쓴 경우 새 일련 번호를 요청하거나 원래 일련 번호를 복원하는 메커니즘이 있거나 일련 번호가 불변이어야 합니다.

완화

공격 표면을 줄이고 공격이 발생할 경우 잠재적인 악영향을 제한하기 위해 특정 조치를 취할 수 있지만, 그 효과는 다양합니다.

Wi-Fi 카메라 및 기타 IoT 장치를 네트워크의 나머지 부분과 분리하는 것은 공격자가 더 중요한 시스템으로 측면 공격을 하는 것을 방지할 수 있는 적극 권장되는 대응책입니다. 그러나 이러한 접근 방식은 공격자가 AJCloud 플랫폼에서 발견된 액세스 제어 취약점을 악용하여 민감한 사용자 데이터를 획득하는 것을 막지는 못합니다. 또한 P2P를 통해 원격으로 카메라에 액세스하고 조작하는 방법을 쉽게 시연할 수 있었다는 점을 고려할 때, 로컬 네트워크 구성에 관계없이 AJCloud 플랫폼에 연결된 모든 장치는 여전히 상당한 보안 침해 위험에 노출되어 있습니다.

이러한 카메라와의 모든 네트워크 통신을 제한하는 것은 카메라 작동에 있어 AJCloud 플랫폼과의 연결이 필수적이기 때문에 불가능합니다. 앞서 언급했듯이 시작 시 다양한 API 엔드포인트에 연결할 수 없는 경우 디바이스가 작동하지 않습니다.

실행 가능한 접근 방식은 초기 시작 루틴 이후 통신을 제한하는 것입니다. 그러나 이렇게 하면 모바일 및 데스크톱 앱을 통한 원격 액세스 및 제어가 불가능해져 애초에 이러한 카메라의 목적이 무색해집니다. 이 분야에 대한 자세한 내용은 " 중단 없이 차단하기"를 참조하세요: 수많은 IoT 디바이스와 공급업체를 대상으로 이 접근 방식을 보다 심층적으로 살펴본 "차단 없이 차단하기: 비필수 IoT 트래픽의 식별 및 완화"를 참조하세요.

공급업체에 관계없이 핵심 기능을 유지하면서 Wi-Fi 카메라를 보호하는 가장 좋은 방법은 OpenIPC 또는 thingino와 같은 대체 오픈 소스 펌웨어로 플래시하는 것입니다. 오픈 소스 펌웨어로 전환하면 사용자에게 디바이스 구성 및 원격 네트워크 접근성을 세밀하게 제어할 수 있어 공급업체 클라우드 플랫폼에 강제로 연결해야 하는 번거로움을 피할 수 있습니다. 펌웨어 소스에 대한 공개 액세스는 부지런한 프로젝트 기여자들이 중요한 결함과 취약점을 신속하게 식별하고 패치할 수 있도록 도와줍니다.

핵심 사항

저희의 조사 결과, 플랫폼에 연결된 AJCloud 펌웨어를 작동하는 카메라의 모든 측면에 걸쳐 몇 가지 중요한 취약점이 발견되었습니다. 해당 플랫폼의 액세스 제어 관리와 PPPP 피어 프로토콜의 심각한 결함은 전 세계 수백만 개의 활성 디바이스에 영향을 미치는 광범위한 공격 표면을 제공합니다. 이러한 결함과 취약점을 악용하면 민감한 사용자 데이터가 노출되고 공격자는 AJCloud 플랫폼에 연결된 모든 카메라를 원격으로 완벽하게 제어할 수 있게 됩니다. 또한, 주요 구성 파일에 대한 임의의 쓰기 권한을 의도적으로 제공하는 내장 P2P 명령을 활용하여 카메라를 영구적으로 비활성화하거나 버퍼 오버플로우를 트리거하여 원격 코드 실행을 용이하게 할 수 있습니다.

보안 연구 커뮤니티에 가장 큰 도움이 될 것으로 생각되는 데이터 및 메모와 함께 저희가 구축한 사용자 지정 도구 및 스크립트를 보려면 저희의 GitHub 리포지토리를 방문하세요.