Damn Vulnerable DeFI 2022 Walkthrough — Challenge 1 Solution "Unstoppable"
Damn Vulnerable DeFi는 DeFi 스마트 계약의 공격적인 보안을 가르칩니다. 수많은 도전을 통해 기술을 개발하여 버그 헌터 또는 보안 감사자가 될 수 있습니다.
시작하기 전에 멋진 빌드Damn Vulnerable Defi challenge를 외치고 싶었습니다.
다음 기사에서는 도전 과제를 안내하고 이를 해결하는 가장 효율적인 방법을 보여 드리겠습니다. 시작하자!
또한 이 비디오를 시청하여 "멈출 수 없는"챌린지를 해결하는 방법을 확인할 수 있습니다.
망할 취약한 DeFi 설정
클론this repository을 시작하려면 터미널에서 git checkout v2.2.0
를 입력하여 최신 버전을 확인하고 yarn install
를 실행하여 종속성을 설치합니다.
이제 계약과 테스트라는 두 가지 주요 폴더가 있습니다. 각 챌린지에 대해 이 두 폴더에 하위 폴더가 있고, 계약에는 챌린지의 취약한 스마트 계약이 포함되며, 테스트에는 계약을 배포하고, 챌린지를 설정하고, 익스플로잇을 테스트하기 위한 Javascript 파일이 포함됩니다.
과제 1 — "멈출 수 없다"
There’s a lending pool UnstoppableLenderwith a million DamnValuableToken (DVT) tokens in balance, offering flash loans for free.
If only there was a way to attack and stop the pool from offering flash loans …You start with 100 DVT tokens in balance.
이것은 고전적인 DOS(서비스 거부) 공격이며 우리의 목표는 풀을 깨는 것이므로 아무도 이를 사용할 수 없게 됩니다. 대박! :)
제가 일반적으로 가장 먼저 하는 일은 비즈니스 로직을 이해하기 위해 테스트 파일을 살펴보는 것입니다. 반면 unstoppable.challlenge.js
를 살펴보면 DamnValuableToken
및 UnstoppableLender
계약이 어떻게 배포되고 있는지, ETH가 어떻게 전송되는지 확인할 수 있습니다. 모든 것이 예상대로 작동하는지 확인하기 위한 풀 및 일부 온전성 검사.
풀이 어떻게 작동하는지 이해하기 위해 우리는 UnstoppableLender.sol
스마트 계약, 특히 우리가 중단해야 하는 flashLoan
기능으로 이동합니다!
"멈출 수 없는" 도전 과제 해결
공격 계획
flashLoan 기능에는 일부 asserts
및 require
opcode가 있으며 이러한 요구 사항이 실패할 경우 트랜잭션이 되돌려집니다. 우리는 항상 이러한 자산 중 하나를 만들 수 있는 방법을 찾으려고 노력할 것입니다. 모두와 우리가 깨뜨릴 수 있는 것을 확인합시다:
require(borrowAmount > 0, "Must borrow at least one token");
그리고
require(balanceBefore >= borrowAmount, "Not enough tokens in pool");
borrowAmount
는 매 트랜잭션마다 사용자가 보내는 매개변수이므로 깨질 수 없습니다.
이 정수 주장은 흥미 롭습니다.
uint256 balanceBefore = damnValuableToken.balanceOf(address(this));
assert(poolBalance == balanceBefore);
풀은 현재 토큰 잔액(balanceBefore)이 poolBalance 매개변수와 같은지 확인하고 있습니다. 이 poolBalance 매개변수는 무엇이며 어떻게 계산됩니까?
poolBalance는 컨트랙트의 토큰 잔액을 추적하는 저장 변수이며 누군가가 토큰을 예치할 때마다 depositTokens
함수에서 업데이트됩니다.
따라서 자산을 부수기 위해서는 poolBalance != balanceBefore
기능을 거치지 않고 ERC20 토큰을 컨트랙트에 직접 보내서 depositTokens
간단하게 할 수 있는지 확인해야 합니다. 너무 간단하죠?
착취
우리는 이 챌린지에서 스마트 계약을 생성하고 배포할 필요가 없습니다. 착취가 매우 간단하기 때문에 depsitTokens 기능을 거치지 않고 일부 DVD ERC20 토큰을 풀로 직접 보내면 됩니다. 이 코드 줄을 unstoppable.challenge.js
파일에 추가해 보겠습니다.
await this.token.connect(attacker).transfer(this.pool.address, 1);
익스플로잇 섹션에 이 코드 라인을 추가함으로써 우리는 1 DVD 토큰을 풀로 전송하여 poolBalance
와 balanceBefore
변수 사이의 어설션을 영구적으로 중단합니다.
이제 터미널에서 yarn unstoppable
를 실행하여 익스플로잇이 작동하는지 확인하고 결과는 다음과 같습니다.
축하합니다. 첫 번째 Damn Vulnerable DEFI 챌린지를 완료했습니다! 다음:
There’s a lending pool UnstoppableLenderwith a million DamnValuableToken (DVT) tokens in balance, offering flash loans for free.
If only there was a way to attack and stop the pool from offering flash loans …You start with 100 DVT tokens in balance.
이것은 고전적인 DOS(서비스 거부) 공격이며 우리의 목표는 풀을 깨는 것이므로 아무도 이를 사용할 수 없게 됩니다. 대박! :)
제가 일반적으로 가장 먼저 하는 일은 비즈니스 로직을 이해하기 위해 테스트 파일을 살펴보는 것입니다. 반면
unstoppable.challlenge.js
를 살펴보면 DamnValuableToken
및 UnstoppableLender
계약이 어떻게 배포되고 있는지, ETH가 어떻게 전송되는지 확인할 수 있습니다. 모든 것이 예상대로 작동하는지 확인하기 위한 풀 및 일부 온전성 검사.풀이 어떻게 작동하는지 이해하기 위해 우리는
UnstoppableLender.sol
스마트 계약, 특히 우리가 중단해야 하는 flashLoan
기능으로 이동합니다!"멈출 수 없는" 도전 과제 해결
공격 계획
flashLoan 기능에는 일부 asserts
및 require
opcode가 있으며 이러한 요구 사항이 실패할 경우 트랜잭션이 되돌려집니다. 우리는 항상 이러한 자산 중 하나를 만들 수 있는 방법을 찾으려고 노력할 것입니다. 모두와 우리가 깨뜨릴 수 있는 것을 확인합시다:
require(borrowAmount > 0, "Must borrow at least one token");
그리고
require(balanceBefore >= borrowAmount, "Not enough tokens in pool");
borrowAmount
는 매 트랜잭션마다 사용자가 보내는 매개변수이므로 깨질 수 없습니다.
이 정수 주장은 흥미 롭습니다.
uint256 balanceBefore = damnValuableToken.balanceOf(address(this));
assert(poolBalance == balanceBefore);
풀은 현재 토큰 잔액(balanceBefore)이 poolBalance 매개변수와 같은지 확인하고 있습니다. 이 poolBalance 매개변수는 무엇이며 어떻게 계산됩니까?
poolBalance는 컨트랙트의 토큰 잔액을 추적하는 저장 변수이며 누군가가 토큰을 예치할 때마다 depositTokens
함수에서 업데이트됩니다.
따라서 자산을 부수기 위해서는 poolBalance != balanceBefore
기능을 거치지 않고 ERC20 토큰을 컨트랙트에 직접 보내서 depositTokens
간단하게 할 수 있는지 확인해야 합니다. 너무 간단하죠?
착취
우리는 이 챌린지에서 스마트 계약을 생성하고 배포할 필요가 없습니다. 착취가 매우 간단하기 때문에 depsitTokens 기능을 거치지 않고 일부 DVD ERC20 토큰을 풀로 직접 보내면 됩니다. 이 코드 줄을 unstoppable.challenge.js
파일에 추가해 보겠습니다.
await this.token.connect(attacker).transfer(this.pool.address, 1);
익스플로잇 섹션에 이 코드 라인을 추가함으로써 우리는 1 DVD 토큰을 풀로 전송하여 poolBalance
와 balanceBefore
변수 사이의 어설션을 영구적으로 중단합니다.
이제 터미널에서 yarn unstoppable
를 실행하여 익스플로잇이 작동하는지 확인하고 결과는 다음과 같습니다.
축하합니다. 첫 번째 Damn Vulnerable DEFI 챌린지를 완료했습니다! 다음:
require(borrowAmount > 0, "Must borrow at least one token");
require(balanceBefore >= borrowAmount, "Not enough tokens in pool");
uint256 balanceBefore = damnValuableToken.balanceOf(address(this));
assert(poolBalance == balanceBefore);
await this.token.connect(attacker).transfer(this.pool.address, 1);
다음 시간까지,
조니타임.
Reference
이 문제에 관하여(Damn Vulnerable DeFI 2022 Walkthrough — Challenge 1 Solution "Unstoppable"), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/johnnytime/damn-vulnerable-defi-2022-walkthrough-challenge-1-solution-unstoppable-3p6f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)