재진입 공격(Reentrancy Attack)이란?
재진입 공격은 한 계약이 호출 도중 다른 계약으로 제어를 넘겨 외부 코드가 첫 번째 계약의 기록 업데이트가 끝나기 전에 다시 첫 번째 계약으로 점프하는 경우를 말합니다. 이 시점 타이밍 트릭은 공격자가 인출과 같은 민감한 작업을 반복할 수 있게 해 줍니다. 계산대를 잠그기 전에 환불을 요청하는 상황을 떠올려 보세요.
“오직 오래된 코드만 재진입 공격에 취약하다.”는 말은 사실이 아닙니다. 자신의 상태를 잠그기 전에 외부 호출을 하는 모든 계약은 로직이 엉성하면 취약해질 수 있습니다.
재진입 공격의 작동 원리
짧은 이야기. 일반적인 스마트 컨트랙트에는 호출자에게 자금을 보낼 수 있는 출금 함수가 있습니다. 먼저 자금을 보내고 잔액을 나중에 지우면, 공격자는 콜백을 삽입하고 잔액이 0으로 설정되기 전에 더 많은 출금을 요구할 수 있습니다.
- 시작: 공격자가 합법적으로 보이게 하기 위해 일부 자금을 예치합니다.
- 호출: 공격자가 대상 컨트랙트에서 출금을 트리거합니다.
- 대체: 대상이 자금을 보내고, 이는 공격자의 대체 함수(fallback)를 실행합니다.
- 반복: 그 대체가 잔액이 업데이트되기 전에 다시 출금을 호출합니다.
- 배출: 잔고가 바닥나거나 가스가 소진될 때까지 루프가 계속됩니다. 그렇습니다, 이것이 그 트릭입니다.
하나의 작은 순서 오류가 큰 문제로 이어집니다.
재진입 공격의 중요성
타이밍 버그가 실제 자금을 빠르게 움직이기 때문에 당신이 관심을 가져야 합니다. 또한 이것은 모든 개발자와 호기심 많은 사용자가 알아두어야 할 클래식한 익스플로잇 중 하나입니다.
- 이득: 패턴을 알면 위험한 코드를 식별하고 자금을 안전하게 지킬 수 있습니다.
- 관점: 공개 투명성에 의존하는 현상이기 때문에 모든 것이 블록체인에 노출되고 호출 가능합니다.
- 관련성: DeFi, 브리지, 금고, 심지어 DAO의 거버넌스 보상에서도 발견될 수 있습니다.
확인 사항은 확인, 효과, 상호 작용 순으로 따라가세요. 균형을 먼저 업데이트한 후 외부 호출을 만드세요. 추가 안전을 위해 간단한 재진입 차단기를 추가하십시오.
재진입 공격의 주요 특징
다음이 그것을 작동하게 만드는 요인입니다:
- 재귀: 외부 코드가 끝나기도 전에 같은 계약으로 다시 호출합니다.
- 정렬: 상태 업데이트보다 자금을 보내거나 외부 호출이 먼저 발생할 때 버그가 나타납니다.
- 교차: 하나의 함수뿐 아니라 여러 계약 간에 이동할 수 있습니다.
- 자산: ETH, 토큰, 심지어 회계 크레딧까지도 잘못 코딩되면 작동합니다.
Variations
다른 형태지만 게다가 코드의 엉성함으로 인한 두통은 같습니다:
- Single: 같은 함수를 반복해서 재진입합니다.
- Cross: 같은 계약 내의 다른 함수를 통해 재진입합니다.
- Multi: 루프에서 둘 이상 계약 간 재진입합니다.
- ReadOnly: 뷰나 가격 오라클에 영향을 주어 나중의 쓰기를 속입니다.
재진입 공격의 수리는 단 하나의 함수에 국한되지 않습니다. 모든 외부 호출을 검토하고, 이상한 호출 체인에 대한 테스트를 추가하며, 정기적인 감사를 계획하세요.
예시
2016년 The DAO 해킹은 잔액이 정리되기 전에 출금에서 재진입 루프를 사용해 몇 분 만에 대규모 금고를 고갈시켰습니다.
재미있는 사실
커뮤니티의 구호인 checks then effects then interactions는 초기 보안 가이드에서 유래했으며 짧고 기억에 남으며 효과적이어서 남아 있습니다.
Wrap-Up
주머니에 넣고 다닐 수 있는 짧은 버전: 외부 코드가 당신의 회계 작업이 끝나기도 전에 당신을 호출할 수 있다면, 그것을 가능하게 만들고 너그러이 돈을 넘겨줄지도 모른다고 가정하세요. 그것이 바로 재진입 공격입니다.