1P by GN⁺ | ★ favorite | 댓글 1개
  • Hanwha Vision 카메라 펌웨어의 웹 관리 UI 파일 약 30개에 동일한 GitHub 토큰이 들어 있었고, 이 토큰은 조직 내 수백 개 저장소에 관리자 권한을 보유했음
  • 펌웨어의 fwupgrader는 하드코딩된 AES 키를 정적 테이블과 XOR해 복원한 뒤 openssl로 루트 파일 시스템을 해독했으며, 키와 IV는 동일 모델군에서 공통으로 사용됐음
  • Vite 빌드 변수가 process.env 전체로 설정되면서 CI 작업의 환경 변수가 결과물에 기록됐고, GITHUB_NPM_TOKEN과 여러 내부 설정까지 카메라 펌웨어에 포함됨
  • 약 500개 펌웨어를 같은 방식으로 조사해 62%를 추출했으며, GitHub 토큰이 발견된 펌웨어 3개에는 모두 같은 토큰이 들어 있었음
  • Hanwha는 신고 후 12시간 이내에 토큰을 폐기했지만, CI 환경 전체를 클라이언트 결과물에 삽입하는 구성은 자격 증명과 내부 인프라 정보를 제품에 노출할 수 있음

펌웨어 확보와 첫 번째 암호화 계층

  • Hanwha Vision 웹사이트는 카메라 모델별 펌웨어 이미지를 공개해 파일을 내려받아 분석할 수 있었음
  • binwalk로 이미지를 조사하자 카메라용 AI 구성요소가 담긴 별도 tarball과 암호화된 fwimage.tgz가 발견됨
  • Matt Brown의 Hanwha 펌웨어 복호화 분석에 따라 HTW와 모델 번호를 결합한 암호를 사용함
    • 분석 대상에서는 HTWXNP-9300RW가 작동함
  • 해제된 tarball 안에는 다른 방식으로 암호화된 또 하나의 fwimage.tgz가 있어 기존 복호화 절차를 그대로 재사용할 수 없었음

fwupgrader에서 복호화 방식 복원

  • 외부 tarball에 포함된 fwupgrader 바이너리를 Ghidra와 Claude Code로 분석해 실제 루트 파일 시스템을 추출함
  • fwupgrader에는 복호화 방식을 감추는 난독화가 적용돼 있었음
    • AES 키를 바이너리 내부의 작은 정적 키 테이블과 XOR한 뒤 실행 중 재조립함
    • IV는 바이너리에 평문으로 들어 있음
    • openssl 명령 조각도 같은 방식으로 XOR 난독화됨
  • 복원된 명령은 SHA-256과 AES-256-CBC를 사용하는 다음 형태임
    openssl enc -md sha256 -aes-256-cbc -d \  
      -K <KEY> -iv <IV> -in <INPUT> -out <OUTPUT>  
    
  • 키와 IV는 하드코딩돼 동일 모델군에서 공통으로 사용됐음
    KEY = dfa049bb922e63e2decc764af5628068e5b7a2662e479a615b14643e567579b0  
    IV  = 53f926801b81454a4f889c9a390db6e6  
    

펌웨어에 포함된 GitHub 관리자 토큰

  • 추출한 루트 파일 시스템을 trufflehog로 검사하자 동일한 GitHub 토큰이 약 30개 파일에서 중복 발견됨
  • 이 토큰은 Hanwha의 GitHub 조직에 속한 수백 개 저장소에 관리자 권한을 가지고 있었음
  • 카메라 UI는 Vite로 빌드되며, 빌드 변수 하나가 process.env 전체로 설정돼 CI 작업의 전체 환경이 결과 파일에 기록된 것으로 확인됨
    var W = {  
      DATAPORT: "9090",  
      GIT_LFS_SKIP_SMUDGE: "1",  
      npm_command: "run-script",  
      KUBERNETES_SERVICE_PORT_HTTPS: "443",  
      GITHUB_NPM_TOKEN: "<snip>:ghp_…REDACTED…",  
      npm_config_userconfig: "/home/docker/.npmrc",  
      // etc  
    }  
    
  • 실제 카메라가 없어 동작 여부는 검증하지 못함
    • 관리 UI에 접근한 사용자에게 토큰이 네트워크로 전송됐을 가능성이 있음
    • 파일이 디스크에만 존재하고 실제로 제공되지 않았을 가능성도 남아 있음

