2023년 12월 8일, OpenZeppelin은 공식적으로 커뮤니티에 중요한 보안 경고를 발표했습니다. 경고는 프로젝트 통합에서 멀티콜과 유사한 방법으로 ERC-2771 표준을 사용할 때 임의 주소 스푸핑 공격의 위험이 있을 수 있음을 지적합니다.
SharkTeam은 이번 사건에 대해 즉시 기술적 분석을 실시하고 보안 예방 조치를 요약했으며, 후속 프로젝트가 이를 통해 교훈을 얻고 블록체인 업계의 보안 방어선을 공동으로 구축할 수 있기를 바랍니다.
1. 공격 거래 분석
본 취약점과 관련된 일련의 공격 트랜잭션이 있으므로 분석을 위해 공격 트랜잭션 중 하나를 선택했습니다.
공격자 주소:
0xFDe0d1575Ed8E06FBf36256bcdfA1F359281455A
공격 트랜잭션:
0xecdd111a60debfadc6533de30fb7f55dc5ceed01dfadd30e4a7ebdb416d2f6b6
공격 프로세스:
1. 첫째. 공격자(0xFDe0d157)는 처음에 5 WETH를 사용하여 약 3, 455, 399, 346 TIME을 교환했습니다.
2. 이후 공격자(0xFDe0d157)는 악성 calldata 매개변수를 구성하고 [Forwarder].execute 함수를 호출했습니다.
3. [Forwarder].execute 함수 호출 시 악성 호출 데이터가 TIME 컨트랙트의 다중 호출 기능을 작동시켰습니다. 그 후, 나머지 콜데이터는 풀의 TIME 토큰을 파괴하기 위해 TIME 계약의 소각 기능을 트리거하는 데 사용됩니다.
2. 취약점 분석
우선, 이 공격은 주로 ERC 2771, 다중 호출, 신중하게 구성된 호출 데이터 등 여러 측면을 포함합니다. TIME 토큰 계약에서 관련 상속을 찾을 수 있습니다.
1. ERC 2771은 가상 msg.sender를 갖는 기능을 제공하여 사용자가 가스 비용을 줄이기 위해 트랜잭션을 실행하도록 제3자[Forwarder]에 맡길 수 있습니다. 트랜잭션이 제출되면 msg.sender 주소가 calldata에 추가됩니다.
2.TIME 토큰 계약은 ERC2771Context를 상속합니다. [Forwarder]가 계약을 호출하면 _msgSender()는 호출 데이터 데이터를 확인하고 오른쪽으로 이동하여 예상 msg.sender로 마지막 20바이트를 자릅니다.
3.Multicall은 단일 함수 호출을 동일한 계약에서 순차적으로 호출되는 여러 함수로 변환하는 방법입니다. 이는 사용자가 코딩한 호출 배열을 수락하고 자체 계약을 실행합니다. 이 함수는 호출 배열을 반복하고 각 작업에 대해 Delegatecall()을 수행합니다. 이를 통해 사용자는 프로토콜에서 특정 작업 조합을 미리 정의할 필요 없이 자신의 일련의 작업을 결합하고 동일한 트랜잭션에서 순차적으로 실행할 수 있습니다. 주요 목적은 가스를 절약하는 것입니다.
4. 신중하게 구성된 호출 데이터에 대해 공격자는 [Forwarder].execute 함수를 호출하고 관련 매개 변수를 전달했습니다.
이에 따라 읽기 쉬운 방식으로 데이터 값의 형식을 지정하고 다음을 얻습니다.
공격자(0x FDe 0 d 157)는 현재 calldata의 offset 연산을 통해 새로운 데이터 값을 획득하고 그 값을 multicall(bytes[]) 함수에 전달한다. 새 데이터의 처음 4바이트는 burn(단위 256) 함수의 선택자이며 amount 매개변수는 62227259510000000000000000000입니다.
5. multicall(bytes[]) 함수에서 Delegatecall을 통해 burn(uint 256) 함수를 호출합니다. 0x20 라인에는 calldata를 구성할 때 처음에 주소 0x760dc1e043d99394a10605b2fa08f123d60faf84가 끝에 추가됩니다. 이 주소는 위에서 언급한 예상 msg.sender인 Uniswap v2의 TIME-ETH 유동성 풀에 해당합니다.
6. 방금 언급한 msg.sender가 왜 TIME-ETH 유동성 풀 주소가 되었나요? 그 이유는 msg.sender가 처음에 [Forwarder] 계약 주소이기 때문입니다. 신뢰할 수 있는 [Forwarder]인지 확인하기 위해 신뢰할 수 있는 [Forwarder]인 경우 msg.sender를 calldata의 마지막 20바이트로 설정합니다.
3. 안전 제안
이 공격의 근본 원인: ERC-2771에서 [Forwarder]는 다중 호출용으로 설계되지 않았습니다. 공격자는 다중 호출의 외부 호출, 즉 본 이벤트의 [Forwarder].execute 함수에 _msgSender() 함수에 관련 매개변수를 추가합니다. 다중 호출 함수에서 일부 함수는 _msgSender()에 관련 매개변수를 추가하여 공격자가 _msgSender()를 스푸핑할 수 있도록 합니다. 따라서 공격자는 관련 기능을 호출하기 위해 다중 호출을 사용하여 임의의 주소에 대한 호출을 모방할 수 있습니다. 마지막으로 풀에 있는 TIME 토큰은 인증을 통해 폐기됩니다.
이 사건에 대응하여 다음과 같은 완화 및 예방 조치를 취할 수 있습니다.
1. 버그 수정 후 새 버전 사용 OpenZeppelin의 Multicall 새 버전은 ERC-277 1context 데이터의 컨텍스트 접미사 길이를 가지며, 이는 ERC-2771의 예상되는 컨텍스트 접미사 길이를 식별하는 데 사용됩니다. 따라서 신뢰할 수 있는 [Forwarder]의 모든 호출이 인식되어 각 하위 기능 호출에 적용됩니다.
다음은 버그 버전과 업데이트 버전 간의 비교 차트입니다.
2. 모든 컨트랙트에서 [포워더]가 멀티콜을 호출하는 것을 금지합니다. ThirdWeb을 예로 들면 이 방법은 OpenZeppelin의 솔루션과 비교됩니다. OpenZeppelin은 여전히 컨트랙트를 통한 멀티콜을 허용합니다. 다음은 ThirdWeb의 관련 버그 버전과 업데이트 버전을 비교한 차트입니다.
About Us
SharkTeam의 비전은 Web3 세계를 보호하는 것입니다. 이 팀은 블록체인 및 스마트 계약의 기본 이론에 능숙한 전 세계의 숙련된 보안 전문가와 수석 연구원으로 구성되어 있습니다. 온체인 빅데이터 분석, 온체인 위험 경고, 스마트 계약 감사, 암호화폐 자산 복구 및 기타 서비스를 포함한 서비스를 제공하며 온체인 빅데이터 분석 및 위험 경고 플랫폼인 ChainAegis를 구축했습니다. 심층적인 그래프 분석을 통해 Web3 세계의 지능형 지속 위협(APT)에 효과적으로 대처할 수 있습니다. Polkadot, Moonbeam, Polygon, Sui, OKX, imToken, ChainIDE 등 Web3 생태계의 다양한 분야의 주요 플레이어와 장기적인 협력 관계를 구축했습니다.
공식 웹 사이트:https://www.sharkteam.org
Twitter:https://twitter.com/sharkteamorg