비트코인 개발 철학: 드러난 취약점

이 기사는 기계로 번역되었습니다
원문 표시

저자: 칼레 로젠바움 & 린네아 로젠바움

출처: https://bitcoindevphilosophy.com/#whenshithitsthefan

이전 기사는 여기에서 확인하세요.

shtf-배너

비트코인은 사람이 개발했습니다. 소프트웨어는 사람이 만들고 실행합니다. 보안 취약점이나 심각한 버그가 발견될 때—사실 둘 사이에 차이가 있을까요?—발견하는 것은 언제나 사람입니다. 처음부터 끝까지, 우리, 피와 살로 이루어진 존재들이죠. 이 장에서는 취약점이 발견되었을 때 사람들이 무엇을 했고, 무엇을 했어야 했으며, 무엇을 하지 말았어야 했는지 살펴봅니다. 첫 번째 섹션에서는 " 책임 있는 공개"라는 용어의 의미를 설명합니다. 이는 취약점이 발견된 후 피해를 최소화하기 위해 책임감 있게 행동하는 방법을 의미합니다. 나머지 장에서는 비트코인 ​​소프트웨어에서 발견된 가장 심각한 취약점 몇 가지와 개발자, 채굴자, 사용자들이 어떻게 대처했는지 살펴봅니다. 비트코인 ​​초기에는 많은 부분이 지금처럼 견고하지 않았습니다.

9.1 적절한 정보 공개

Bitcoin Core 소프트웨어에서 누군가가 네트워크를 통해 특수하게 조작된 메시지를 전송하는 것만으로 원격에서 비트코인 ​​코어 노드를 종료시킬 수 있는 버그를 발견했다고 상상해 보세요. 이제, 당신에게는 악의적인 의도가 전혀 없고 이 취약점이 악용되는 것을 원하지 않는다고 가정해 봅시다. 그렇다면 어떻게 하시겠습니까? 만약 당신이 침묵을 지킨다면, 다른 누군가가 이 취약점을 발견할 수도 있지만, 그 사람은 당신처럼 선의를 갖고 있지 않을 수도 있습니다.

보안 문제를 공개할 때는 공개자가 책임 있는 공개 절차를 따라야 합니다. 비트코인 ​​개발자들도 이 용어를 자주 사용하며, 위키피디아에서는 그 의미를 다음과 같이 설명합니다 .

하드웨어 및 소프트웨어 개발자는 버그를 수정하는 데 시간과 자원이 필요한 경우가 많습니다. 이러한 취약점은 종종 윤리적 해커[1]에 의해 발견됩니다. 해커와 컴퓨터 보안 과학자는 이러한 취약점에 대한 대중의 인식을 높이는 것을 사회적 책임으로 여길 수 있습니다. 문제를 숨기면 잘못된 안전감을 조성할 수 있습니다. 이를 방지하기 위해 관련 당사자들은 취약점 해결을 위한 적절한 기간을 협의하고 결정합니다. 이 기간은 취약점의 잠재적 영향, 긴급 수정 또는 임시 해결책을 개발 및 구현하는 데 필요한 예상 시간, 기타 요인에 따라 며칠에서 몇 달까지 다양할 수 있습니다.

— 위키백과, "책임 있는 정보 공개" 항목

즉, 보안 취약점을 발견하면 시스템 개발을 담당하는 팀에 보고해야 한다는 뜻입니다. 그렇다면 비트코인 ​​세계에서는 어떻게 작동할까요? 7.1장 ( 중국어 번역 )에서 설명했듯이, 비트코인을 통제하는 주체는 없습니다. 비트코인 ​​개발의 중심은 오직 Bitcoin Core GitHub 저장소 뿐입니다. 이 저장소의 관리자는 저장소 내의 코드에 대한 책임은 있지만, 전체 비트코인 ​​시스템에 대한 책임은 없으며, 그 누구도 마찬가지입니다. 또한, 일반적으로 가장 좋은 방법은 security@bitcoincore.org 로 이메일을 보내는 것입니다.

앤서니 타운스는 2017년 "책임 있는 버그 공개"라는 제목의 이메일 에서 자신이 생각하는 모범 사례를 요약하려고 시도했습니다. 그는 여러 출처와 다양한 사람들의 의견을 수렴하여 이 주제에 대한 자신의 관점을 제시했습니다.

  • 취약점은 bitcoincore.org 웹사이트의 보안 페이지를 통해 보고해야 합니다[0].
  • 심각한 취약점(즉시 악용될 수 있는 취약점 또는 이미 악용되어 상당한 피해를 발생시킨 취약점)은 다음과 같이 처리됩니다.
    • 가능한 한 빨리 패치를 배포하세요
    • 널리 퍼진 알림에 따르면 업그레이드(또는 해당 시스템 비활성화)가 필요합니다.
    • 공격을 지연시키기 위해 실제 문제를 가능한 한 적게 공개하십시오[1][2]
  • 중요하지 않은 취약점(악용하기 어렵거나 비용이 많이 드는 취약점)은 다음과 같이 처리됩니다.
    • 표준 개발 프로세스에 따른 패치 및 검토.
    • 마스터 브랜치에서 현재 릴리스로 수정 사항 또는 해결 방법을 이식합니다.[2]
  • 개발자는 취약점의 본질을 드러내지 않고 수정 사항을 배포하려고 시도합니다. 접근 방식은 경험이 많지만 취약점을 알지 못하는 개발자에게 제안된 수정 사항을 제공하고 취약점이 수정되었음을 알리고 취약점을 찾도록 요청하는 것입니다. [2]
  • 수정 사항이 발행되고 널리 채택되기 전에 개발자는 취약점 노출을 방지할 수 있다면 다른 비트코인 ​​구현에서 수정 사항을 채택하도록 제안할 수 있습니다. 예를 들어 수정 사항이 상당한 성능 이점을 제공하는 경우 이러한 코드를 병합하는 이유가 될 수 있습니다[3].
  • 취약점이 드러나기 전에 개발자는 일반적으로 우호적인 알트코인 개발자에게 수정 사항을 후속 조치하도록 권고합니다. 그러나 이는 수정 사항이 비트코인 ​​네트워크에 널리 배포된 후에만 가능합니다. [4]
  • 개발자는 일반적으로 이전에 적대감을 보인 알트코인 개발자(예: 취약점을 이용하여 다른 사람을 공격하거나 금지 사항을 위반한 경우)에게 알리지 않습니다[5].
  • 비트코인 개발자는 비트코인 ​​노드의 80% 이상이 수정 사항을 배포할 때까지 취약점을 공개하지 않습니다. 취약점 공개자는 동일한 전략을 따르도록 권장되고 요구됩니다[1][6].

