
탈중앙화 금융(DeFi)은 블록체인 생태계에서 인기 있는 프로젝트 형태로서 보안이 특히 중요합니다. 지난해부터 수십 건의 보안 사고가 발생했다.
블록섹은 DeFi 보안에 관한 장기 연구 팀(https://blocksecteam.com)으로서 다수의 DeFi 보안 사고를 독자적으로 발견했으며 연구 결과는 유수 보안 컨퍼런스(USENIX Security, CCS 및 검은 모자). 다음 시간에는 DeFi 보안 사고를 체계적으로 분석하고 보안 사고의 근본 원인을 분석합니다.
지난 리뷰:
(1) [BlockSec DeFi 공격 분석 시리즈 중 하나] 나 자신을 대변합니다: ChainSwap 공격 이벤트 분석
(2) [BlockSec DeFi 공격 분석 시리즈 2] 모든 것을 공짜로: Sushiswap 수수료 도난
(3) [BlockSec DeFi 공격 분석 시리즈 3] 하늘을 훔치고 하루를 바꾼다: Akropolis 공격 이벤트 심층 분석
0x0.서문
베이징 시간으로 2021년 3월 9일 이른 시간, 이더리움 기반 분산 거래 플랫폼인 DODO의 여러 V2 크라우드 펀딩 풀이 공격을 받았고 풀의 토큰은 왕자를 위해 사향 고양이를 바꾸는 속임수를 벌였습니다. 그러나 이후의 분석에서 문제의 전개는 명백히 공격자의 예상 경로에서 벗어났는데…
Ethereum 초보자이고 이야기 읽기를 좋아한다면 아래 0x1부터 읽기 시작할 수 있습니다. 간단하고 직접적인 공격 분석이 마음에 드시면 0x2로 스크롤하여 읽기를 시작할 수 있습니다.
첫 번째 레벨 제목
0x1. 이벤트 리뷰
"공격은 성공했는가? 성공했지만 완전히는 아니다." 이는 당시 샤오아의 심리묘사일지도 모른다.
No code, no bug
보조 제목
0x1.1 개념 분석
DODO V2 크라우드 펀딩 풀이 정말 많이 언급됐는데 그게 뭘까요? 쉽게 말해 자금 풀인데, 이 글에서 자금은 우리가 매일 접하는 법정화폐가 아니라 이더리움 상의 토큰(ERC20 토큰)을 가리킨다. 이러한 종류의 자금 풀이 초기화되면 체인에 있는 두 종류의 가치 있는 ERC20 토큰이 이 풀의 토큰 쌍으로 설정되며(이 점을 기억하십시오. 나중에 테스트할 예정입니다) 사용자는 이러한 풀에서 제공하는 서비스를 사용할 수 있습니다. 정상적으로 풀. DODO V2 크라우드펀딩 풀에 대한 이번 공격에서 리틀에이는 풀에서 제공하는 플래시론 서비스를 이용했습니다.
플래시론은 일반 대출에 비해 담보 없이 거액의 자금을 빌려 돈을 갚기 전에 상태를 되돌리는 특성이 있다. 간단히 말해서 빈손으로 할 수 있습니다.마지막으로 빌린 돈을 한 번의 조작으로 잃어 버리면 여전히 그것을 만회하지 못하더라도 상관 없습니다.모든 관련 상태는 대출 이전으로 롤백됩니다. 차용인의 유일한 손실은 절차 외에 수수료 외에 시간 만있을 수 있습니다. 플래시 론을 사용하는 논리도 매우 간단합니다. 즉, 사용자가 펀드 풀에서 돈을 빌리고 --> 빌린 돈으로 운영하고 --> 돈을 상환하고, 이 모든 것이 한 번의 거래로 완료되어야 합니다.
자, 관련 개념을 간단히 이해한 후 Little A의 작동을 살펴보겠습니다.
0x1.2 샤오A의 요염한 작전
Little A는 다음에 두 가지 일을 했습니다.
먼저 두 개의 ERC20 토큰 컨트랙트를 생성하는 것입니다.직설적으로 두 개의 위조 코인(가치가 없기 때문에)을 FDO와 FUSDT라고 합니다. 공격을 받다.
리틀에이가 두 번째로 한 일은 DODO V2 크라우드펀딩 풀의 플래시론 서비스를 이용하는 것이었습니다. 위에서 언급했듯이 플래시론을 사용하는 논리 중 하나는 빌린 돈으로 운영하는 것이며 이 기사의 주인공 Xiao A는 이 링크에서 속임수를 썼습니다.
Little A는 이 DODO V2 크라우드 펀딩 풀이 인위적으로 다시 초기화될 수 있고 제한이 없다는 것을 발견했습니다. 그리고 Little A는 돈을 빌려준 후 풀을 다시 초기화했고, 초기화 시 설정된 토큰 쌍은 Little A가 직접 만든 두 개의 위조 코인 FDO/FUSDT가 되었습니다. . 그리고 Little A는 돈을 빌리기 전에 위에서 한 첫 번째 작업을 통해 충분한 양의 두 종류의 위조 통화를 이 풀에 미리 예치했으며 이로 인해 풀은 Little A의 부채 상황을 확인하게 되었기 때문에 체크된 토큰은 더 이상 존재하지 않습니다. 기존의 실화폐지만 A씨가 예치한 위조화폐, 그 금액은 충분하다. 이렇게 리틀에이는 위조지폐를 이용해 진짜 화폐를 만들었다.
위의 프로세스에 대해 간단한 유추를 할 수 있으며 자세한 내용은 표시되지 않습니다. 은행이 있고, 이 은행을 위에서 언급한 펀드 풀에 비유할 수 있습니다. 동시에 은행에도 계좌를 보관할 소책자가 있는데 소책자 홈페이지에 [은행은 위안화 만 취급하고 준비금은 100]이라는 기록이 있습니다. 다른 통화는 미국 달러 또는 베트남 동입니다. 사용자도 입금할 수 있지만 은행은 당신을 신경 쓰지 않고 소액 장부에 계좌를 보관하지만 확인할 때 위안화 관련 기록만 봅니다.
크라우드펀딩 풀이 재초기화될 수 있다는 문제를 유추하자면 이렇게 이해할 수 있다. 이 작은 책에 문제가 있다 문제는 홈페이지[은행은 인민폐만 취급한다]의 룰이 연필로 쓰여 있고 이 작은 책을 창가에 두고 외부인이 지우개와 연필로 바꿀 수 있다는 점이다. . 그런 다음 Little A가 이 문제를 발견했습니다. 그는 먼저 이 은행에 100 VND를 입금했고 은행은 [Little A가 은행에 100 VND를 입금함]을 기록했습니다. 그런 다음 꼬마 A는 은행에 가서 100위안을 빌려주고 은행은 [꼬마 A가 은행에서 100위안을 빌렸습니다]라고 기록합니다. 은행은 모든 사용자의 위안화 차용 및 입금을 확인하고 준비금과 비교하여 사용자가 위안화를 빌리고 갚지 않았는지 확인합니다.
꼬마 A는 돈을 빌리자마자 준비한 연필과 지우개를 꺼내 소책자 홈페이지의 규정을 [저희 은행은 베트남동만 취급, 적립금 100동]으로 바꿨습니다. 그러다가 은행에서 금액을 확인해보니 베트남동만 취급하도록 규정이 바뀌었기 때문에 베트남동 예치금과 리틀A가 예치한 베트남동 금액이 같아 빚진 사람이 없다는 뜻이었다. 은행 돈. 그런 다음 Xiao A는 빌린 위안화를 받고 뒤돌아 보지 않고 떠났습니다.
DODO V2 크라우드 펀딩 풀을 공격하려는 Little A의 아이디어는 위에서 언급한 바와 같으며, Little A가 다음으로 해야 할 일은 그의 아이디어를 실제 행동으로 옮기는 것입니다. 이 글이 컨트랙트 코드 레벨에서 분석한 공격은 위에서 언급한 공격이지만 우리의 이야기는 아직 끝나지 않았습니다. 스토리를 계속 읽기 싫으신 분들은 0x2의 공격 분석 섹션으로 바로 스크롤을 내리시면 됩니다.
0x1.3 공격 과정: 산길의 열여덟 굴곡
처음으로. 사마귀가 매미를 잡고 꾀꼬리가 따라온다.
책을 계속합시다.
프로젝트 당사자, 즉 DODO는 동일한 논리로 여러 풀을 생성했으며 이러한 풀은 동일한 허점을 가지고 있습니다. 리틀에이가 처음 목표로 삼은 풀은 (WSZO/USDT) 풀이었는데, WSZO와 USDT는 두 개의 가치 있는 토큰(ERC20 토큰)입니다. 자신의 공격 논리를 트랜잭션에 즐겁게 쓴 후 누워서 돈을 모으려던 참이었는데, 이때 뭔가 잘못됐다.
사용자가 채굴자에게 지불하는 이더리움 거래에는 거래 수수료가 있다는 것을 알고 있습니다. 따라서 채굴자들은 자신의 이익을 극대화하기 위해 펭딩 풀에서 트랜잭션을 패키징하고 체인에 올라갈 준비를 할 때 각 트랜잭션의 트랜잭션 수수료를 확인하고 순서대로 정리할 것입니다. 먼저 체인. 그리고 이더리움의 탈중앙화 메커니즘 때문에 어둠의 숲의 법칙이 여기에도 적용됩니다. 공격자, 차익거래자, 디파이(Decentralized Finance) 프로젝트의 초기 주자들이 전 세계에 도사리고 있다 목표를 찾으면 떼를 지어 몰려든다 결국 누가 성공하느냐는 거래 수수료를 누가 내느냐에 달려 있다 기술 및 기타 요인에 더해 키가 큽니다.
다시 주인공 꼬마 A로 돌아가 허점을 찾아 돈을 벌 기회를 잡으려 했으나, 꼬마 A의 행동을 다른 캐릭터인 돌진 로봇이 발각했다.돌진하는 로봇 꼬마 B라고 하자. Little B는 거래 수수료에 대해 소란을 피우고 거래의 가스 가격을 인상하여 거래 수수료를 높였습니다. 이것은 채굴자들이 트랜잭션을 패키징할 때 작은 B의 트랜잭션을 먼저 패키징하게 만듭니다. 일반적으로 Little B의 이러한 운영을 전면 실행이라고합니다. 작은 A 트랜잭션을 패키징할 차례가 되었을 때 WSZO/USDT 풀의 WSZO 및 USDT는 비어 있었고 쓸모 없는 묶음(FDO/FUSDT)만 남았습니다.
Little A는 이번 실패가 그저 평범한 선불 거래라고 생각했을지도 모르기 때문에 그는 예전의 트릭을 반복했습니다. 이번에 대상을 (ETHA/USDT) 풀로 변경한 것 뿐이고, 도둑맞는 것을 방지하기 위해 Little A는 이번 거래에서 거래의 가스 가격을 높였습니다. 그러나 작은 A가 모르는 것은 그가 작은 B의 표적이 되었다는 것입니다.
같은 루틴과 같은 방법으로 꼬마 A는 다시 꼬마 B에게 납치되었습니다.
두 번째로 Cheng Yaojin은 중간에 사망했습니다.
지금까지 Little A는 두 번의 공격으로 Little B를 위해 웨딩 드레스를 만들었고 거래 수수료까지 잃었습니다! Little A는 너무 화가 나서 고통에서 배웠고 다음 풀(wCRES/USDT)을 목표로 삼았습니다. 그리고 이번에는 꼬마 A가 꼬마 B의 모니터링을 성공적으로 우회했습니다. 일이 꼬마에이가 성공할 것 같은 상황까지 발전했지만 실상은 꼬마에이와 장난을 치는 것을 좋아한다.
3차 공격은 꼬마B를 우회했지만, 꼬마A는 성공적으로 돈을 인출한 뒤 자신의 주소로 돈을 직접 이체하지 않고 돈을 받기 위해 새로운 계약을 맺었다. Little A의 아이디어는 먼저 이 새로운 계약에 돈을 임시로 보관한 다음 자신의 계좌로 이체하는 것입니다. 그러나 리틀에이의 계약에는 훔친 돈을 일시적으로 보관하는 또 다른 허점이 있다.
However, this contract had a loophole that allowed anyone to withdraw assets from it.
이 취약점은 다른 캐릭터(Little C)에 의해 발견되었습니다. 따라서 꼬마A가 이 계약에서 훔친 돈을 되찾기 위해 거래를 했을 때 두 사람 모두 또 다시 도둑을 맞았지만 이번에는 선점이 꼬마C가 됐다.
이를 보면 Little A는 선불 거래의 공격자이자 피해자입니다. 이 물결, 작은 A는 닭을 훔쳤지만 돈을 잃은 것으로 간주될 수 있습니다.
세 번째. 완고한 작은 A
앞에서 언급했듯이 동일한 논리적 허점을 가진 여러 개의 풀이 있습니다. Little A는 네 번째 공격을 다시 시작할 준비가 되었습니다. 이번에는 대상이 (DODO/USDT) 풀로 변경됩니다. 이번에 꼬마 A는 똑똑해지는 법을 배웠습니다.한편으로는 훔친 돈을 임시 보관하던 컨트랙트를 새로운 컨트랙트로 교체했고, 한편으로는 꼬마 A도 토큰 전송 과정을 하나의 트랜잭션으로 결합하여 세 번째를 피했습니다. 2차 공격에서 꼬마C에게 납치당한 사례. 하지만 이번에도 남벽에 부딪히지 않고 뒤돌아보지 않은 리틀A는 결국 위조화폐(FDO/FUSDT)로 실물화폐(DODO/USDT)를 얻는 데 성공했다.
Chapter 4. 미치고 자신을 깨물다
네 번의 공격이 마침내 성공한 후 Little A는 만족합니까? 사실은 대답이 '아니오'임을 말해줍니다.
작은 A가 어떻게 생각하는지 모르겠지만 우여곡절 끝에 마침내 성공해서 너무 흥분했을 수도 있습니다. 이 다섯 번째 공격에서 그의 목표는 (wCRES/USDT) 풀이었습니다. 친숙해 보입니까? 좋아요! 이 풀은 정확히 세 번째 공격에서 Little A의 대상 풀입니다. 세 번째 공격 이후 풀은 (wCRES/USDT) 풀에서 (FDO/FUSDT) 풀로 변경되었습니다. 즉, 실제 코인 풀이 위조 코인 풀이 되었습니다. 따라서 이번 공격에서 Little A가 동일한 공격 루틴을 사용하여 얻은 결과는 새 위조 동전을 이전 위조 동전으로 교환하는 것에 지나지 않습니다...
그리고 이 두 개의 위조 동전은 Xiao A가 직접 만든 것입니다. 어쩌면 샤오아는 여전히 향수를 불러일으키는 사람일지도...
꼬마 A에 대한 우리의 이야기도 끝이 나고 있습니다. 아마도 이더리움은 공격자에게 어두운 숲이고, 사냥꾼과 먹이의 정체성은 이 특수한 영역에서 정적이지 않습니다. 당신이 심연을 들여다보면 심연도 당신을 들여다본다는 것을 항상 기억하십시오.
자, 다음 단계는 심각한 공격 분석 링크입니다.
첫 번째 레벨 제목
0x2. 공격 분석
이해의 편의를 위해 다음은 세 번째 공격을 예로 들어 분석할 것이며, 관련된 풀은 (wCRES/USDT) 풀입니다.
0x2.1 코드 분석
아래에 언급된 기능은 모두 펀드 풀(wCRES/USDT)의 계약 코드에서 왔으며 이 공격에 관여합니다.
0x2.1.1 getVaultReserve 기능
먼저 getVaultReserve 함수를 보면 이 함수의 함수는 매우 간단합니다.
0x2.1.2 플래시론 기능
위의 그림은 이번 공격에서 펀드풀 컨트랙트의 플래시론 기능입니다. 사용자가 이 함수를 호출하면 사용자가 전달한 baseAmount와 quoteAmount의 두 매개변수에 따라 매개변수 assetTo가 나타내는 주소로 해당 수의 토큰이 전송되는 것을 볼 수 있습니다. 이 시점에서 flashloan의 대출 연결이 완료됩니다. 코드를 살펴보면 데이터가 비어 있지 않은 한 외부 논리가 트리거됩니다. 그리고 이 외부 논리는 호출자 자신에 의해 구현되며 이 공격의 실현은 바로 이 외부 논리가 실행될 때입니다.
0x2.1.3 초기화 기능
위의 그림은 이번 공격에서 가장 중요한 초기화 함수 init인데 이 함수가 외부에서 호출되는 것을 알 수 있는데 가장 중요한 것은 이 함수가 다음과 같은 두 가지 특징을 가지고 있다는 점이다.
[권한 필요 없음] 이는 외부에서 누구나 이 함수를 호출할 수 있음을 의미합니다.
[반복적으로 호출 가능]은 init 함수가 풀이 빌드될 때 한 번 호출되는 것을 제외하고 풀을 다시 초기화하기 위해 언제든지 호출될 수 있음을 의미합니다.
호출자가 이 함수를 호출하면 전달된 두 개의 매개변수 baseTokenAddress 및 quoteTokenAddress가 각각 변수 _BASE_TOKEN_ 및 _QUOTE_TOKEN_을 재할당하는 데 사용됩니다. 그리고 이 두 변수의 변경은 이 풀의 토큰 쌍도 변경된다는 것을 의미합니다. 이것이 wCRES/USDT 풀이 FDO/FUSDT가 되는 이유입니다.
0x2.2 공격 프로세스
공격 트랜잭션의 흐름은 아래 그림과 같습니다.
거래 흐름 분석은 우리 팀의 거래 분석 도구를 사용할 수 있습니다.https://tx.blocksecteam.com/
Step 0
공격자는 먼저 두 개의 ERC20 토큰 계약(FDO 및 FUSDT)을 생성했으며, 이는 단순히 두 개의 위조 토큰(가치 없음)을 생성하는 것으로 이해할 수 있습니다. 그리고 이 두 개의 토큰을 자신의 주소(0x368a6)로 대량 전송하여 후속 공격에 대비했습니다.
Step 1
공격자는 펀드 풀 계약의 getVaultReserve 함수를 호출하여 풀에 있는 wCRES 및 USDT의 현재 준비금을 확보하여 다음 공격에 대비합니다.
Step 2
1단계에서 획득한 준비금에 따라 공격자는 두 위조 통화 계약의 transferFrom 함수를 호출하여 준비금보다 약간 더 많은 위조 통화(FDO 및 FUSDT)를 자금 풀 계약(DLP)으로 전송합니다. flashloan 기능의 잔액 확인을 통과할 수 있습니다.
Step 3
그런 다음 공격자는 펀드 풀 계약(DLP)의 플래시론 기능을 호출하여 펀드 풀 준비금보다 약간 적은 실제 코인(wCRES 및 USDT)을 빌려줍니다.
Step 4
flashloan 기능은 wCRES 및 USDT를 공격자가 미리 설정한 계약 주소로 전송한 후 자동으로 공격자의 외부 로직을 호출합니다. 공격자는 외부 로직 구현에서 wCRES/USDT 풀의 초기화 기능 init를 호출하여 풀의 토큰 쌍을 FDO/FUSDT로 교체했습니다.
Step 5
아래 그림과 같이 flashloan 기능이 외부 로직을 실행한 후 현재 풀의 토큰(토큰) 잔고를 확인합니다. 그러나 풀의 토큰 쌍이 FDO/FUSDT로 대체되기 때문에 baseBalance 및 quoteBalance로 표시되는 잔액은 FDO 및 FUSDT의 잔액이기도 합니다.
동시에 공격자는Step 2 첫 번째 레벨 제목
0x3. 요약 및 보안 권장 사항
이 공격의 주된 이유는 DODO V2 크라우드 펀딩 풀의 초기화 기능입니다. 이 함수의 호출을 살펴보면 풀이 처음 빌드될 때 이 함수는 한 번만 호출할 수 있고 액세스 권한이 설정되어야 하며 반복적으로 호출할 수 없다는 것이 정상적인 논리여야 함을 알 수 있습니다. 공격자는 init 함수를 반복적으로 호출하여 풀을 재초기화할 수 있는 취약점을 이용하여 플래쉬론과 결합하여 풀에 있는 실물 화폐를 위조 화폐로 인출함으로써 공격을 완성하였다.
따라서 관련 프로젝트 당사자에게 다음과 같이 제안합니다.
프로젝트 계약의 주요 기능에 대한 권한 검토를 잘 수행하여 낮은 권한 요구 사항으로 인해 핵심 기능의 오용으로 인한 손실을 방지하십시오.
첫 번째 레벨 제목
0x4.참조
보조 제목
기사에 관련된 외부 주소 및 계약 주소
이 문서에서 다루는 트랜잭션
첫 번째 공격
두 번째 공격
세 번째 공격
네 번째 공격
다섯 번째 공격