배경
Blast는 Blur의 창립자인 Pacman(Tieshun Roquerre, 일명 Tieshun)이 출시한 이더리움 레이어 2 네트워크로, 지난 2월 29일 메인넷을 출시했으며, 현재 Blast 메인넷에는 약 19,500 ETH와 640,000 stETH가 약속되어 있습니다.
공격을 받은 프로젝트인 Munchables는 Blast가 주최한 빅뱅 대회에서 우승한 프리미엄 프로젝트였습니다.
Blast 관계자는 Blast 메인넷에서 ETH를 약속한 사용자에게 일반 포인트를 발급합니다.
사용자가 Blast 생태계의 DeFi 프로젝트에 참여하도록 장려하기 위해 Blast 관계자는 추천을 위해 고품질 프로젝트를 선택하고 사용자가 더 빠른 포인트 증가 및 골드 포인트를 얻기 위해 DeFi에 두 번째로 ETH를 약속하도록 권장합니다. Blast 메인 네트워크에서 약속된 ETH를 새로 생성된 DeFi 프로젝트에 약속한 사용자는 거의 없습니다.
이러한 DeFi 프로젝트의 성숙도와 보안은 아직 조사되지 않았으며 이러한 계약에 사용자의 수천만 달러, 심지어 수억 달러를 보호할 수 있는 충분한 보안 고려 사항이 있는지 여부도 조사되지 않았습니다.
이벤트 개요
Blast 메인넷이 온라인에 접속한 지 한 달도 채 되지 않아 2024년 3월 21일 SSS 토큰(Super Sushi Samurai)에 대한 공격이 발생했습니다. 토큰 계약에 전송 논리 오류가 있어 공격자가 SSS 토큰을 늘릴 수 있었습니다. 특정 계정의 잔액이 부족해 프로젝트는 결국 1,310 ETH(약 460만 달러) 이상을 잃었습니다.
SSS 토큰 공격이 발생한 지 일주일도 채 되지 않아 Blast에서 또 다른 대규모 공격이 발생했는데, Munchables 프로젝트는 17413.96 ETH, 총 약 6250만 달러에 달하는 공격자들에 의해 휩쓸려갔습니다.
공격 거래가 발생한 지 30분 만에 프로젝트 계약에 포함된 73.49 WETH도 해커에 의해 다른 주소로 도난당했습니다.
현재 프로젝트 당사자의 컨트랙트 주소에는 여전히 7276 WETH, 7758267 USDB, 4 ETH가 저장되어 있어 언제든지 해커들의 손에 넘어갈 것이며, 해커는 프로젝트 당사자의 모든 자금을 탈취할 수 있는 권한을 가지고 있습니다. 전체 프로젝트 규모는 약 9,700만 달러로 위험에 노출되어 있습니다.
사건 직후, X의 유명 온체인 탐정인 zachXBT(트위터)는 이번 공격의 근본 원인이 특정 국가 출신의 해커를 고용한 것이라고 지적했다.
특정 국가의 해커가 어떻게 1억 달러에 가까운 공격을 완료했는지 자세히 살펴보겠습니다.
현장 복원
피해자들이 목소리를 내고 있다
[UTC+ 0 ] 2024년 3월 26일 21시 37분(공격 5분 후), Munchables는 X(트위터)에 공격을 받고 있음을 공식적으로 게시했습니다.
온체인 형사 Zach의 조사에 따르면 공격자는 게임 개발 작업을 하러 왔습니다. 그는 매우 거칠고 정말 중국 해커처럼 보였습니다. 우리는 그를 한 달 만에 해고했습니다. 그는 또한 우리에게 자신의 직원을 고용하려고 했습니다. 아마 해커이기도 한 친구들. 해커.
이번 공격으로 인해 커뮤니티 내 사용자들에게 큰 손실이 발생했기 때문에 우리는 즉시 온체인 조사에 착수했습니다.이 “특정 국가의 해커”의 공격 세부 내용을 심층적으로 살펴보겠습니다.
첫 번째 장면
[UTC+ 0 ] 2024년 3월 26일 21시 32분에 17413.96 ETH와 관련된 공격이 발생했습니다.
Blastscan을 통해 이 공격 트랜잭션을 볼 수 있습니다: https://blastscan.io/tx/0x9a7e4d16ed15b0367b8ad677eaf1db6a2a54663610696d69e1b4aa1a08f55c95
손상된 계약(0x 29..1 F)은 사용자가 약속한 자금을 저장하는 대리 계약으로, 공격자가 약속 계약의 잠금 해제 기능을 호출하고 모든 권한 확인을 통과한 후 전송한 것을 확인할 수 있습니다. 계약은 공격자 주소 1(0x 6 E..c 5)로 이동합니다.
공격자는 출금과 유사한 동작으로 잠금 해제 기능을 호출하고 손상된 계약(0x 29..1 F)에서 ETH의 대부분을 빼앗은 것으로 보입니다.
프로젝트 당사자가 금고를 잠그는 것을 잊었나요?
손상된 컨트랙트(0x 29..1 F)에는 Unlock 관련 검사가 2개 있는데, 하나씩 살펴보겠습니다.
먼저, 권한 확인 과정에서 현재 msg.sender, 즉 해커 주소 1(0x 6 E..c)인지 확인하기 위해 컨트랙트(0x 16..A 0)의 isRegistered 메소드가 호출되는 것을 발견했습니다. 5) 이미 등록된 항목:
대답은 다음과 같습니다. 검증을 통과했습니다.
여기에는 계약(0x 16..A 0) 및 해당 최신 논리 계약(0x e 7..f 1)이 포함됩니다.
[UTC+ 0 ] 2024년 3월 24일(공격 2일 전) 08:39에 컨트랙트(0x 16..A 0)에 해당하는 논리적 컨트랙트가 업그레이드되었습니다.
논리적 계약 업그레이드 트랜잭션:
https://blastscan.io/tx/0x9c431e09a80d2942319853ccfdaae24c5de23cedfcef0022815fdae42a7e2ab6
논리 계약은 0x e 7..f 1 로 업데이트됩니다.
원래 논리 계약 주소는 여기에서 볼 수 있으며, 이는 0x 9 e..CD입니다.
https://blastscan.io/tx/0x7ad050d84c89833aa1398fb8e5d179ddfae6d48e8ce964f6d5b71484cc06d003
이때 해커는 프록시 계약의 논리 구현 계약을 업데이트하고 0x9 e..CD를 악성 0xe 7..f 1로 변경하여 검증 권한 우회를 완료한 것으로 의심됩니다.
진짜야?
Web3.0에서는 다른 사람의 말을 추측하거나 들을 필요가 없으며 기술을 익히기만 하면 스스로 답을 얻을 수 있습니다.
두 계약(오픈 소스 계약 아님)을 비교하면 원래 0x 9 e..CD 계약과 업데이트된 0x e 7..f 1 사이에 몇 가지 명백한 차이점이 있습니다.
0x e 7..f 1의 초기화 함수 부분은 다음과 같이 구현됩니다.
0x 9 e..CD의 초기화 기능 부분은 다음과 같이 구현됩니다.
공격자는 원래 논리 계약(0x 9 e..CD)에 레지스터로 공격자 주소(0x 6 e..c 5)를 설정했으며, 다른 두 개의 공격자 주소 0x c 5 ..0도 있음을 알 수 있습니다. d, 0x bf..87도 등록되어 있으며 해당 필드 0은 초기화 시 블록 시간으로 설정됩니다. 필드 0의 용도는 나중에 설명합니다.
사실 우리가 추측한 것과는 달리 백도어를 이용한 실제 로직 컨트랙트는 처음부터 존재했고, 이후의 업데이트도 정상이었습니다!
잠깐, 이 업데이트는 2024년 3월 24일 [UTC+ 0] 08:39(공격 2일 전)에 나타났습니다. 즉, 이번 사건 이전에는 논리 계약이 백도어 없는 계약으로 되어 있었습니다. 왜일까요? 공격자는 여전히 완료할 수 있습니까? 공격?
이는 델리게이트 콜 때문이므로 실제 상태 저장 업데이트는 컨트랙트(0x 16..A 0)에 있기 때문에 나중에 로직 컨트랙트를 백도어 없이 로직 컨트랙트로 업데이트하더라도 0xe 7..이 되는 결과를 낳게 됩니다. f 1 , 계약의 변경된 슬롯(0x 16..A 0)은 여전히 복원되지 않습니다.
확인해 봅시다:
보시다시피 계약의 해당 슬롯(0x 16....A 0)에는 값이 있습니다.
이를 통해 공격자는 isRegistered 메소드 검사를 통과할 수 있습니다.
공격자는 나중에 백도어가 이미 설치되어 있다는 사실을 숨기기 위해 백도어 계약을 일반 계약으로 변경합니다.
또한 잠금 해제 프로세스에는 두 번째 확인도 포함됩니다.
잠금 시간 확인과 관련하여, 이 부분은 잠긴 자산이 만료되기 전에 이동되지 않도록 하기 위한 것입니다.
공격자는 잠금 해제가 호출될 때의 블록 시간이 필요한 잠금 만료 시간(필드 3)보다 큰지 확인해야 합니다.
이 확인 부분에는 손상된 계약(0x 29..1 F)과 해당 논리적 계약 0x f 5..cd가 포함됩니다.
2024년 3월 21일 [UTC+ 0](공격 5일 전) 11시 54분의 거래에서,
https://blastscan.io/tx/0x3d08f2fcfe51cf5758f4e9ba057c51543b0ff386ba53e0b4f267850871b88170
손상된 계약(0x 29..1 F) 계약의 원래 논리적 계약은 0x 91..11이었고 불과 4분 후인 것을 알 수 있습니다.
https://blastscan.io/tx/0xea1d9c0d8de4280b538b6fe6dbc3636602075184651dfeb837cb03f8a19ffc4f
0x f 5..cd로 업그레이드되었습니다.
또한 두 계약을 비교한 결과 공격자가 이전과 마찬가지로 초기화 기능에도 트릭을 적용한 것을 확인할 수 있습니다.
0x f 5..cd의 초기화 기능 부분 구현:
0x 91..11의 초기화 기능 부분 구현:
동일한 수법으로 다시 ETH 수량과 잠금 해제 시간을 조작하고, 이를 일반 계약으로 대체해 타인을 속이는 것을 볼 수 있으며, 프로젝트 팀과 보안 연구원들이 디버깅을 할 때 모두 보이는 논리적 계약은 정상적인 것이며, 그 계약은 모두 오픈소스가 아닌 계약이기 때문에 문제의 핵심을 명확하게 보기는 더욱 어렵습니다.
지금까지 우리는 17413 ETH가 포함된 이 거래와 공격자가 어떻게 이를 수행했는지 이해하고 있지만, 이 사건 뒤에는 이 정도의 정보만 있는 걸까요?
위의 분석에서 실제로 해커가 계약서에 3개의 주소를 구축한 것을 확인했습니다.
0x 6 e..c 5(공격자 주소 1)
0x c 5..0 d (공격자 주소 2)
0x bf..87(공격자 주소 3)
그런데 위에서 찾은 공격 트랜잭션에서는 0x 6 e..c 5만 보았는데, 나머지 두 주소는 무엇을 하였나요? 그리고 address(0), _dodoApproveAddress 및 _uniswapV3Factorty에는 어떤 비밀이 숨겨져 있나요?
두 번째 장면
먼저 같은 방법으로 73.49 WETH를 훔친 공격자 주소 3(0x bf..87)을 살펴보겠습니다.
https://blastscan.io/tx/0xfc7bfbc38662b659bf6af032bf20ef224de0ef20a4fd8418db87f78f9370f233
그리고 가스의 소스 주소(0x 97..de)를 공격하고, 0x c 5..0 d(공격자 주소 2)와 0x bf..87(공격자 주소 3) 모두에 처리 수수료를 제공합니다.
가스 소스 주소(0x 97..de)를 공격하는 0.1 ETH의 소스는 owlto.finance(크로스체인 브리지)에서 나옵니다.
0x c 5..0 d(공격자 주소 2)는 처리 수수료를 받은 후 어떠한 공격도 수행하지 않았지만 실제로는 숨겨진 계획을 가지고 있었습니다. 계속해서 살펴보겠습니다.
실제로 공식 구제 거래에 따르면 손상된 계약의 원래 주소(0x 29..1 F)는 73.49 WETH만이 아니었고, 공격이 끝날 때까지 여전히 7276.5 WETH 7758267 USDB가 있었습니다.
구출 거래:
https://blastscan.io/tx/0x1969f10af9d0d8f80ee3e3c88d358a6f668a7bf4da6e598e5be7a3407dc6d5bb
공격자는 원래 이 자산을 훔칠 계획이었으며, 주소 0x c 5..0 d(공격자 주소 2)가 원래 USDB를 훔치는 데 사용되었음을 알 수 있습니다.
여기의 _dodoApproveAddress는 0x0000000000000000000000004300000000000000000000000000000000000003입니다.
usdb 주소입니다
0x bf..87(공격자 주소 3) 이 주소는 Weth를 훔치는 데 사용됩니다.
여기의 _uniswap V3 팩토리는 0x00000000000000000000000043000000000000000000000000000000000000004입니다.
웨스 주소예요
그리고 0x 6 e..c 5(공격자 주소 1)는 네이티브 자산인 ETH인 주소(0)를 훔치는 역할을 합니다.
필드 0을 설정하면 공격자는 다음 논리를 통해 해당 자산을 훔칠 수 있습니다.
질문
공격자가 모든 자산을 훔치지 않은 이유는 무엇입니까?
이론적으로 그는 나머지 WETH와 USDB인 모든 자산을 훔칠 수 있습니다.
0x bf..87(공격자 주소 3)은 73.49 WETH만 훔쳤습니다. 0x bf..87(공격자 주소 3)은 실제로 7350 WETH를 모두 가져갈 수 있거나 0x c 5..0 d(공격자 주소 2)가 가져간 것을 사용할 수 있습니다. 7758267 USDB를 모두 가져갔습니다. WETH를 조금만 가져간 후 중지된 이유는 무엇인지 모르겠습니다. 심층적인 내부 조사를 수행하려면 유명한 연쇄 탐정이 필요할 수도 있습니다.
https://blastscan.io/tx/0xfc7bfbc38662b659bf6af032bf20ef224de0ef20a4fd8418db87f78f9370f233
공격자는 왜 17413 ETH를 이더리움 메인넷으로 전송하지 않았나요?
우리 모두 알고 있듯이 Blast 메인 네트워크는 중앙 집중식 방법을 통해 이러한 ETH를 가로채어 사용자에게 큰 손실을 입히지 않고 영구적으로 여기에 머물게 하는 것이 가능합니다. 그러나 이러한 ETH가 이더리움 메인 네트워크에 들어가면 가로챌 수 있는 방법이 없습니다. 그것.
현재 Blast 교차교량을 평가했는데 공식 교차교량 수에는 제한이 없지만 종료하는 데 14일이 소요되며 이는 Blast 관계자가 차단 계획을 준비하는 데 충분합니다.
제3자 크로스체인 브리지는 공격자의 수수료 소스와 마찬가지로 거의 실시간으로 적립될 수 있으며 신속하게 크로스체인을 완료할 수 있습니다. 공격자는 왜 즉시 크로스체인을 수행하지 않았습니까?
실제로 공격자는 첫 순간(공격 후 2분 이내)에 크로스체인을 수행했습니다.
https://blastscan.io/tx/0x10cf2f2b884549979a3a1dd912287256229458ef40d56df61738d6ea7d9d198f
게다가 자금이 이더리움 메인 네트워크에 도착하는 데 20초가 걸렸습니다. 이론적으로 공격자는 크로스체인 브리지가 수동으로 개입하기 전에 계속해서 크로스체인을 수행하고 체인 간에 대량의 ETH를 전송할 수 있습니다.
한 번에 3 ETH만 가능한 이유는 Blast에서 ETH까지 크로스체인 브리지의 유동성 제한 때문입니다.
Blast를 지원하는 또 다른 크로스체인 브리지는 다음보다 더 적은 지원도 지원합니다.
이번 크로스체인 거래 이후, 공격자는 다른 크로스체인 작업을 계속하지 않았으며, 그 이유는 알려지지 않았으며, 특정 국가의 해커가 Blast 자금 인출에 대한 적절한 준비를 하지 않은 것으로 보입니다.
공격 후에 무슨 일이 일어났는가
커뮤니티 사용자 Nearisbuilding의 피드백을 바탕으로 그는 공격자의 더 많은 신원 정보를 발견하고 공격자가 자금을 반환하도록 유도하는 방법을 찾았습니다.
https://twitter.com/Nearisbuilding/status/1772812190673756548
결국 암호화 커뮤니티의 관심과 노력으로 특정 국가의 해커는 자신의 신원이 노출될까 봐 두려워서 위 3개의 공격자 주소의 개인 키를 프로젝트 측에 제공하고 모두 반환했습니다. 프로젝트 당사자도 구출 거래를 진행했으며 손상된 계약서의 모든 자금을 다중 서명 계약서로 이체하여 보관합니다.