펌웨어 결함이 1,082 BTC를…콜드카드 5년 보안 허점

하드웨어 지갑의 최후의 보루가 무너졌다. 콜드카드(Coldcard)에서 5년간 지속된 펌웨어 오류로 1,082 BTC(약 7,000만 달러, 약 992억 원)가 탈취됐다. 가장 충격적인 점은 공격자가 피해자의 기기에 접근할 필요가 없었다는 것이다.
갤럭시 리서치는 1,196개 지갑에서 41분 동안 자금이 사라진 사건을 추적했다. 초기 보도(CoinDesk 7월 31일)는 594 BTC였으나 추가 집계로 1,082 BTC로 늘어났다.
시드 생성이 취약했다…오프라인도 막지 못한 이유
콜드카드 같은 하드웨어 지갑의 원칙은 오프라인 보안이다. 개인키를 기기 안에만 보관하고 인터넷에 꺼내지 않는다. 그런데 이번 공격은 그 원칙을 무시했다. 공격자가 자신의 컴퓨터에서 가능한 개인키를 전부 생성한 뒤 블록체인 주소와 대조했다. 매칭되는 주소의 자금을 가져갔다. 피해자의 콜드카드는 평생 인터넷에 연결되지 않았을 수도 있다.
정상적인 비트코인 지갑은 128비트 엔트로피를 가져야 하는데, 콜드카드의 결함 기기는 극도로 축소됐다. 공격 복잡도도 사라졌다. 로컬 컴퓨터 1대에서 2~3시간 내에 모든 후보 시드를 생성할 수 있었다. 블록체인 교차 검색은 50개 후보당 1초 미만이었다.
5년간 방치된 마이그레이션 오류
문제의 뿌리는 2021년 3월 펌웨어 4.0.0 업데이트다. 블록 엔지니어링팀 분석에 따르면 libNgU 라이브러리로 마이그레이션하는 중 빌드 설정 오류가 발생했다.
정상 흐름은 이래야 한다. TRNG(하드웨어 난수생성기)에서 128비트 난수를 수집한 후 BIP-39 표준을 적용해 12단어 시드를 생성한다. 그런데 오류로 인해 하드웨어 RNG가 우회됐다. 대신 소프트웨어 PRNG인 야스마랑(Yasmarang) 난수생성기로 폴백됐다. 더 문제는 이 생성기가 칩의 시리얼넘버와 클록 레지스터만을 시딩값으로 사용했다는 것이다. 결과: 약 1조 개 조합만으로 모든 개인키를 나열할 수 있게 됐다.
코드 리뷰는 실패했다. 빌드 설정에서 MICROPY_HW_ENABLE_RNG=0(하드웨어 RNG 비활성화)이 설정돼 있었는데, libNgU의 guards 검사가 “매크로 값 무시”하는 방식으로 구현돼 있었다. 펌웨어 바이너리에는 TRNG 라이브러리가 존재했지만 실제 심볼 해석(symbol resolution)이 잘못됐다. 설계 문제가 아니라 구현 미흡이었다.
Mk3는 40비트, Mk4는 72비트…모델별 편차
콜드카드는 여러 버전이 있고, 보안 구성이 달랐다. Mk3는 최악이었다. 펌웨어 4.0.1~4.1.9 버전에서 완전 결정론적(deterministic) 시드를 생성했다. 마이크로파이썬 야스마랑만 사용했기 때문이다. 검색 공간은 약 40비트(1조 개).
Mk4·Mk5·Q는 보안요소(SE1·SE2)의 엔트로피가 더해져 검색 공간이 약 72비트로 넓었다. 같은 결함을 안고 있었지만 Mk3보다는 공략이 어려웠다는 뜻이다. 야스마랑 폴백이 발생해도 하드웨어 엔트로피(약 40비트)가 추가로 혼합된다. 결합 엔트로피는 약 72비트(2^72, 약 4.7경개). 검색 공간이 Mk3의 약 100만 배 컸다. 선행 계산은 불가능했고(SE1/SE2 상태가 기기별 고유), 후행 검색에는 고속 컴퓨팅으로도 수일에서 수주가 걸리는 것으로 분석됐다.
40비트와 128비트…BIP-39 엔트로피가 뜻하는 것
독자들이 이해해야 할 기본이다. 비트코인은 BIP-39 표준을 따른다. 128비트 엔트로피는 약 3.4×10^38개의 가능한 시드를 의미한다. 평균 탐색에는 2^127번 시도가 필요하다. 고속 컴퓨터 100대로도 우주 나이보다 오래 걸린다. 반대로 40비트는 약 1조 개다. 128비트는 40비트의 약 3.4×10^28배 안전하다. 현실 공격에서 40비트는 PC 몇 대로 몇 시간 내에 공략 가능하고, 128비트는 불가능하다. 그 차이가 이번 사건을 낳았다.
콜드카드 제조사 코인키트는 책임을 인정했다. 결함을 없앤 펌웨어 4.2.0을 2026년 7월 31일 내놓고 사용자에게 절차를 안내했다. 취약 구간은 2021년 3월의 4.0.0부터 4.1.9까지였다.
Mk3 사용자는 가장 엄격한 조건을 받았다. 펌웨어 업그레이드에 이어 새 시드를 생성하고 자금을 모두 옮겨야 했다. 시드 생성 시엔 “주사위 롤(Dice Roll)” 옵션을 강력히 권고했다. 시드를 만들 때 주사위를 50회 이상 굴리면 검색 공간이 그만큼 넓어진다. 생성된 12/24단어 시드는 종이에 필기해 별도 안전 장소에 보관해야 했다. BIP-39 패스프레이즈를 함께 쓰도록 권장했다. 길고 무작위할수록 안전하다. 이 패스프레이즈는 시드와 다른 장소에 보관하면 시드만으로는 지갑에 접근할 수 없게 된다.
Mk4/Mk5/Q 사용자는 대체안이 있었다. 기존 시드 지갑을 폐기하고, 주사위를 50회 이상 굴려 엔트로피를 더한 시드를 새로 만드는 것이 권고됐다. 다만 패스프레이즈는 이미 만들어진 시드의 취약성을 없애지는 못한다. 시드를 새로 만드는 것이 먼저다. 자금 이전 비용도 고려사항이었다. 옮길 때 드는 채굴 수수료는 거래 크기와 그때의 혼잡도에 따라 달라진다. 1,082 BTC 피해에 비하면 무시할 수 없는 대가였다.
시드 재생성과 패스프레이즈 강화…사용자의 선택지
“내 키가 내 코인”이라는 자기수탁(self-custody)의 원칙이 흔들렸다. 콜드카드는 그 원칙의 표본으로 여겨졌다. 오픈소스, 격리된 기기, 사용자 통제 세 가지를 갖췄기 때문이다. 그런데 1,082 BTC 사건은 기기 제조사 오류로 인한 완전 손실을 보였다. 피해자는 기기 탈취도, 데이터 유출도 당하지 않았다. 하드웨어 사용이 절대 안전이 아니라는 뜻이었다.



연관 기사