CI 환경에 포함된 DoD 주소

  • 노출된 환경 변수에는 미국 국방부에 할당된 IP 주소도 포함돼 있었음
  • 이 주소가 외부와 통신하지 않는 내부 서비스에 임의로 사용된 것인지, Hanwha와 미국 국방부의 관계에서 비롯됐는지는 확인되지 않음
  • Hanwha Vision은 Samsung Techwin으로 설립된 영상 감시 기업이자 Hanwha Group의 자회사임
    • 과거 제품에는 K9 Thunder 자주포, K10 탄약운반장갑차, K2 Black Panther 하위 시스템, SGR-A1 경계 로봇이 포함됨
    • SGR-A1은 무장 경계 로봇임
  • CI를 Hanwha의 중앙 조직이 제공하고 계열사 Hanwha AerospaceHanwha Defense USA의 요구로 관련 변수가 공유됐을 수도 있으나, 이는 확인되지 않은 추측임

전체 펌웨어 조사

  • 우연한 단일 사례인지, 서로 다른 토큰이 더 있는지 확인하기 위해 Hanwha 웹사이트에서 내려받을 수 있는 카메라 펌웨어를 수집함
  • 약 600개 카메라 가운데 펌웨어가 제공되는 모델을 대상으로 약 500개 펌웨어를 확보함
  • 같은 방법으로 62%를 추출할 수 있었으며, 나머지가 실패한 이유는 확인하지 못함
  • GitHub 토큰이 들어 있던 펌웨어는 3개였고, 모두 동일한 토큰을 포함했음

신고와 대응

  • 토큰 위치를 식별할 수 있는 최소한의 정보를 Hanwha의 공개 보안 신고 이메일로 전달함
  • Hanwha는 신고 후 12시간 이내에 응답하고 해당 토큰을 폐기함
  • GitHub 토큰이 펌웨어에 포함된 것은 잘못이지만, 신고 접수와 해결은 매우 신속하게 이뤄졌음

댓글과 토론