— 앤서니 타운스, "버그의 적절한 공개" 메일링 리스트, Bitcoin-dev 메일링 리스트(2017)

위 목록은 비트코인 ​​패치를 배포할 때 얼마나 신중해야 하는지를 보여줍니다. 패치는 취약점의 위치를 ​​드러낼 수 있기 때문입니다. 특히 네 번째 항목은 패치가 잘 숨겨져 있는지 확인하는 방법을 설명하고 있어 흥미롭습니다. 실제로, 패치가 취약점을 수정하는 것임을 알고 있는 숙련된 개발자 몇 명조차 취약점을 찾지 못한다면, 다른 개발자들이 이를 찾는 것은 매우 어려울 수 있습니다.

이 이메일 이전까지 이메일 스레드에서는 알트코인 개발자 및 기타 비트코인 ​​구현 개발자에게 취약점을 언제, 어떻게 공개해야 하는지에 대한 논의가 주를 이루었습니다. 명확한 답은 없었습니다. "선량한 사람들을 돕는 것"은 합리적으로 보이지만, 그들이 선량한 사람들이 아니라는 것을 누가 확신할 수 있을까요? 어디까지가 허용되어야 할까요? 브라이언 비숍은 사기성 알트코인이라 할지라도 보안 침해로부터 스스로를 보호할 수 있도록 돕는 것은 도덕적 책임 이라고 주장합니다 .

비트코인과 그 사용자를 당면한 위협으로부터 보호하는 것만으로는 충분하지 않습니다. 모든 유형의 사용자와 다양한 소프트웨어를, 설령 사용자가 여러분이 직접 유지 관리, 개발 또는 권장하지 않는 취약하고 안전하지 않은 소프트웨어를 사용하더라도, 그 형태를 불문하고 광범위한 위협으로부터 보호해야 할 더 큰 책임이 있습니다. 취약점에 대한 정보를 접하는 것은 매우 까다롭고, 처음 설명된 것보다 훨씬 더 심각한 직접적 또는 간접적 결과를 초래할 수 있는 정보를 접하게 될 수도 있습니다.

— 브라이언 비숍, "버그의 적절한 공개" 메일링 리스트, Bitcoin-dev 메일링 리스트(2017)

타운즈의 이메일에 앞서 그레고리 맥스웰이 보안 취약점이 겉으로 보이는 것보다 더 심각할 수 있다고 주장하는 이메일을 보냈습니다.

저는 처음에 악용하기 어렵다고 여겨졌던 문제가 적절한 기관만 찾으면 아주 쉽게 악용될 수 있다는 것을 여러 번 목격했습니다. 또한 사소한 DoS 공격 문제가 훨씬 더 심각한 문제로 발전하는 경우도 보았습니다.

단순한 성능 버그라도 신중하게 활용하면 네트워크를 마비시킬 수 있습니다. 예를 들어 채굴자 A와 거래소 B가 한 네트워크에 있고 다른 채굴자들은 다른 네트워크에 있다면, 누군가가 반복적으로 돈을 쓸 수 있게 되는 것입니다.

이런 식으로 계속됩니다. 따라서 저는 각기 다른 상황을 다르게 처리해야 한다는 점에는 전적으로 동의하지만, 그 경계가 항상 명확한 것은 아닙니다. 가장 중요한 것은 문제를 실제보다 더 심각하게 생각하지 않도록 주의하는 것입니다.

— 그레고리 맥스웰, "버그의 적법한 공개" 메일링 리스트, Bitcoin-dev 메일링 리스트(2017)

그러므로 취약점이 악용하기 어려워 보이더라도, 실제로는 악용하기 쉽다고 가정하는 것이 가장 좋습니다. 단지 당신이 아직 악용 방법을 알아내지 못했을 뿐입니다.

그레고리는 또한 "이 이메일 스레드가 '정보 공개'에 대해 논의하는 것이라고 생각하는 것은 잘못입니다. 정보 공개는 공급업체에게 알리는 것을 의미합니다. 이 이메일 스레드는 '공개 공개'에 관한 것이며, 그 의미는 다릅니다. 공개 공개란 잠재적 공격자에게도 알렸다는 것을 확실히 하는 것을 의미합니다."라고 지적했습니다. 정보 공개와 공개 공개의 차이에 대한 이 마지막 지적은 중요합니다. 책임 있는 정보 공개는 비교적 간단한 부분이고, 합리적인 공개 공개는 어려운 부분입니다.

