심볼 기부용 주소 : NBVBA3ATY2EM67D4FUOYRETQU5LCQZL43TTYAZA
해당 게시글의 기부번호 : 200000001 (메시지에 입력, 암호화 X)
트랜잭션 URI (복사해서 desktop-wallet에 붙여넣기 가능)
기부 완료시 블로그 상단 기부왕 목록에 표시해드립니다 😊
바로가기
3줄 요약글 작성에 앞서발견 주 원인 클라이언트 (catapult)표준 개발 도구 (SDK)수정Catapult (케타펄트)기존 Aggregate Transaction의 허용 범위SDKs마무리
3줄 요약
- @toshi 씨가 발견한 Aggregation Transaction의 취약점이 Sev0(매우 취약함) 단계로 불릴만큼 심볼 네트워크가 해킹의 위험에 노출됨을 확인
- 즉시 신디케이트 팀은 해당 취약점을 보안 하기 위한 보안 업데이트 작업을 진행
글 작성에 앞서
해당 글은 심볼 @Syndicate 팀의 “Symbol - October 25th, Post Mortem” 글을 바탕으로 작성 되었으며, 어떤 취약점이 발견되었고 그 취약점을 해결하기 위해서 어떤 노력을 했는지 최대한 쉽게 설명하기 위해 글을 작성하게 되었습니다.
발견
10월 13일 최초로 @toshi 씨가 디스코드의 #sdk-js 채널을 통해 해당 사실에 대해 언급하였습니다.
@toshi 씨는 사용되지 않는 이전 버전의 Symbol SDK(심볼 개발 도구) 와 현재 새롭게 만들어진 Symbol SDK 간의 Aggregation Transaction의 해시 값이 다르게 계산 되고 있음을 발견 했습니다.
그것은 예상하지 못한 것이었고, 더욱 문제 되는 부분은 두 버젼 모두 네트워크로 부터 허락을 받은 안전한 트랜잭션이라고 컨펌 되었기 때문입니다.
주 원인
그래서 @Syndicate 팀은 Symbol 네트워크의 클라이언트 프로그램인 catapult와 위 2가지 버전의 SDK를 분석하여 빠르게 버그 내용을 파악하였습니다.
클라이언트 (catapult)
2019년 11월 8일에 출시된 Catapult 클라이언트의 “Fushicho 2” 버전에서는 Completed 및 Bonded aggregate 트랜잭션의
TransactionsHash
필드를 검증하기 위해 Aggregate Transaction 플러그인에 새로운 검증자가 추가되었습니다. 하지만, 실수로 인해 이 검증자는 Aggregate Transaction 플러그인에 등록되지 않았으며, 따라서 해당 부분이 호출되지 않았습니다.manager.addStatelessValidatorHook([config](auto& builder) { // the following line should have been present but was not builder.add(validators::CreateAggregateTransactionsHashValidator()); builder.add(validators::CreateBasicAggregateCosignaturesValidator( config.MaxTransactionsPerAggregate, config.MaxCosignaturesPerAggregate)); if (config.EnableStrictCosignatureCheck) builder.add(validators::CreateStrictAggregateCosignaturesValidator()); });
Failure_Aggregate_Transactions_Hash_Mismatch
오류 코드를 발동시킬 E2E 테스트를 추가하는 것을 팀에서 체크하는 것(E2E 테스트 코드 누락)을 놓쳤고 그 결과, Symbol은 Aggregate 트랜잭션 해시에 대한 적절한 검증 없이 출시되었습니다.더욱이, 사용 중단된
TypeScript SDK
, Java SDK
, 그리고 우리의 Python
및 JavaScript SDK
들 사이에서 Aggregate 트랜잭션의 해시 계산에 차이가 있었습니다.Python
및 JavaScript SDK
는 Aggregate 트랜잭션 해시를 올바르게 계산하는 반면, 올해 초에 사용 중단된 TypeScript SDK
와 Java SDK
는 그렇지 못했다고 이야기하고 있습니다.표준 개발 도구 (SDK)
사용 중단된 TypeScript SDK는 계산에서 두 가지 버그를 가지고 있기에 이러한 문제가 발생했다고 합니다.
어그리게이트 트랜잭션은 내장된 트랜잭션들의 컨테이너(집합)입니다. 그렇기에 각 내장 트랜잭션은 8바이트 경계에서 트랜잭션의 데이터가 시작될 것이 보장됩니다. 이를 정확하게 계산하기 위해 트랜잭션 사이에 0으로 채워진 패드 바이트가 삽입되어야합니다. 내장 트랜잭션 해시를 계산할 때, 트랜잭션의 의미 있는 데이터만 해싱되어야 하며 0 패드 바이트는 제외되어야 합니다. 불행히도 TypeScript SDK는 이러한 0 패드 바이트를 해시 계산에 포함시켰고 큰 보안 이슈는 아니지만 문제의 소지가 있었습니다.
또한 진짜 버그는 머클 해시 계산에서 발견되었습니다. splice의 부적절한 사용으로 인해 요소를 교체하는 대신 삽입되었습니다. 두 번째 매개변수는 교체를 위해 1이 되어야 했습니다.
hashes.splice(i / 2, 0, this.hash([hashes[i], hashes[i + 1]]));
불충분한 테스트 커버리지와 표준 테스트 벡터를 사용하지 않은 것이 원인으로, 이러한 두 가지 실수는 코어팀에서 확인하기에는 쉽지 않았다고 합니다.
(사용 중단된)
Java SDK
는 TypeScript SDK
와 같은 머클 해시 계산 버그를 가지고 있었습니다. 놀랍게도, Java SDK
는 패딩 없이 내장 트랜잭션 해시를 올바르게 계산했습니다.이 두 SDK가 수년 동안 다른 어그리게이트 트랜잭션 해시를 계산해 왔는데 아무도 지금까지 눈치채지 못했다는 점은 매우 우스운 일이고 최소한으로 공통으로 된 테스트 벡터를 사용했어야 했다고 이야기 했습니다.
수정
Catapult (케타펄트)
케타펄트 버전이
1.0.3.4
로 업데이트가 되면서 AggregateTransactionHashValidator
가 정상적으로 플러그인에 등록이 되었습니다.또한 블록 높이
1’690’500
부터 모든 aggregate transaction의 해시는 패딩 값이 없이 계산되게 끔 변경 되었습니다. (그리고 정상적인 머클 해시 알고리즘도 포함)기존 Aggregate Transaction의 허용 범위
아래 5가지 중에 하나라도 충족 되는 Aggregate Transaction은 네트워크에서 컨펌됩니다.
- Unpadded transaction hashes with correct Merkle Hash algorithms
- Padded transaction hashes with correct Merkle Hash algorithms (TS SDK, <= 2 embedded transactions)
- Unpadded transaction hashes with invalid Merkle Hash algorithms (Java SDK, > 2 embedded transactions)
- Padded transaction hashes with invalid Merkle Hash algorithms (TS SDK, > 2 embedded transactions)
- Hash has matching entry in new
corrupt_aggregate_transaction_hashes
network configuration setting (20 miscellaneous)
성능 상의 이유로
1’690’500
이후 블록 부터는 version 2의 Aggregate Transaction만 허용 됩니다.SDKs
Python과 Javascript SDK는 V2 Aggregate Transaction을 지원하도록 업데이트 되었습니다. (현재는 Java SDK, Typescript SDK도 지원 하는 것으로 보임)
업데이트 이후 V1 Aggregate Transaction에 대한 지원을 제한하며, SDK들 또한 정상적인 머클 해시 알고리즘을 등록하였습니다.
마무리
글을 마무리하며, 신디케이트 팀은 취약점에 대한 보안을 고양이와 쥐 처럼 쥐를 잡기 위해 계속해서 쫓는 그런 상황이라고 표현 하였습니다.
또한 이번과 같이 블록체인 네트워크가 공격당할 만큼 큰 이슈에 대해서 정보를 일반 유저층에 바로 전달하지 못한 점에 대해서도 언급을 하였습니다. 일반 유저들 입장에서는 사실 크게 변화 하는 것도 없고 해프닝 정도로 넘어갈 수 있었겠지만 이는 수 많은 사람들의 노력이 있었기에 조용히 넘어간 것 이라고 생각하시면 좋을 것 같습니다.
그리고 이번 사건을 사전에 확인하고 알려준 @toshi 씨에게는 공개 보상금 ¥370,000 (한화 약 355만원)이 지급될 예정이라고 합니다.
다시 한번 Symbol 네트워크의 발전에 기여한 @toshi 씨에게 감사의 말씀 올립니다.
ありがとう @toshi さん。