
1900개 이상의 ETH가 도난당한 사건, Radiant Capital는 어떻게 해커에게 450만 달러를 훔쳐졌는가
TechFlow 선정TechFlow 추천

1900개 이상의 ETH가 도난당한 사건, Radiant Capital는 어떻게 해커에게 450만 달러를 훔쳐졌는가
2024년 1월 3일, Radiant Capital 프로젝트가 공격자에 의해 플래시론 공격을 당했으며, 공격자는 3건의 거래를 통해 1900개 이상의 ETH를 탈취해 약 450만 달러 상당의 피해를 입혔다. 현재 훔쳐간 자금은 여전히 공격자의 주소에 보관되어 있다.
글 작성: Beosin
2024년 1월 3일, Beosin 산하 EagleEye 보안 리스크 모니터링·경보 및 차단 플랫폼에 따르면, Radiant Capital 프로젝트가 공격자에 의해 플래시론 공격을 당했다. 공격자는 3건의 트랜잭션을 통해 1,900개 이상의 ETH를 탈취했으며, 이는 약 450만 달러 상당이며, 현재 탈취된 자금은 여전히 공격자의 주소에 남아 있다. Beosin 보안팀은 이번 사건을 즉각 분석했다.
취약점 분석
이번 사건의 근본 원인은 Radiant Capital 프로젝트가 토큰 수량을 계산하는 과정에서 정밀도 확장(precision expansion)을 사용하고 반올림 방식을 채택함으로써, 공격자가 정밀도 크기를 조절하고 반올림과 결합해 수익률을 인위적으로 늘릴 수 있게 되었기 때문이다.

위 코드를 살펴보면, rayDiv 함수는 두 개의 uint256 데이터 a와 b를 입력받으며, 전체 과정은 (a*RAY+b/2)/b로 간략화할 수 있다. 여기서 RAY는 정밀도 확장을 위한 값으로 10^27이다. 따라서 결과는 a*RAY/b+0.5가 되며, 이는 반올림 기능을 구현한다. 이 계산 방식의 오차는 주로 b에서 발생하는데, b가 a에 비해 매우 작다면 오차는 무시할 수 있지만, b가 a와 동일한 수준의 크기를 가지게 되면 오차는 a 자체와 맞먹는 수준까지 커질 수 있다.
예를 들어, a*RAY=10000이고 b=3이라면 계산 결과는 3333이 되어 실제 값보다 1/10000 작다. 반면 a*RAY=10000이고 b=3000이라면 계산 결과는 3이 되어 실제 값보다 1/10 작아진다.
이번 사건에서는 공격자가 b 값을 조작하여 a와 유사한 수준이 되게 함으로써, 계산 결과가 마치 3/2.0001=1처럼 나타나 실제 값보다 1/3 작게 되는 현상을 유도한 것이다.
공격 절차
공격자의 공격 절차를 확인해보자.
1. 공격자는 먼저 AAVE를 통해 300만 USDC를 플래시론으로 빌려 공격 초기 자금으로 사용한다.

2. 공격자는 200만 USDC를 Radiant 컨트랙트에 예치하고, 동일한 수량의 rUSDCn 증명 토큰을 획득한다.

3. 공격자는 Radiant 컨트랙트를 통해 200만 USDC를 플래시론으로 대출한 후, 콜백 함수 내에서 200만 USDC를 상환하면서 동시에 2단계에서 예치했던 USDC를 인출한다. 이후 플래시론 함수는 transferFrom 함수를 호출하여 공격자의 USDC를 원리금 포함해 컨트랙트로 이체한다. 이때 9/10000의 수수료가 부과되며, 이 수수료가 풀의 유동성으로 추가된다.

4. 공격자는 위 3단계의 작업을 반복 수행하여 liquidityIndex를 매우 큰 값으로 조작한다. 최종적으로 liquidityIndex는 271800000000999999999999998631966035920에 도달한다.

5. 다음으로 공격자는 새로운 컨트랙트를 생성하고 그 안에 54.36만 USDC를 입금한다. 이는 5436(USDC 수량)이 4단계의 liquidityIndex 값 2718의 정확히 2배이므로, 반올림 조작을 용이하게 하기 위해서이다.

6. 공격자는 54.36만 USDC 전부를 Radiant 컨트랙트에 담보로 맡기고 동일한 수량의 rUSDCn을 받는다.

7. 공격자는 40.77만 USDC를 인출한다. 이때 40.77만 rUSDCn이 소각되어야 하지만, 앞서 설명한 바와 같이 burn 함수는 정밀도 확장과 반올림 계산을 적용한다.
407700000000000000000000000000000000000 / 271800000000999999999999998631966035920 = 1.49999999이며, 반올림 결과는 1이 된다. 이로 인해 결과값이 실제보다 1/3 작아지는 오차가 발생한다.
아래 이미지에서 볼 수 있듯이, 실제로는 40.77만이 소각되어야 하지만, 27.18만이 남아 있어 실제로는 27.18만만 소각된 것으로 나타난다. 즉 공격자는 40.77만 USDC를 인출하면서도 rUSDCn은 27.18만만 소각한 셈이다.

8. 공격자는 7단계의 취약점을 이용해 반복적으로 담보 예치 및 인출 작업을 수행하며, 매번 인출량이 예치량보다 1/3 더 많도록 한다. 이를 통해 결국 풀 내 모든 USDC를 전부 인출해낸다.

자금 추적
기사 작성 시점 기준, 탈취된 1,902개의 ETH는 여전히 공격자의 주소에 있으며 이동되지 않았다. Beosin Trace는 해당 자금을 지속적으로 모니터링할 예정이다.

2024년의 시작과 함께 우리는 이미 두 건의 대규모 자산 탈취 사건을 목격했다. (어제 사건 요약: 연초 첫 사건, 8,000만 달러가 탈취된 Orbit Chain 사건의 전말은?) 이러한 일련의 사건들은 다시 한번 우리에게 Web3 생태계에서 보안 방어가 얼마나 중요한지를 상기시키고 있다!
TechFlow 공식 커뮤니티에 오신 것을 환영합니다
Telegram 구독 그룹:https://t.me/TechFlowDaily
트위터 공식 계정:https://x.com/TechFlowPost
트위터 영어 계정:https://x.com/BlockFlow_News