9.2 아동기 트라우마

비트코인은 초기에는 개인 프로젝트였습니다(적어도 창시자의 가명으로 판단컨대, 한 사람이 만든 것으로 보입니다). 당시 비트코인은 거의 가치가 없었습니다. 따라서 취약점 공개와 버그 수정이 지금처럼 엄격하게 이루어지지 않았습니다.

비트코인 위키는 비트코인에 영향을 미친 공개된 취약점(CVE) 목록을 관리합니다. 이 장에서는 이러한 보안 취약점 중 일부와 비트코인 ​​초기 시절에 발생했던 예상치 못한 사건들을 소개합니다. 모든 취약점을 다루지는 않고, 특히 흥미로운 취약점들만 살펴볼 것입니다.

9.2.1 2010-07-28: 타인의 돈을 사용하는 행위 (CVE-2010-5141)

2010년 7월 28일, "ArtForz"라는 가명을 사용하는 익명의 사용자가 bitcoin ​​소프트웨어 버전 0.3.4에서 다른 사람의 코인을 사용할 수 있는 취약점을 발견했습니다. ArtForz는 이 취약점을 사토시 나카모토 와 "개빈 앤드레슨"이라는 또 다른 개발자에게 성실히 보고했습니다.

문제는 당시 스크립트 오퍼코드 OP_RETURN 프로그램 실행을 즉시 종료시킨다는 점입니다. 따라서 사용된 코인에 대한 스크립트 공개 키가 <pubkey> OP_CHECKSIG 이고 스크립트 서명이 OP_1 OP_RETURN 인 경우, 스크립트 공개 키에 있는 프로그램은 전혀 실행되지 않습니다. 단지 1 게임 스택에 푸시되고, OP_RETURN 으로 인해 스크립트 공개 키에 있는 프로그램이 건너뛰어질 뿐입니다. 프로그램 실행이 완료된 후, 스택 맨 위에 0 아닌 값이 있으면 지출 조건이 충족된 것입니다. 스택 맨 위의 요소가 0이 아닌 1 이므로 지출이 성공한 것입니다.

다음은 당시 OP_RETURN 처리했던 코드입니다.

 case OP_RETURN: { pc = pend; } break;

pc = pend; 의 효과는 프로그램의 나머지 부분을 건너뛰는 것이므로 스크립트의 공개 키에 잠겨 있는 스크립트는 모두 무시됩니다. 한 가지 해결책은 OP_RETURN 의 의미를 변경하여 (스크립트 실행) 실패를 즉시 출력하도록 하는 것입니다.

 case OP_RETURN: { return false; } break;

사토시 나카모토 자신의 코드베이스를 수정하고 버전 번호 0.3.5를 사용하여 실행 가능한 바이너리를 컴파일했습니다. 그런 다음 그는 비트코인토크 포럼에 "경고! 가능한 한 빨리 0.3.5로 업그레이드하세요 (***** 알림 *** 가능한 한 빨리 0.3.5로 업그레이드하세요)"라는 글을 올려 사용자들에게 바이너리를 설치하도록 촉구했지만, 소스 코드는 제공하지 않았습니다.

지금 바로 0.3.5 버전으로 업그레이드하세요! 네트워크에서 사기 거래가 승인되도록 허용했던 구현 버그를 수정했습니다. 0.3.5 버전으로 업그레이드하기 전까지는 비트코인 ​​결제를 받지 마세요!

— 사토시 나카모토, Bitcointalk 포럼(2010)

원래 메시지는 수정되었으며, 완전한 형태는 현재 알려지지 않았습니다. 위 발췌문은 인용된 답변 에서 가져온 것입니다. 일부 사용자는 사토시 나카모토 의 바이너리를 실행해 보았지만 문제가 발생했습니다. 그 직후 사토시 나카모토 다음과 같이 말했습니다 .

SVN이 아직 업데이트되지 않았습니다. 현재 개발 중인 버전 0.3.6이 나올 때까지 기다려 주시기 바랍니다. 그동안에는 노드를 종료하셔도 됩니다.

— 사토시 나카모토, Bitcointalk 포럼(2010)

(역자 주: 여기서 "SVN"은 오픈 소스 버전 관리 시스템인 "Apache Subversion"을 의미합니다.)

35분 후, 그는 이렇게 말했다 .

SVN이 버전 0.3.6으로 업데이트되었습니다.

Windows 실행 파일(버전 0.3.6)을 Sourceforge에 업로드한 다음 Linux 실행 파일을 다시 컴파일하겠습니다.

— 사토시 나카모토, Bitcointalk 포럼(2010)

(역자 주: "Sourceforge"는 다른 사람들이 다운로드할 수 있도록 코드를 업로드하는 웹사이트입니다.)

이 시점에서 그는 원래 게시글을 업데이트하여 "0.3.5"를 "0.3.6"으로 변경한 것으로 보입니다.

지금 바로 0.3.5 버전으로 업그레이드하세요! 사기 거래가 승인된 것처럼 보일 수 있었던 구현 오류를 수정했습니다. 0.3.5 버전으로 업그레이드하기 전까지는 비트코인 ​​결제를 받지 마세요!

지금 0.3.6 버전으로 업그레이드할 수 없는 경우, 비트코인 ​​노드를 종료하고 업그레이드한 다음 다시 시작하는 것이 가장 좋습니다.

버전 0.3.6에서는 해시 연산 속도가 향상되었습니다.

  • tcatm 덕분에 중간 상태 캐싱 최적화가 구현되었습니다.
  • Crypto++ ASM SHA-256을 추가해 주신 BlackEye에 감사드립니다.

