2024년 3월 28일, 프리즈마 파이낸스는 플래시 대출 공격을 받아 프로젝트 측에 약 1,221만 달러의 손실을 입었습니다.
샤크팀은 이번 사건에 대한 기술적 분석을 수행하고 후속 프로젝트가 이를 경고로 삼아 블록체인 산업의 보안 방어를 구축할 수 있기를 바라며 보안 예방 조치를 요약했습니다.
I. 공격 트랜잭션 분석
공격자 1: 0x7e39e3b3ff7adef2613d5cc49558eab74b9a4202 (0x7e39의 줄임말)
공격자 계약 1: 0xd996073019c74b2fb94ead236e32032405bc027c (0xd996의 약어)
공격자 2: 0x7fe83f45e0f53651b3ed9650d2a2c67d8855e385
Attacker 2: 0x4148310fe4544e82f176570c6c7b649290a90e17
공격 대상 컨트랙트: 0x1cc79f3f47bfc060b6f761fcd1afc6d399a968b6
이 공격은 16개의 트랜잭션으로 구성되며, 첫 번째 공격 거래를 예로 들면 다음과 같습니다.
0x00c503b595946bccaea3d58025b5f9b3726177bbdc9674e634244135282116c7
공격 흐름
1. 대상 컨트랙트에서 0x56a201b872b50bbdee0021ed4d1bb36359d291ed(약칭 0x56a2) 주소의 모든 담보와 채권을 읽습니다.
다음 내용을 반환합니다:
주소 0x56a2에는 대상 계약에 총 1,745wstETH의 담보가 있고 총 부채는 총 1,442,100 mkUSD입니다.
2. 공격자 0x7e39가 공격 컨트랙트 0xd996을 통해 mkUSD 부채 컨트랙트에서 flashLoan 함수를 호출합니다.
매개변수 수신자가 MigrateTroveZap으로 설정되어 있고 금액은 위에서 조회한 전체 부채입니다.
그런 다음, 수신기의 onFlashLoan 함수(이 경우 MigrateTroveZap)가 flashLoan 함수에서 호출됩니다.
플래시 대출을 통한 플래시 대출 기능은 먼저 원래 부채를 모두 상환하고 수신자에게 담보를 추출한 다음 수신자가 일정 수의 담보 재 모기지가되어 일정 금액의 부채를 빌릴 수 있습니다. 주로 두 가지 함수를 호출합니다.
(1) closeTrove 함수, troverManager에서 추출한 부채와 모든 담보(1745.08 swtETH)를 수신자에게 상환합니다(여기서는 MigrateTroveZap. 컨트랙트);
(2) 수신자가 트로버매니저에 463.18wstETH를 재가설하고 1,443,598 mkUSD의 부채를 가진 오픈트러브 함수.
위 데이터에서 볼 수 있듯이, 플래시론 함수는 다음과 같이 실행됩니다. 실행이 완료된 후에도 troverManager에서 추출한 주소 0x56a2에 속하는 담보가 수신기에 남아 있으며, 이는 약 1745.08 - 463.18 = 1281.90 wstETH에 달합니다.
3 공격자 0x7e39는 공격 컨트랙트 0xd996을 통해 라이트닝 대출을 통해 밸런서로부터 1wstETH를 빌렸습니다.
그런 다음, 1 wstETH를 담보로 2000 mkUSD의 부채를 빌렸으며, 수수료와 함께 총 부채는 2200 mkUSD입니다.
4. 다음과 유사합니다. 2단계와 유사하게 mkUSD 부채 컨트랙트에서 flashLoan 함수를 호출하는데, 여기서 매개변수 수신자는 여전히 MigrateTroveZap으로 설정되고 금액은 마지막 담보 1wstETH 이후의 전체 부채, 즉 2000 mkUSD입니다. FflashLoan 함수에서는 수신자에서 onFlashLoan 함수가 호출됩니다. onFlashLoan 함수를 호출한 다음 closeTrove 및 openTrove 함수를 호출합니다.
단, 여기서 closeTrove와 openTrove 함수의 매개변수 계정은 위의 0x56a2 주소가 아니라 1wstETH가 담보된 공격 컨트랙트 0xd996입니다.
(1) closeTrove 함수, 부채를 갚습니다. 를 실행하고 모든 담보(1 swtETH)를 트로버매니저에서 수신자에게로 추출합니다(여기서는 여전히 MigrateTroveZap 컨트랙트). 이 시점에서 수신자에는 총 1281.90 +1=1282.90 wstETH가 있습니다.
(2) 수신자가 1,282.80 wstETH(거의 대부분)를 troverManager로 재가설하는 데 사용되는 openTrove 함수는 다음과 같은 책임을 가지고 있습니다. 2001.8 mkUSD.
사실, 여기서 담보로 제공된 1281.80 wstETH는 공격하는 컨트랙트 0xd996이 아니라 위의 주소 0x56a2에 속합니다.
5. 마지막으로, 공격자 0x7e39는 0xd996을 공격하여 컨트랙트 0xd996을 공격하고 있습니다. 0xd996 컨트랙트는 closeTrove 함수를 별도로 호출하고 담보로 제공된 1282.80 wstETH를 공격 컨트랙트 0xd996으로 추출합니다.
플래시 크레딧을 상환한 후에도 공격자는 여전히 1281.80wstETH, 약 230만 달러의 수익을 얻었습니다.
II. 취약점 분석
이 사건의 근본 원인은 프로젝트 계약에 논리 및 권한 검사가 존재하기 때문에 공격자가 다음을 수행할 수 있기 때문입니다. 취약점을 악용하여 다른 계정 주소에서 담보 자산을 확보할 수 있기 때문입니다.
공격자가 최종적으로 획득한 wstETH는 troverManager 컨트랙트의 원본 주소 0x56a2에 대한 담보였으며, 이는 mkUSD 컨트랙트의 flashLoan 함수를 통해 MigrateTroveZap 컨트랙트에서 사용자 정의된 것입니다. onFlashLoan 함수를 사용하여 공격 컨트랙트의 담보로 변환한 다음, MigrateTroveZap을 사용하여 추출합니다.
공격자는 mkUSD 컨트랙트의 flashLoan 함수를 통해 다른 계정 주소의 담보화 및 추출을 조작하고, MigrateTroveZap 컨트랙트의 onFlashLoan 함수를 통해 이를 추출합니다.
(1) onFlashLoan 함수의 수신자는 계정의 모든 담보를 수신하므로 수신자에 대해 신뢰할 수 있는 체크섬이 필요하기 때문에 매개변수 수신자의 주소에 대한 체크섬이 없습니다.
(
( 2) closeTrove와 openTrove 함수는 모두 계정의 자산을 조작하기 때문에 권한 측면에서 계정 주소에 대한 검증을 추가해야 합니다.
이에 대한 검증에 추가하여 onFlashLoan 함수는 계정 주소에 대한 검증이 부족합니다.
두 개의 주소 매개변수를 확인하는 것 외에도 flashLoan 함수와 구현 로직에서 수량 매개변수를 확인해야 할 수도 있습니다.
세 가지 보안 권장 사항
이 공격에 대응하기 위해 개발 과정에서 다음 예방 조치를 따라야 합니다.
(1) 프로젝트의 요구사항과 일치하는 방식으로 프로젝트를 설계 및 개발해야 합니다. ) 설계 및 개발 프로세스에서 프로젝트는 로직의 무결성과 엄격성을 유지하기 위해, 특히 프로세스에서 자산 전송과 관련하여 권한 검증 조사 기능을 강화하여 호출자, 호출 함수, 함수 매개 변수, 전송 로직 등이 안전하고 신뢰할 수 있는지 확인하는 것이 더 중요합니다.
(2) 프로젝트가 시작되기 전에 계약 감사를 수행할 전문 외부 감사 팀을 찾아야 합니다.
회사 소개
SharkTeam의 비전은 웹3.0 세상을 보호하는 것입니다. 이 팀은 블록체인과 스마트 컨트랙트의 기본 이론에 정통한 전 세계의 숙련된 보안 전문가와 선임 연구원으로 구성되어 있습니다. 위험 식별 및 차단, 스마트 컨트랙트 감사, KYT/AML, 온체인 분석 등의 서비스를 제공하고 있으며, 웹3.0 세상에서 지능형 지속 위협(APT)에 효과적으로 대응할 수 있는 온체인 지능형 위험 식별 및 차단 플랫폼인 체인에이지스(ChainAegis)를 구축했습니다. 체인아이지스는 폴카닷, 문빔, 폴리곤, 수이, OKX, imToken, 콜라보 등 웹3.0 생태계의 주요 업체들과 장기적인 관계를 구축해왔습니다.
공식 웹사이트: https://www.sharkteam.org
트위터: https://twitter.com/sharkteamorg
텔레그램: https://t.me/sharkteamorg
디스커드: https://discord.gg/ jGH9xXCjDZ