
편집자 주: 이 기사의 출처는PeckShield(ID:PeckShield), 승인을 받아 Odaily에서 재인쇄했습니다.
편집자 주: 이 기사의 출처는
PeckShield 보안 담당자는 bZx 공격을 적극적으로 추적하여 이 사건이 DeFi 프로젝트 간의 공유 및 구성 가능한 유동성 설계에 대한 공격임을 발견했습니다.특히 레버리지 거래 및 대출 기능이 있는 DeFi 프로젝트에서 이 문제가 더 쉽게 악용될 것입니다.
Figure 1: Five Arbitrage Steps in bZx Hack
취약점의 공격 내역은 다음과 같습니다.
취약점의 공격 내역은 다음과 같습니다.
이 공격 이벤트는 2020-02-15 09:38:57 베이징 시간(블록 높이 #9484688)에 발생했습니다. 공격자의 거래 정보는 etherscan에서 확인할 수 있습니다. 이 공격 프로세스는 다음 다섯 단계로 나눌 수 있습니다.
1단계: 플래시 론으로 가용 자금 확보
Figure 2: Flashloan Borrowing From dYdX
이미지 설명
첫 번째 단계 이후, 다음 표에 있는 공격자의 자산은 현재로서는 이점이 없습니다.
2단계: WBTC 자리 모으기
Figure 3: WBTC Hoarding From Compound
이미지 설명
이 단계 후에 공격자가 제어하는 자산이 변경된 것을 볼 수 있지만 이 시점에서는 여전히 이점이 없습니다.
보조 제목
bZx의 레버리지 거래 기능을 사용하여 ETH를 매도하여 대량의 WBTC를 매수합니다. 구체적인 단계는 다음과 같습니다. 공격자는 1,300 ETH를 예치하고 bZx 레버리지 거래 기능, 즉 mintWithEther() 인터페이스를 호출합니다. 이 함수는 내부적으로 marginTradeFromDeposit() 인터페이스를 계속 호출합니다. 다음으로 공격자는 bZx의 5배 레버리지로 얻은 5,637.62 ETH를 KyberSwap을 통해 51.345576 WBTC로 교환했습니다. 여기서 ETH를 쇼트하면 5배 차용된다는 점에 유의하세요. 이 거래로 인해 WETH/WBTC 환율이 정상 환율(~38.5 WETH/WBTC)의 약 3배인 109.8로 증가했습니다.
Figure 4: Margin Pumping With bZx (and Kyber + Uniswap)
이 트랜잭션을 완료하기 위해 KyberSwap은 기본적으로 준비금을 쿼리하고 최상의 환율을 찾습니다.결국 Uniswap만이 이러한 유동성을 제공할 수 있으므로 이 트랜잭션은 본질적으로 Uniswap에서 WBTC의 가격을 3배로 올립니다.
이 단계는 컨트랙트 내부에 보안 확인 로직을 구현하지만 실제로 트랜잭션 후 잠금 값을 확인하지 않는다는 점에 유의해야 합니다. 즉, 공격이 발생했을 때 이 검사가 활성화되지 않았으며 이 계약의 문제는 이후 섹션에서 자세히 설명합니다.
이 단계 이후 해커가 관리하는 자산에 대해 다음과 같은 변경 사항이 있음을 확인했습니다. 그러나이 단계 후에도 여전히 이익이 없습니다.
이미지 설명
Figure 5: WBTC Dumping With Uniswap
5단계: 플래시론 상환
보조 제목
5단계: 플래시론 상환
이 단계 후에 다음 자산 세부 정보를 다시 계산했습니다. 결과는 공격자가 이 공격을 통해 71 ETH와 두 개의 잠긴 포지션인 Compound(+5,500weth/-112WBTC) 및 bZx(-4,337WETH/+51WBTC)를 획득했음을 보여줍니다. bZx의 잠금 위치는 기본이며, Compound의 잠금 위치는 수익성이 있습니다. 분명히 공격 후 공격자는 저당 잡힌 5,500 WETH를 상환하기 위해 복합 부채(112BTC)를 상환하기 시작했습니다. bZx 잠금이 이미 기본 설정되어 있으므로 공격자는 더 이상 관심이 없습니다.
1WBTC=38.5WETH(1WETH=0.025BTC)의 평균 시장 가격을 참고하여 공격자가 112 WBTC를 시장 가격으로 구매하면 약 4,300 ETH의 비용이 듭니다. 112 WBTC는 Compond의 부채를 상환하고 5,500 ETH의 담보를 되찾는 데 사용되므로 공격자의 총 이익은 71 WETH +5,500 WETH -4,300 ETH=1,271 ETH, 총 $355,880(현재 ETH 가격은 $280)입니다.
보조 제목
핵심 분석: bZx는 위험한 코드 논리 결함을 방지할 수 있습니다.
계약에서 공격자가 구현한 이전 단계에서 문제의 핵심 원인은 세 번째 단계에서 marginTradeFromDeposit()를 호출하여 1,300 ETH를 차입하고 5배의 레버리지를 추가하여 ETH/WBTC 트랜잭션을 매도하는 것으로 볼 수 있습니다. , 그래서 추가 검토 계약 코드는 이것이 "회피 가능한 차익 거래 기회"라는 것을 발견했지만 코드의 논리 오류로 인해 위험을 피하기 위해 사용할 수 있는 코드 논리가 적용되지 않았습니다. 특정 코드 추적은 다음과 같습니다.
먼저 marginTradeFromDeposit( )는 _borrowTokenAndUse( )를 호출하는데 여기서 예치된 자산은 레버리지 거래에 사용되므로 네 번째 매개변수는 true입니다(840행).
_borrowTokenAndUse( )에서 amountIsADeposit이 true일 때 _getBorrowAmountAndRate( )를 호출하고 sentAmounts[1]에 borrowAmount를 저장합니다(1,348행).
1,355행에서 sentAmounts[6]는 sentAmounts[1]로 설정되고 _borrowTokenAndUseFinal( )은 1,370행에서 호출됩니다.
IBZx 인터페이스를 통해 bZxContract의 takeOrderFromiToken( ) 기능을 입력하십시오.
bZxContract는 다른 계약 iTokens_loanOpeningFunctions에 속하므로 계속해서 계약 코드를 분석하고 함수에서 핵심 논리적 판단을 찾습니다.
148행에서 bZx는 실제로 오라클 계약의 shouldLiquidate( )를 사용하여 이 레버리지 거래의 포지션이 건전한지 확인하려고 시도합니다. 그러나 첫 번째 조건(146-147행)이 이미 참이므로 shouldLiquidate()의 논리적 판단을 무시하고 실행을 계속합니다.