최종 가속 효과는 2.4배입니다.

다운로드 페이지:

http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.3.6/

Windows 및 Linux 사용자: 버전 0.3.5를 사용 중이더라도 버전 0.3.6으로 업그레이드해야 합니다.

— 사토시 나카모토, Bitcointalk 포럼(2010)

두 메시지의 표현이 다르다는 점에 유의해 주십시오. 첫 번째 메시지는 "(가짜 거래가) 네트워크에서 승인되었습니다."라고 되어 있는 반면, 두 번째 메시지는 "승인된 것으로 표시되었습니다."라고 되어 있습니다. 아마도 사토시 나카모토 실제 문제에 대한 관심을 피하기 위해 심각성을 축소했을 가능성이 있습니다. 어쨌든 0.3.6 버전으로 업그레이드한 사용자는 비트코인을 정상적으로 사용할 수 있습니다. 문제는 해결되었으며, 놀랍게도 아무도 비트코인을 잃지 않았습니다.

사토시 나카모토 의 메시지에는 채굴 성능 최적화에 대한 언급도 있었습니다. 왜 이것이 중요한 보안 패치에 포함되었는지는 불분명하지만, 실제 문제를 은폐하려는 의도였을 가능성도 있습니다. 하지만 그가 단순히 서브버전 코드베이스의 개발 브랜치(정확한 명칭은 알 수 없지만)에 보안 패치를 추가한 것일 가능성이 더 높아 보입니다.

그 당시에는 지금보다 비트코인 ​​사용자가 훨씬 적었고, 비트코인의 가치는 사실상 전무했습니다. 만약 그들이 오늘날 이와 같은 버그를 처리했다면, 엄청난 드라마로 여겨졌을 겁니다.

  • 사토시 나카모토 수정 사항이 포함된 바이너리 파일만으로 구성된 버전 0.3.5를 공개했습니다. 패치와 소스 코드가 포함되지 않은 것은 문제를 은폐하려는 의도로 해석될 수 있습니다.
  • 버전 0.3.5 는 실행조차 되지 않습니다 .
  • 0.3.6 버전의 수정 사항은 실제로 하드 포크 이며, 5.2절 ( 중국어 번역 )에서 설명되어 있습니다.

또 다른 논쟁거리는 사용자가 자신의 노드를 비활성화할 수 있도록 허용한 것이 좋은 일이었는지 나쁜 일이었는지에 대한 것입니다. 오늘날에는 그것이 불가능하지만, 당시에는 많은 사용자가 포럼 업데이트를 적극적으로 확인하고 관련 지식이 풍부했기 때문에 가능했고, 어쩌면 합리적인 조치였을지도 모릅니다.

9.2.2 2010년 8월 15일: 병합된 출력 값 오버플로 (CVE-2010-5139)

2010년 8월 중순, 비트코인토크 포럼 사용자 "jgarzik"(제프 가르직으로도 알려짐)은 블록 높이 74638의 거래 출력 중 두 개가 매우 높은 가치를 지니고 있음 을 발견했습니다 .

블록 #74638의 "출력"이 매우 이상합니다.

 "out" : [ { "value" : 92233720368.54277039, "scriptPubKey" : "OP_DUP OP_HASH160 0xB7A73EB128D7EA3D388DB12418302A1CBAD5E890 OP_EQUALVERIFY OP_CHECKSIG" }, { "value" : 92233720368.54277039, "scriptPubKey" : "OP_DUP OP_HASH160 0x151275508C66F89DEC2C5F43B6F9CBE0B5C4722C OP_EQUALVERIFY OP_CHECKSIG" } ]

92233720368.54277039 BTC요? 그건 그냥 UINT_64(부호 없는 64비트 정수)의 최댓값 아닌가요?

— 제프 가르직, 비트코인토크 포럼 (2010)

이는 두 출력값의 합이 Garzik이 예상했던 uint_64가 아닌 int64(부호 있는 64비트 정수)로 출력되어 -0.00997538 BTC라는 음수 값으로 오버플로우되는 버그 때문일 가능성이 매우 높습니다. 따라서 입력값과 관계없이 출력값의 합은 항상 더 작으므로 당시 코드상으로는 유효한 거래로 간주되었습니다.

이러한 맥락에서, 해당 버그는 대규모 공격으로 인해 공개되었습니다. 불행하게도 이 공격으로 인해 약 920억 BTC가 2배로 발행되어 당시 약 370만 BTC에 불과했던 통화 공급량이 심각하게 희석되었습니다.

관련 게시물에서 사토시 나카모토 누군가 채굴(당시에는 " 생성 "이라고 불렸음)을 중단해 준다면 감사할 것이라고 밝혔습니다.

사람들이 생산을 중단해 주시면 도움이 될 것 같습니다. 블록체인의 다른 분기를 채굴해야 할 수도 있는데, 현재 분기에서 생산 속도가 느려질수록 다른 분기를 더 빨리 구축할 수 있습니다.

첫 번째 패치는 SVN 리비전 132에 포함될 예정입니다. 아직 업로드되지 않았는데, 몇 가지 자잘한 변경 사항을 먼저 완료한 후 패치를 업로드하겠습니다.

— 사토시 나카모토, Bitcointalk 포럼(2010)

그의 계획은 위에서 언급한 것과 같은 거래를 무효화하는 소프트 포크 생성하여 그러한 거래가 포함된 블록(특히 높이 74638의 블록)을 무효화하는 것이었습니다. 한 달도 채 지나지 않아 그는 서브버전 코드베이스의 132번째 리비전에 패치를 제출 하고 포럼에 사용자들이 어떻게 해야 하는지에 대한 자신의 생각을 게시했습니다 .