Hacker News 의견들
  • 제조사가 지원하면서도 필요에 따라 rootfs를 제거할 수 있는 화이트라벨 IP 카메라나 준플러그앤플레이 제품을 찾고 있음
    예전에는 케이스조차 없는 비싼 개발 키트뿐이었는데, 지금은 GoodCam 같은 선택지가 생긴 듯함

    • 개방형 펌웨어는 아니어도 격리된 네트워크에서 ONVIF를 사용하면 상당히 근접함
      ONVIF 카메라는 대부분의 네트워크 영상 녹화기(NVR)와 호환되고 오픈소스 NVR도 여럿 있음
      저렴한 PoE 카메라를 외부에 노출하지 않으면 제조사 펌웨어의 보안은 덜 중요하지만, VLAN과 망 분리는 매우 꼼꼼히 구성해야 함
    • 이 문제를 해결하려고 Wyrecam을 만들었으며, Wyze v3의 Ingenic T31을 지원함
      안정성은 Apple HomeKit과 비슷한데, 그다지 훌륭하지는 않음
    • Thingino는 지원 카메라 목록이 명확하며, SD 카드 플래싱 지원 모델이라면 설치도 간단함
      Sonoff Slim Gen2 두 대를 문제없이 업그레이드했음
    • 일부 카메라는 Thingino로 기존 펌웨어를 교체할 수 있고, OpenIPC 지원 하드웨어 목록도 참고할 만함
    • 상점 페이지가 Stránka nenalezena, There's been a glitch... 오류를 내며 작동하지 않는 듯함
  • 펌웨어에 미국 국방부 IP 주소가 박혀 있다는 쪽이 더 큰 문제로 보이며, 한국산 보안 제품은 피해야겠다고 느낌

    • 어떤 회사는 미 국방부의 전체 IP 대역을 블랙홀 처리하고 내부 주소로 사용하기도 하므로 그런 경우일 수 있지만, 그래도 매우 이상함
    • 캐나다 해군도 최근 대형 사업에서 비슷한 결정을 내린 것으로 보임: 검색 결과
    • 미 국방부가 워낙 방대한 IP 주소 공간을 보유해서 우연히 겹쳤을 가능성도 충분함
    • 한국산 IoT 제품도 마찬가지이며, 직접 다뤄본 제품들의 보안 방식은 터무니없는 수준이었음
    • 자국 제품도 보안 취약점과 허술한 엔지니어링으로 엉망인 경우가 많음
  • 많은 공급업체가 위험한 기본값, 망가진 보안, 하드코딩된 값을 사용함
    보안을 최우선으로 두지 않더라도 최소한 하드코딩 자격 증명 검사 같은 기본 점검은 필요함

    • 보안 카메라에서 보안이 우선순위가 아니라는 사실 자체가 아이러니함
    • 가장 경험 없고 저렴한 인력에게 일을 맡기는 운영 방식에서는 최소 기준 검사조차 기대하기 어려움
    • 요즘은 저장소에 기본 보안 검사를 수행하는 기능만 추가해도 되므로 변명의 여지가 거의 없음
  • 카메라는 별도 VLAN에 넣고 해당 VLAN의 인터넷 접근을 완전히 차단하는 것이 최소한의 조치임

  • 예전에 확인해 보니 많은 OBD-II 동글이 동일한 MAC 주소로 출하됐고, 그 결과 여러 웹사이트의 모든 정보에 접근할 수 있었음
    이런 문제는 피하고 싶어도 계속 발생하기 마련임

    • 동일한 MAC 주소가 어떻게 전체 접근 권한으로 이어졌는지 궁금함
      웹사이트가 클라이언트가 제공하는 MAC 주소를 인증 수단으로 삼았다면 전형적인 IoT 보안 실패임
  • 제품명에서 보안을 빼고 그냥 카메라라고 부르는 편이 나을 듯함

  • 이 블로그가 외부 링크 아이콘을 잘못 사용하는 점이 거슬림

    • a[href*="://"]::after 선택자는 내부 링크가 href="/about" 같은 상대 경로라고 가정하지만, 이 사이트는 탐색 링크에도 [https://hhh.hn/about](https://hhh.hn/about) 같은 절대 URL을 사용해서 모든 링크에 아이콘이 붙음
      사이트 주소로 시작하는 링크를 제외하면 해결 가능함: a[href*="://"]:not([href^="https://hhh.hn";])::after
  • 최근 구매한 실내 분위기 조명은 전용 앱 없이는 제어할 수 없었음
    Google 스토어에서 APK를 받아 분석해 보니 백엔드와 Shopify 등의 API 키가 사실상 고스란히 들어 있었지만, 아직 이를 이용해 무언가 하지는 않았음

    • 공개 키는 특별한 접근 권한을 주지 않는 경우가 많음
      보안을 신경 쓰는 개발자라면 App Attest나 Google 스토어의 동등한 기능을 사용할 것임
    • 조명 앱에 Shopify API 접근 권한이 필요한 타당한 이유는 떠오르지 않음
      다만 Shopify 상점 자문을 해본 입장에서 저가 컨설턴트나 디자이너가 제공하는 코드 품질은 처참한 경우가 많아 놀랍지는 않음
    • 외관 때문에 항상 최선은 아니더라도 Zigbee나 Z-Wave처럼 로컬 제어가 가능한 스마트 기기만 구매하는 편이 안전함
    • 이런 정보를 공개하면 업체가 법적으로 대응할 수 있어 위험함
      연구자를 법적 결과로부터 보호해 주던 회사가 있었지만 이름은 기억나지 않음
    • 전용 앱 없이도 결국 제어할 수 있으니, 프로토콜을 역공학해 방법을 공개해 주길 바람
  • LLM 때문에 코드 난독화가 사실상 무력화됐음
    난독화는 작업을 지루하게 만들어 방해했을 뿐인데 AI는 그런 수고를 개의치 않음

    • 난독화는 지루함을 견디지 못하는 가벼운 공격자에게만 효과가 있었음
      국가 조직이나 범죄 해커 집단은 그 수고를 충분히 감수함
    • 긍정적으로 보면 작은 로컬 LLM만으로도 이런 저품질 코드를 쉽게 개선할 수 있음
  • 이런 시스템을 미국 방위산업 전시회에서 본 적이 있어 실제로 어딘가에서 사용 중일 가능성이 높음