2026년 1월 25일, 저희는 Ethereum, Arbitrum, Base, BSC 전반에 걸쳐 SwapNet과 Aperture Finance가 배포한 피해자 컨트랙트를 대상으로 한 일련의 의심스러운 트랜잭션을 탐지했으며, 총 손실액은 $1,700만을 초과합니다. 개괄적으로 보면, 두 사건의 근본 원인은 간단하며 이미 최초 알림 [1, 2]에서 개요가 제시된 바 있습니다:
피해자 컨트랙트는 불충분한 입력 검증으로 인해 임의 호출 기능을 노출하고 있으며, 공격자가 기존 토큰 승인을 악용하여 transferFrom을 호출해 자산을 탈취할 수 있게 합니다.
그러나 두 피해자 컨트랙트 모두 소스가 비공개이며, 디컴파일 시 수천 줄의 코드로 확장되고 깊이 중첩된 복잡한 분기 로직을 포함하여 분석 난이도를 크게 높입니다. 또한 피해 프로젝트들이 이후 공개한 사후 분석 보고서 [3, 4]는 주로 복구 및 대응에 초점을 맞추었으며, 근본적인 기술적 세부 사항에 대한 논의는 제한적이었습니다. 그 결과, 취약한 호출 경로가 어떻게 구성되었는지, 그리고 기존의 검사들이 왜 악용을 방지하지 못했는지를 포함한 몇 가지 중요한 질문들이 답변되지 않은 채로 남아 있습니다.
본 보고서에서는 디컴파일된 바이트코드와 온체인 실행 추적을 기반으로 보다 상세한 기술적 분석을 제공합니다. 소스 코드의 부재로 가시성이 제한되지만, 바이트코드 수준의 분석은 취약한 로직을 재구성하기에 충분하며, 고수준 알림에서는 즉시 명확하지 않은 컨트랙트 설계에 관한 몇 가지 흥미로운 관찰을 드러냅니다.
SwapNet 사건에 대한 심층 분석을 시작으로, 이어서 Aperture Finance 사건에 대한 상세 분석을 진행합니다.
SwapNet 사건
배경
SwapNet [5] 은 AMM 및 프라이빗 마켓 메이커를 포함한 다수의 온체인 소스에서 유동성을 집계하여 최적의 스왑 경로를 찾는 DEX 애그리게이터입니다. 이 프로토콜은 또한 사용자가 스왑 실행 시 커스텀 라우터 또는 풀을 지정할 수 있도록 허용하여 추가적인 유연성을 제공합니다.
근본 원인 분석
이 사건은 사용자 제공 입력값에 대한 불충분한 검증에서 비롯되었으며, 공격자가 임의의 파라미터로 transferFrom() 호출을 유발할 수 있게 합니다. 그 결과, 피해자 컨트랙트(예: 0x616000e384Ef1C2B52f5f3A88D57a3B64F23757e)에 이미 승인된 자산이 공격자에게 전송될 수 있습니다.
디컴파일된 바이트코드에 기반하면, 0x87395540() 함수는 핵심 입력값에 대한 적절한 검증이 부재한 것으로 보입니다. 예상되는 라우터 또는 풀 주소를 토큰 주소(예: USDC)로 교체함으로써, 컨트랙트는 해당 토큰을 유효한 실행 대상으로 잘못 처리합니다. 이로 인해 공격자가 제어하는 calldata로 저수준 호출이 실행됩니다.
결과적으로, 피해자 컨트랙트는 approvedAsset.transferFrom(victim, attacker, amount) 형태의 호출을 수행하여 공격자가 승인된 모든 자산을 탈취할 수 있게 합니다.
공격 흐름
SwapNet에 대한 다수의 공격이 관찰되었습니다. 여기서는 Base 트랜잭션 0xc15df1d131e98d24aa0f107a67e33e66cf2ea27903338cc437a3665b6404dd57을 예시로 사용합니다.
공격자는 단순히 악의적인 입력값으로 피해자 컨트랙트의 0x87395540() 함수를 호출했습니다. 이 호출은 두 가지 주요 단계로 구성됩니다.
- 핵심 내부 변수(예:
v51)가 USDC로 설정되어 의도된 라우팅 로직을 우회했습니다.
- 공격자가 제어하는 calldata를 사용하여 저수준 호출이 실행되었으며, 그 결과
USDC.transferFrom()이 호출되어 승인된 모든 USDC가 탈취되었습니다.
손실 요약, 트랜잭션 및 피해 컨트랙트
SwapNet 사건으로 인해 여러 체인에 걸쳐 약 $1,341만의 손실이 발생한 것으로 추정됩니다. 아래 표는 주요 익스플로잇 트랜잭션과 관련된 피해자 컨트랙트 주소를 요약합니다.
Aperture Finance 사건
배경
Aperture Finance [6]는 사용자를 대신하여 Uniswap V3 LP와 같은 집중 유동성 포지션을 관리하는 DeFi 프로토콜입니다. 비공개 소스 컨트랙트(예: 0xD83d960deBEC397fB149b51F8F37DD3B5CFA8913)는 사용자가 네이티브 토큰을 사용하여 Uniswap V3 포지션을 민팅하고 관리할 수 있도록 합니다.
UniswapV3 포지션 민팅을 위한 의도된 워크플로우
0x67b34120() 함수를 통해 Uniswap V3 포지션을 민팅할 때, 컨트랙트는 다음과 같은 의도된 세 단계 워크플로우를 따릅니다:
-
네이티브 토큰 래핑
-
내부 함수
0x1d33()을 통한 네이티브 토큰 스왑 -
UniswapV3 포지션 민팅
문제는 2단계에서 발생합니다: 0x1d33()은 저수준 호출을 통해 커스터마이즈된 스왑을 수행하는데, 여기서 핵심 파라미터(예: 호출 대상 및 calldata)가 사용자 제어 하에 있고 충분한 검증이 이루어지지 않아 의도하지 않은 외부 호출이 가능합니다. 자세한 내용은 다음 섹션에서 제공됩니다.
근본 원인 분석
SwapNet 사례와 유사하게, Aperture Finance 사건은 저수준 호출에 대한 불충분한 입력 검증으로 인해 발생했습니다. 0x67b34120()이 호출될 때, 내부 함수 0x1d33()은 호출 대상이나 함수 선택자에 대한 엄격한 제약 없이 사용자가 제공한 calldata를 사용하여 저수준 호출을 실행합니다.
아래 그림에서 볼 수 있듯이, 저수준 호출을 유발하는 데 사용되는 calldata는 순전히 공격자의 입력값에 기반합니다.
이를 통해 공격자는 피해자 컨트랙트의 맥락에서 approvedToken.transferFrom(victim, attacker, amount)이 실행되는 악의적인 calldata를 구성할 수 있습니다. 그 결과, ERC20 토큰뿐만 아니라 승인된 Uniswap V3 포지션 NFT도 탈취될 수 있습니다.
공격 흐름
Aperture Finance에 대한 다수의 공격이 관찰되었습니다. 이 섹션에서는 Ethereum 트랜잭션 0x8f28a7f604f1b3890c2275eec54cd7deb40935183a856074c0a06e4b5f72f25a을 대표적인 예시로 사용합니다.
-
공격자는 공격 컨트랙트
0x5c92884dFE0795db5ee095E68414d6aaBf398130을 생성했습니다. -
공격 컨트랙트는 악의적인 입력값과
100wei ETH(즉,msg.value==100)로0x67b34120()함수를 호출했습니다.
- a) 네이티브 ETH가
WETH.deposit()함수를 통해 WETH로 래핑되었습니다.
- b) 내부 함수
0x1d33()이 저수준 호출을 수행하기 위해 호출되었습니다. 이 단계에서 피해자 컨트랙트의 맥락에서WBTC.transferFrom(victim, attacker, amount)호출이 실행되어 공격자가 승인된 토큰을 탈취할 수 있었습니다. 함수0x1d33()말미에서 잔액 검사가 통과되었다는 점은 주목할 만합니다. 구체적으로, 함수0x1d33()은 잔액 변화를 공격자가 직접 지정한 스왑 출력값(즉,varg2.word2)과 비교했습니다. 그 결과, 아무것도 수신하지 않은 채 실행이 성공적으로 완료되었습니다.
- 마지막으로,
NonfungiblePositionManager.mint()함수가 호출되어100weiWETH를 사용하여 공격자를 위한 포지션이 민팅되었습니다.
흥미로운 발견
정상 트랜잭션과 비정상 트랜잭션을 비교하면, 두 트랜잭션 모두 동일한 스펜더(예: OKX DEX: TokenApprove)에게 토큰을 승인했지만 서로 다른 라우터 주소(즉, DexRouter와 WBTC)를 지정했음을 확인했습니다. 이는 컨트랙트가 승인 스펜더에 대한 검증은 시행하면서 실제 실행 대상에 대한 검증은 실패하여, 임의 호출을 통해 악용 가능한 치명적인 허점을 남겼음을 시사합니다.
손실 요약, 트랜잭션 및 피해 컨트랙트
Aperture Finance 사건으로 인해 여러 체인에 걸쳐 약 $367만의 총 손실이 발생한 것으로 추정됩니다. 아래 표는 주요 익스플로잇 트랜잭션과 관련된 피해자 컨트랙트 주소를 요약합니다.
결론
SwapNet과 Aperture Finance 사건은 서로 다른 프로토콜과 체인에 영향을 미쳤지만, 두 경우 모두 근본적인 문제는 복잡하지 않습니다: 토큰 승인을 보유한 컨트랙트에서 사용자 제어 저수준 호출과 불충분한 입력 검증의 결합입니다. 이러한 사건들은 컨트랙트 설계의 유연성이 특히 외부 검토가 제한된 비공개 소스 시스템에서 엄격한 호출 제약과 신중하게 균형을 이루어야 한다는 점을 상기시켜 줍니다.
참고문헌
[1] https://x.com/Phalcon_xyz/status/2015614087443697738
[2] https://x.com/Phalcon_xyz/status/2015624519898234997
[3] https://meta.matcha.xyz/SwapNet-Incident-Post-Mortem
[4] https://x.com/ApertureFinance/status/2015938720453820752
[6] https://x.com/ApertureFinance
BlockSec 소개
BlockSec은 풀스택 블록체인 보안 및 암호화폐 컴플라이언스 제공업체입니다. 저희는 고객이 프로토콜 및 플랫폼의 전체 수명주기에 걸쳐 코드 감사(스마트 컨트랙트, 블록체인 및 지갑 포함)를 수행하고, 실시간으로 공격을 차단하며, 사건을 분석하고, 불법 자금을 추적하며, AML/CFT 의무를 이행할 수 있도록 제품과 서비스를 구축합니다.
BlockSec은 저명한 학술 컨퍼런스에서 다수의 블록체인 보안 논문을 발표했으며, DeFi 애플리케이션의 여러 제로데이 공격을 보고했고, 2,000만 달러 이상을 구제하기 위해 다수의 해킹을 차단했으며, 수십억 달러 규모의 암호화폐를 보호했습니다.
-
공식 웹사이트: https://blocksec.com/
-
공식 트위터 계정: https://twitter.com/BlockSecTeam
-
🔗 BlockSec 감사 서비스 : 문의 제출