해당 패치가 SVN 버전 132에 업로드되었습니다!

현재로서는 다음과 같은 조치가 권장됩니다.

1) 노드를 종료합니다.

2) "knightmb" blk 파일을 다운로드하세요(기존의 blk001.dat 및 blkindex.dat 파일을 대체할 파일입니다).

3) 소프트웨어를 업그레이드하십시오.

4) 소프트웨어는 74,000개 미만의 블록부터 동기화를 시작합니다. 나머지 블록을 다시 다운로드하도록 하십시오.

knightmb의 파일을 사용하고 싶지 않다면, "blk"로 시작하고 ",dat" 문자를 포함하는 blk*.dat 파일을 직접 삭제하면 됩니다. 하지만 모든 사용자가 동시에 모든 블록을 다운로드하면 네트워크에 과부하가 걸릴 수 있습니다.

곧 컴파일해서 배포하겠습니다.

— 사토시 나카모토, Bitcointalk 포럼(2010)

그는 사람들이 특정 사용자("kinghtmb")로부터 블록 데이터를 다운로드하기를 원했습니다. 이 사용자는 자신의 하드 드라이브에 있는 블록체인, 즉 blkXXXX.dat 및 blkindex.dat 파일을 게시했습니다. 블록 데이터를 처음부터 다시 동기화하는 대신 이러한 방식으로 다운로드하는 이유는 네트워크 대역폭 병목 현상을 줄이기 위해서였습니다.

여기서 심각한 문제가 발생합니다. 사용자가 knightmb에서 다운로드한 블록은 비트코인 ​​소프트웨어가 시작될 때 검증되지 않습니다. blkindex.dat 파일에는 이미 UTXO 세트가 포함되어 있으며, 소프트웨어는 해당 파일의 모든 데이터를 검증된 것으로 간주합니다. knightmb는 데이터를 조작하여 자신이나 다른 사람을 위해 인위적으로 비트코인을 추가할 수 있습니다.

(역자 주: 이러한 가능성은 존재합니다. 하지만 사용자가 색인 재구축 시작 옵션으로 소프트웨어를 실행하면 이 문제가 드러납니다. 궁극적으로 사용자가 이 두 파일을 교체한 후에는 소프트웨어가 시작 시 자동으로 재검증을 수행하지는 않지만, 사용자는 소프트웨어가 재검증을 수행하도록 할 수 있습니다.)

이번에도 조언이 받아들여진 듯, 잘못된 블록과 그 후속 블록들을 되돌리는 작업이 성공적으로 진행되었습니다. 채굴자들은 높이 74637 의 원래 블록 이후부터 채굴 시작했고, 첫 번째 후속 블록은 문제가 발견된 지 약 6시간 후인 23시 53분(UTC)에 생성되었습니다. 다음 날(8월 16일) 08시 10분, 높이 74689의 블록에서 새로운 체인이 기존 체인을 대체했고, 구형 소프트웨어를 사용하는 모든 노드는 새로운 체인을 따르도록 재구성되었습니다. 이는 비트코인 ​​역사상 가장 심층적인 블록 재구성으로, 총 52개 블록에 걸쳐 진행되었습니다.

OP_RETURN으로 인해 발생하는 문제와 비교하면, 이 접근 방식은 훨씬 더 현명하다고 할 수 있습니다.

  • 바이너리 파일뿐만 아니라 더 많은 내용을 포함하는 패치가 배포되었습니다.
  • 새로 출시된 소프트웨어는 예상대로 잘 작동하고 있습니다.
  • 하드 포크 없음

문제 해결 과정에서 사용자들에게 채굴 중단해달라는 요청이 있었습니다. 이것이 좋은 생각인지에 대해서는 논쟁의 여지가 있지만, 만약 당신이 채굴자이고, 불량 블록 이후에 채굴된 블록들이 결국 대규모 블록체인 재구성 과정에서 파괴될 것이라고 확신한다면, 왜 굳이 자원을 낭비하며 그런 블록들을 채굴해야 할까요?

사토시 나카모토 낯선 사람의 하드 드라이브에서 블록체인과 UTXO 세트를 다운로드하라는 제안이 어느 정도 그럴듯하다고 생각할 수도 있습니다. 만약 그렇다면, 당신의 생각은 맞습니다. 그 제안은 분명히 문제가 있습니다. 하지만 그런 상황에서는 그러한 비상 대응이 합리적일 수도 있습니다.

이번 사건은 OP_RETURN 사건과 상당히 다른데, 그 이유는 이번 사건에서는 취약점이 실제로 악용되어 보다 직접적인 수정이 가능했기 때문입니다. OP_RETURN 사건의 경우, 개발자들은 수정 사항을 숨겨야 했고, 공개 성명을 통해서도 문제를 직접적으로 드러낼 수 없었습니다.

9.2.3. 2013-03-11 DB 잠금 문제 0.7.2 - 0.8.0 (CVE-2013-3220)

2013년 3월, 매우 흥미롭고 유익한 문제가 발생했습니다. 당시 블록체인이 225429 높이 이후에 분기된 것으로 보였습니다(아래 인용문에서 "포크"는 이를 의미합니다). 이 사건에 대한 자세한 내용은 BIP50 문서에 공개되어 있으며 , 해당 문서는 이를 다음과 같이 요약합니다.

채굴되어 브로드캐스트된 블록에서 총 거래 입력 수가 이전에 관찰된 최대치를 초과했습니다. 비트코인 ​​0.8 노드는 이 블록을 처리할 수 있었지만, 0.8 이전 버전(pre-0.8)의 일부 비트코인 ​​노드는 이를 거부하여 예기치 않은 블록체인 포크 발생했습니다. 0.8 및 이전 버전과 호환되지 않는 체인(이하 "0.8 체인")은 채굴 해시레이트 의 60%를 집중시켜 이 분할을 자동으로 해결하는 것이 불가능해졌습니다. (만약 pre-0.8 체인의 해시레이트 0.8 체인을 압도할 수 있었다면, 0.8 노드들은 pre-0.8 온체인 으로 재집결하여 분할이 자동으로 해결되었을 것입니다.)

BTCGuild와 Slush는 정상적인 블록체인을 최대한 빨리 복원하기 위해 노드 소프트웨어를 비트코인 ​​0.8에서 0.7로 다운그레이드했습니다. 이로 인해 채굴 풀은 더 큰 블록을 거부하게 되었고, 대부분의 해시레이트 더 큰 블록이 없는 온체인 으로 복귀하여 궁극적으로 0.8 노드들이 0.8 이전 온체인 으로 재구성될 수 있었습니다.

— 비트코인 ​​코어 개발자 여러 명, BIP50(2013)

이번 위기 동안 BTCGuild와 Sluch 마이닝 풀이 보여준 신속한 조치는 인상적이었습니다. 그들은 대부분의 해시레이트 0.8 이전 분기로 이전하여 합의 재구축을 도왔습니다. 덕분에 개발자들은 지속 가능한 해결책을 마련할 시간을 벌 수 있었습니다.

이 경우 또 다른 흥미로운 문제는 버전 0.7.2가 이전 버전들과 마찬가지로 자체적으로 호환되지 않는다는 점입니다. 이는 BIP50의 "근본 원인" 섹션 에서 설명되어 있습니다.

이처럼 불충분한 BDK 잠금 구성은 블록의 유효성을 판단하는 네트워크 합의 규칙으로 암묵적으로 적용됩니다(다만, 이는 노드마다 사용되는 잠금량이 다를 수 있으므로 일관성이 없고 안전하지 않은 규칙입니다).

— 비트코인 ​​코어 개발자 여러 명, BIP50(2013)

간단히 말해, 문제는 Bitcoin Core 소프트웨어가 블록 검증에 사용하는 데이터베이스 잠금의 개수가 확정적이지 않다는 것입니다. 어떤 노드는 X개의 잠금이 필요할 수 있지만, 다른 노드는 X+1개의 잠금이 필요할 수도 있습니다. 또한 노드가 블록에 대해 보유할 수 있는 잠금의 개수에도 제한이 있습니다. 필요한 잠금 개수가 이 제한을 초과하면 해당 블록은 무효로 간주됩니다. 따라서 X+1이 제한을 초과하지만 X는 초과하지 않는 경우, 두 노드는 각각 다른 분기로 나뉘어 어떤 분기가 유효한지에 대해 의견 차이를 보이게 됩니다.

위에서 언급한 두 주요 채굴 풀에서 취한 긴급 조치 외에도 최종적으로 선정된 해결책에는 다음 사항들이 포함되었습니다.

  • 버전 0.8.1에서는 블록의 크기뿐만 아니라 블록에 포함될 수 있는 잠금의 개수에도 제한이 있습니다.
  • 이 패치는 이전 버전(0.7.2 및 일부 이전 버전)이 동일한 새 규칙을 사용하도록 수정하는 동시에 전역 잠금 제한을 강화합니다.

2번 항목에서 언급한 것처럼 전역 잠금 제한을 늘리는 것 외에도, 이러한 규칙은 미리 정해진 기간 동안만 사용되는 임시 규칙으로 구현됩니다. 대다수 노드의 업그레이드가 완료되면 이러한 제한을 제거할 계획입니다.

이 소프트 포크 합의 실패 리스크 크게 줄였고, 몇 달 후인 5월 15일에는 임시 규칙이 네트워크 전체에서 일괄적으로 비활성화되었습니다. 이 비활성화는 사실상 하드 포크 와 같은 조치였지만, 논란 없이 진행되었습니다. 또한, 이전 소프트 포크 와 함께 발표되었기 때문에 소프트 포크 이후에 소프트웨어를 실행하는 노드들은 하드 포크 뒤따를 것이라는 사실을 알고 있었습니다. 따라서 하드 포크 활성화되었을 때 대다수의 노드는 동기화 상태를 유지했습니다. 그러나 업그레이드를 하지 않은 소수의 노드는 이 과정에서 네트워크에서 퇴출되었습니다.

혹시 이런 생각이 드시나요? 만약 이런 일이 오늘날 발생했다면, 우리가 여전히 이런 방식으로 처리할 수 있었을까요? 현재 채굴 환경은 훨씬 더 복잡해졌습니다. 분기된 브랜치의 양쪽 모두 해시 해시레이트 보유하고 있을 수 있어 BIP50처럼 빠르게 패치를 배포하기 어렵습니다. 또한, "잘못된" 브랜치의 채굴자들이 블록 보상을 포기하도록 설득하는 것도 쉽지 않을 것입니다.

9.2.4 BIP66

BIP66은 다음과 같은 점들의 중요성을 보여주기 때문에 흥미롭습니다.

  • 우수한 선택적 암호화
  • 정당한 정보 공개
  • 취약점을 노출하지 않고 수정 사항을 배포하세요
  • 검증된 블록에서 채굴

BIP66은 비트코인 ​​스크립트에 포함된 서명의 인코딩 규칙을 강화하기 위한 제안이었습니다. 이 제안의 목적은 OpenSSL 외의 다른 소프트웨어 및 코드 라이브러리를 사용하여 서명을 파싱할 수 있도록 하는 것이었습니다(이전에는 OpenSSL 최신 버전만 사용할 수 있었습니다). OpenSSL은 범용 암호화 코드 라이브러리이며, 당시 Bitcoin Core 여전히 사용되고 있었습니다.

이 BIP는 2015년 7월 4일에 활성화되었습니다. 하지만 위에서 언급한 내용 외에도, BIP66은 원래 BIP에는 언급되지 않았던 훨씬 더 심각한 문제를 해결했습니다.

취약성

이 취약점은 2015년 7월 28일 피터 윌레가 비트코인 ​​개발자 메일링 리스트에 보낸 이메일을 통해 비로소 완전히 공개되었습니다.

여러분, 안녕하세요,

2014년 9월에 발견한 취약점을 공개하고자 합니다. 이 취약점은 이달 초 BIP66 배포율이 95%에 도달한 이후로 더 이상 악용될 수 없게 되었습니다.

간략한 설명

특수하게 설계된 거래는 블록체인을 다음 세 가지 유형의 노드로 분할할 수 있습니다.

  • 32비트 및 64비트 Windows 시스템에서 OpenSSL을 사용하는 노드
  • Windows 이외의 64비트 시스템(Linux, OSX 등)에서 OpenSSL을 사용하는 노드
  • 서명 노드를 파싱하기 위해 OpenSSL이 아닌 다른 코드베이스를 사용하세요.

— 피터 윌레, "공개: BIP66에서 직접 해결된 합의 버그", Bitcoin-dev 메일링 리스트(2015)

이메일에는 취약점 발견 과정과 그 발견으로 이어진 구체적인 이유가 자세히 설명되어 있습니다. 마지막으로 피터는 사건의 시간 순서를 제시합니다. 그림 13에 나타난 것처럼 가장 중요한 사건들을 몇 가지 살펴보겠습니다. 이 중 일부는 이미 앞서 논의된 내용입니다.

bip66-타임라인-1

그림 13. BIP66을 둘러싼 사건들의 시간 순서. 굵게 표시된 부분은 위에서 설명한 내용입니다.

공개 전

누구도 이 문제를 알기 전에, 현재는 철회된 BIP62를 통해 해결할 수 있었을 것입니다. 이 BIP는 거래 변조 가능성을 줄이는 것을 목표로 했습니다. BIP62에서 제안된 변경 사항 중 하나는 서명 인코딩, 즉 "엄격한 DER 인코딩"에 대한 합의 규칙을 강화하는 것이었습니다. 피터 윌레는 2014년 7월에 이 문제를 해결할 수 있는 몇 가지 수정안을 BIP62에 제안했습니다.

  • 2014년 7월 18일: 비트코인의 서명 인코딩 규칙을 특정 OpenSSL 파서에 종속되지 않도록 하기 위해, BIP32 제안을 수정하여 엄격한 분산 에너지(DER) 서명 요구 사항이 버전 번호 1의 트랜잭션에도 적용되도록 했습니다. 당시에는 DER이 아닌 서명은 블록에 포함되지 않았기 때문에 직접적인 영향은 없을 것으로 예상되었습니다. 자세한 내용은 https://github.com/bitcoin/bips/pull/90http://lists.linuxfoundation.org/pipermail/bitcoin-dev/2014-July/006299.html을 참조하십시오. 당시에는 알려지지 않았지만, BIP66이 배포되면 이 취약점이 해결될 것입니다.

— 피터 윌레, "공개: BIP66에서 직접 해결된 합의 버그", Bitcoin-dev 메일링 리스트(2015)

이 BIP의 적용 범위가 너무 넓어 "엄격한 DER 코딩" 요건을 훨씬 초과했기 때문에 지속적으로 수정되었고 배포가 지연되었습니다. 이후 "분리된 증인" BIP141이 거래 오류 문제를 보다 완벽하게 해결하면서 이 BIP는 네트워크화되었습니다.

공개 후

OpenSSL은 패치가 포함된 새 버전의 소프트웨어를 출시했습니다. 처음부터 Bitcoin ​​소프트웨어에 이 패치(새 소프트웨어)를 사용하면 문제가 해결될 것입니다. 그러나 단순히 Bitcoin Core 의 새 버전에 OpenSSL의 새 버전을 사용하는 것만으로는 문제가 악화될 수 있습니다. 그레고리 맥스웰은 2015년 1월 다른 메일링 리스트 에서 이 점을 설명했습니다.

대부분의 애플리케이션에서 특정 서명을 강력하게 거부하는 것은 일반적으로 허용되지만, 비트코인은 합의 시스템이므로 모든 참여자가 입력 데이터의 유효성 또는 무효성에 대해 동의해야 합니다. 즉, "정확성"보다 "일관성"이 더 중요합니다.

...

하지만 위의 패치는 이 광범위한 문제의 한 가지 증상만 해결할 뿐입니다. 합의 명세의 동작은 합의 목적으로 설계 및 배포되지 않은 소프트웨어(특히 OpenSSL)에 의존합니다. 따라서 점진적인 개선 방안으로, BIP62의 일부 기능만 사용하는 전용 소프트 포크 통해 가능한 한 빨리 더욱 엄격한 DER 호환성을 적용하는 것을 제안합니다.

— 그레고리 맥스웰, OpenSSL 업그레이드 관련, 비트코인 ​​개발자 메일링 리스트

그는 합의 시스템에서 사용될 목적으로 만들어지지 않은 코드를 사용하는 것은 심각한 리스크 초래한다고 지적하며 비트코인이 엄격한 분산 에너지 자원(DER) 인코딩을 구현해야 한다고 제안했습니다. 이는 선택적 암호화의 중요성을 보여주는 훌륭한 사례이며, 이 내용은 7.4장 에서 논의했습니다( 중국어 번역 ).

이러한 사건들을 보면 그레고리 맥스웰이 피터 윌리가 나중에 밝힌 취약점에 대해 알고 있었지만, 진짜 문제에 대한 관심을 끌지 않기 위해 "예방"이라는 명목으로 이를 은폐하려 했다는 인상을 받을 수도 있습니다. 그럴 가능성도 있지만, 모두 추측일 뿐입니다.

맥스웰이 제안한 대로 BIP66은 엄격한 분산 에너지 자원(DER) 인코딩만을 명시하는 BIP62의 하위 집합으로 제시되었습니다. 이 BIP는 널리 수용되어 7월에 배포되었지만, 아이러니하게도 " 검증 없는 채굴"로 인해 두 차례의 블록체인 분할이 발생했습니다. 이러한 분할에 대해서는 다음 섹션에서 자세히 살펴보겠습니다.

bip66-타임라인-2

이는 중요한 결론으로 ​​이어집니다. BIP는 어느 정도 원자적 이어야 합니다. 즉, 유용한 기능을 제공하거나 특정 문제를 해결할 만큼 충분히 완전해야 하지만, 사용자들이 널리 지적할 수 있을 만큼 충분히 작아야 합니다. BIP에 너무 많은 것을 담을수록 수용될 가능성은 낮아집니다.

검증되지 않은 채굴 로 인해 블록체인이 분할되었습니다.

불행히도 BIP66 관련 이야기는 여기서 끝나지 않습니다. BIP66 활성화는 극심한 혼란을 야기했는데, 일부 채굴자들이 블록을 수신하자마자 검증하지 않고 곧바로 채굴 시작했기 때문입니다. 이를 "검증 없는 채굴" 또는 "SPV 채굴"이라고 합니다(SPV는 "간소화된 결제 검증(Simplified Payment Verification)"의 약자로, 블록 헤더만 검증합니다). 비트코인 ​​노드에는 이 문제를 설명하는 웹페이지 와 함께 경고 메시지가 전송되었습니다.

2015년 7월 4일 이른 아침, (BIP66)은 95%(950/1000) 임계값에 도달했습니다. 그러나 얼마 지나지 않아 예상대로 소규모 채굴자(업그레이드를 하지 않은 5% 중 하나)가 무효 블록을 채굴했습니다. 불행히도 네트워크 채굴 해시레이트 의 약 절반이 불완전한 블록 검증 설정(이른바 "SPV 채굴 ")으로 채굴 있었고, 이로 인해 해당 무효 블록 이후에도 새로운 블록이 채굴되고 있었던 것으로 밝혀졌습니다.

— bitcoin.org에 게시된 비트코인 ​​코어 개발자들의 경고 메시지 (2015)

이 경고 페이지는 사용자가 이전 버전의 Bitcoin Core 사용하는 경우 일반적인 자발적 블록 확인 요구 사항 외에 추가로 30개 블록을 기다려야 한다고 안내합니다.

앞서 언급한 분기는 2015년 7월 4일 02:10 UTC, 블록 높이 363730 이후에 발생했습니다. 이 문제는 같은 날 03:50에 해결되었지만, 그 전에 6개의 무효 블록이 채굴되었습니다. 그러나 안타깝게도 동일한 문제가 다음 날인 7월 5일 21:50에 다시 발생했으며, 이번에는 무효 분기가 단 3개의 블록 동안만 지속되었습니다.

bip66-타임라인-3

BIP66의 생성 및 배포로 이어진 사건들과 그 이후의 사태들은 비트코인 ​​개발자들이 왜 신중을 기해야 하는지를 보여주는 훌륭한 사례 연구입니다. BIP66 사건에서 얻을 수 있는 몇 가지 핵심적인 결론은 다음과 같습니다.

  • 취약점을 공개하는 것과 비공개하는 것 사이에서 균형을 찾는 것은 매우 섬세한 문제입니다.
  • 공개되지 않은 취약점에 대한 수정 사항을 배포하는 것은 매우 까다로운 작업입니다.
  • 합의를 유지하는 것은 쉽지 않다.
  • 합의 시스템에서 사용될 목적으로 개발되지 않은 소프트웨어는 종종 리스크 초래할 수 있습니다.
  • BIP는 어느 정도 분무되어야 합니다.

9.3 결론

비트코인에는 버그가 있습니다. 버그를 발견한 사람들은 비트코인 ​​개발자들이 버그가 공개되기 전에 수정할 수 있도록 책임감 있게 버그를 알려줄 것을 권장합니다. 이상적으로는 버그 수정이 성능 개선이나 다른 명분으로 위장될 수 있습니다.

지난 몇 년 동안 드러난 심각한 취약점 몇 가지와 이를 해결하기 위해 취해진 조치들을 검토했습니다. 일부 취약점은 악용되면서 드러났지만, 다른 취약점들은 악의적인 공격자들이 악용하기 전에 사전에 공개되고 패치되었습니다.

출처
면책조항: 상기 내용은 작자의 개인적인 의견입니다. 따라서 이는 Followin의 입장과 무관하며 Followin과 관련된 어떠한 투자 제안도 구성하지 않습니다.
라이크
즐겨찾기에 추가
코멘트