Back to Blog

#9 1inch 사고: 콜데이터 손상에서 위조 정산까지: 바이너리 익스플로잇의 온체인 전이

Code Auditing
February 13, 2026
5 min read

2025년 3월 5일, 1inch의 Fusion V1 프로토콜과 통합된 서드파티 리졸버 컨트랙트가 조직적인 익스플로잇 공격을 받아 총 500만 달러 이상의 피해가 발생했습니다. 근본 원인은 정산 흐름에서의 안전하지 않은 calldata 재구성이었으며, 공격자가 제어하는 인터랙션 길이값이 suffix 조립 과정에서 포인터 언더플로우를 유발하여 위조된 정산 데이터가 주입될 수 있었습니다. 이 익스플로잇은 잘못 설정된 신뢰 경계에 의해 더욱 가능해졌는데, 리졸버 컨트랙트가 msg.sender만을 기준으로 정산 컨트랙트가 전달하는 모든 calldata를 암묵적으로 신뢰함으로써, 모든 접근 제어 검사를 통과함에도 불구하고 공격자가 제어하는 데이터가 정산 수준의 권한을 상속받게 되었습니다.

이 사건은 새로운 금융 프리미티브를 활용해서가 아니라, 저수준 ABI 및 메모리 레이아웃 가정을 악용함으로써 스마트 컨트랙트 취약점과 전통적인 바이너리 익스플로잇 기법 사이의 경계를 흐린다는 점에서 2025년 가장 정교한 DeFi 익스플로잇 중 하나로 주목받고 있습니다.

배경

1inch의 Fusion V1 프로토콜

1inch는 사용자에게 최적화된 스왑 실행을 제공하기 위해 여러 DEX에서 유동성을 조달하는 탈중앙화 거래소(DEX) 애그리게이터입니다. 애그리게이터의 지정가 주문 인프라 위에 구축된 1inch Fusion은 더치 옥션 기반의 주문 매칭 모델을 도입하여, 사용자가 가격 범위 및 스왑 시간 창과 같은 유연한 실행 파라미터를 지정할 수 있도록 합니다.

Fusion 모델에서 사용자 주문은 프로토콜 자체에 의해 직접 체결되지 않습니다. 대신, 리졸버라고 알려진 특수 행위자에 의해 실행됩니다. 리졸버는 권한을 가진 화이트리스트 참가자로 볼 수 있으며, 자격을 얻으려면 충분한 유니콘 파워를 획득하기 위해 토큰을 스테이킹해야 하며, 이는 경제적 게이트키핑 메커니즘으로 작동합니다.

운영 측면에서 리졸버는 1inch의 백엔드 API와 연동되는 자체 오프체인 인프라를 운영하여 사용자 주문을 발견하고 체결 여부 및 시기를 결정합니다. 리졸버가 주문 실행을 결정하면, 전용 계정을 통해 Settlement 컨트랙트에 온체인 트랜잭션을 제출하고, Settlement 컨트랙트가 실제 스왑을 수행합니다. (Fusion은 리졸버 간의 경쟁적인 더치 옥션을 포함하지만, 이 메커니즘은 공격 이해에 필수적이지 않으므로 생략합니다. 단순화를 위해 리졸버가 사용자의 주문 조건을 직접 충족할 수 있다고 가정합니다.)

스왑을 실행할 때 리졸버는 사용자의 최소 요건보다 더 나은 실행을 제공하기 위해 외부 시장에서 유동성을 조달하거나, 자신의 자산을 사용하여 거래를 직접 정산할 수 있습니다. 이 과정에서 발생하는 잉여 가치는 리졸버의 수익으로 귀속됩니다. 이 블로그에서 다루는 공격은 이러한 리졸버 컨트랙트를 대상으로 합니다. 구체적으로, 자산을 보유하고 Settlement 컨트랙트에 승인을 부여한 온체인 시장 조성에 사용되는 컨트랙트가 대상이었으며, 이로 인해 해당 자산의 손실이 발생했습니다.

주문 처리 및 체결

1inch Fusion의 주문 실행은 Settlement 컨트랙트가 조율하며, 선형적인 실행 흐름이 아닌 인터랙션 데이터에 의해 구동되는 재귀적 정산 모델을 따릅니다.

프로세스는 리졸버가 settleOrders() 함수를 호출할 때 시작되며, 첫 번째 주문과 인터랙션 페이로드를 인코딩한 calldata를 전달합니다. Settlement는 모든 주문을 한 번에 정산하려 하지 않고, 내부 _settleOrder() 함수의 반복 호출을 통해 점진적으로 처리합니다.

각 주문에 대해 _settleOrder() 함수는 메모리에서 Limit Order Protocol(AggregationRouterV5.fillOrderTo())에 대한 호출을 재구성합니다. 이 재구성 과정에서 Settlement는 동적 suffix 형태로 리졸버 관련 컨텍스트를 인터랙션 데이터에 추가합니다. 이 suffix는 리졸버 신원 및 누적 수수료와 같은 실행 메타데이터를 담고 있으며, Limit Order Protocol은 이를 불투명하게 처리합니다. 변경 없이 전달되며 나중에 인터랙션 콜백 중에 Settlement 자체에 의해 디코딩됩니다.

주문이 체결된 후, fillOrderInteraction() 함수를 통해 제어권이 Settlement로 반환됩니다. 인터랙션 데이터를 기반으로 Settlement는 남은 인터랙션 페이로드로 _settleOrder() 함수를 재귀적으로 호출하여 정산을 계속하거나, 최종화 단계로 전환합니다. 최종 단계에서 Settlement는 리졸버 컨트랙트의 resolveOrders() 함수를 호출하여 누적된 실행 컨텍스트와 함께 리졸버 컨트랙트로 제어권을 전달합니다.

이 설계는 단일 트랜잭션 내에서 여러 주문을 순차적으로 정산하면서, 모든 프로토콜 수준의 실행 단계가 완료될 때까지 리졸버별 로직을 지연시킬 수 있게 합니다.

취약점 분석

취약점은 내부 _settleOrder() 함수의 안전하지 않은 calldata 재구성 로직에서 발생하며, 특히 인터랙션 데이터에 추가되는 동적 suffix의 배치 과정에서 나타납니다.

리졸버 컨트랙트는 명시적인 접근 제어로 보호됩니다: 호출이 Settlement 컨트랙트에서 시작되어야 하고, 해결 과정에서 제공된 리졸버 주소가 리졸버 컨트랙트 자신과 일치해야 합니다. 이 검사들은 정산 과정에서 전파되는 리졸버 신원이 올바르게 구성되어 그대로 유지된다고 가정합니다. 이 가정은 calldata 재구성 과정에서 리졸버 관련 데이터가 인코딩되고 추가되는 방식의 정확성에 달려 있습니다.

구체적으로, 리졸버의 resolveOrders()는 두 가지 검사를 강제합니다:

require(msg.sender == _settlement, OnlySettlement());
require(this == resolver, NotTaker());

첫 번째 검사는 호출이 Settlement 컨트랙트에서 시작되었음을 확인합니다. 두 번째 검사는 suffix에서 디코딩된 resolver 파라미터가 리졸버 컨트랙트 자신의 주소와 일치하는지 확인합니다. 정상 운영 시 두 필드는 _settleOrder()에 의해 올바르게 설정됩니다. 공격 시에도 두 검사는 통과됩니다: 공격자는 정산 흐름 내부에서 작동하므로(외부가 아님) msg.sender는 진정한 Settlement 컨트랙트이며, resolver 필드는 위조된 suffix에서 디코딩되고 공격자가 피해 리졸버의 주소를 기록했습니다.

정산 과정에서 _settleOrder()는 메모리에서 calldata를 재구성하고 리졸버별 실행 컨텍스트를 담은 동적 suffix를 추가합니다. 이 suffix에는 리졸버 주소뿐만 아니라 리졸버가 정산을 합법적인 것으로 해석하는 데 의존하는 주문 관련 정보도 포함됩니다. suffix는 ptr + interactionOffset + interactionLength로 계산된 메모리 위치에 기록되며, 여기서 interactionLength는 calldata에서 전체 32바이트 값으로 직접 읽혀집니다.

이 오프셋 계산이 범위 검사 없이 수행되기 때문에, 공격자는 interactionLength를 제어하여 산술 오버플로우를 유발하고 suffix가 메모리에 기록되는 위치를 조작할 수 있습니다. 이를 통해 공격자는 의도된 suffix를 위조된 suffix로 교체하여, 공격자가 제어하는 주문 컨텍스트와 함께 임의의 리졸버 주소를 제공할 수 있습니다.

결과적으로, 정산 흐름이 나중에 suffix를 디코딩할 때, 실제로는 어느 가정도 성립하지 않음에도 불구하고 합법적인 리졸버에서 유효한 주문 데이터와 함께 실행이 시작된 것으로 해석할 수 있습니다. 공격자는 사실상 수 wei를 수백만 달러와 교환하기 위해 리졸버인 척하면서 자신의 버전의 주문 suffix를 주입할 수 있게 됩니다.

공격 분석

트랜잭션 0x74bc를 예시로 살펴보겠습니다. 공격은 무시할 수 있는 양의 토큰(수 wei)을 불균형하게 큰 출력 금액으로 교환하는 다섯 개의 유효한 주문 생성으로 시작됩니다. 이 주문들은 구문적으로 유효하며 프로토콜 수준의 검사를 통과합니다.

그런 다음 공격자는 주문 calldata를 대량의 null 바이트 영역으로 패딩합니다. 이 패딩은 잘못된 suffix 배치로 인해 나중에 덮어쓰일 제어된 메모리 영역으로 사용됩니다.

결정적으로, 공격자는 마지막 주문에 유효하지 않은 interactionLength 값을 지정합니다. 이 값은 부호 있는 정수로 해석될 때 -512에 해당하는 0xffff…fe00으로 선택됩니다. interactionLength는 부호 없는 256비트 값으로 처리되어 포인터 산술에 직접 사용되기 때문에, suffix 쓰기 오프셋 계산 시 산술 오버플로우가 발생합니다.

아래의 악의적인 인터랙션 구조는 suffix로 처리됩니다:

위조된 Suffix에서 자산 탈취까지

Settlement가 마지막 주문을 처리할 때, 오버플로우로 인해 합법적인 suffix가 null로 패딩된 영역에 기록되어 0을 무해하게 덮어씁니다. 공격자가 실제 읽기 위치에 배치한 위조된 suffix가 합법적인 정산 컨텍스트로 해석됩니다.

위조된 suffix는 최종화 플래그를 설정하여 Settlement가 재귀적 주문 처리에서 최종화 단계로 전환하게 합니다. Settlement는 suffix에서 디코딩된 주소, 즉 피해 리졸버의 resolveOrders()를 호출합니다. 취약점 분석에서 설명한 바와 같이, 두 접근 제어 검사 모두 통과됩니다: msg.sender는 Settlement 컨트랙트이고(호출이 합법적인 정산 경로를 통해 흐름), resolver는 피해자의 주소와 일치합니다(공격자가 위조된 suffix에 기록).

피해 리졸버는 공격자가 선택한 자산 주소와 금액을 포함하는 tokensAndAmounts 배열을 처리합니다. 리졸버가 정상 운영을 위해 이전에 Settlement 컨트랙트에 토큰 승인을 부여했기 때문에, 이전이 실행됩니다. 리졸버는 수 wei의 입력만 필요한 주문을 체결하기 위해 보유 자산을 전송하게 되어, 500만 달러 이상의 손실이 발생합니다.

요약

이 사건은 1inch의 더 이상 사용되지 않는 Fusion V1 프로토콜과 통합된 서드파티 리졸버 컨트랙트를 대상으로 하여 상당한 손실을 야기했으며, 몇 가지 중요한 교훈을 제시합니다.

  • 안전하지 않은 데이터 가정: 동적으로 구성된 입력 데이터에 의존하는 시스템은 사용자가 영향을 줄 수 있는 부분이 있을 때 길이, 오프셋, 또는 구조적 무결성을 가정해서는 안 됩니다.
  • 암묵적 신뢰 체인: 컨트랙트가 각 경계에서 직접 검증하는 대신 중요한 컨텍스트를 보존하기 위해 상위 컴포넌트에 의존할 때, 보안 검사가 약화될 수 있습니다.
  • 레거시 공격 표면: 구식 컴포넌트를 지원하면 공격 표면이 증가하고 프로토콜이 새로운 익스플로잇 기법에 더 취약해집니다.
  • 크로스 도메인 익스플로잇 패턴: 전통적인 소프트웨어에서 일반적인 취약점은 저수준 메모리나 데이터 레이아웃 로직이 포함될 때 온체인에서 재등장할 수 있습니다.

참고 자료

  1. https://blog.decurity.io/yul-calldata-corruption-1inch-postmortem-a7ea7a53bfd9

  2. https://paragraph.com/@cookies-research/1inch-fusion-cost-efficient-mev-resistant-swaps

  3. https://blog-zh.1inch.com/fusion-swap-resolving-onchain-component/#steps-5-6


BlockSec 소개

BlockSec은 풀스택 블록체인 보안 및 암호화폐 컴플라이언스 제공업체입니다. 저희는 고객이 코드 감사(스마트 컨트랙트, 블록체인 및 지갑 포함)를 수행하고, 실시간으로 공격을 차단하고, 사고를 분석하고, 불법 자금을 추적하며, 프로토콜 및 플랫폼의 전체 라이프사이클에 걸쳐 AML/CFT 의무를 이행할 수 있도록 지원하는 제품과 서비스를 구축합니다.

BlockSec은 저명한 학술 대회에서 다수의 블록체인 보안 논문을 발표했으며, DeFi 애플리케이션의 여러 제로데이 공격을 보고하고, 2,000만 달러 이상을 구제하기 위해 여러 해킹을 차단했으며, 수십억 달러의 암호화폐를 보호했습니다.

Sign up for the latest updates
~$410만 손실: Taiko, SecondFi 익스플로잇 | BlockSec 위클리
Security Insights

~$410만 손실: Taiko, SecondFi 익스플로잇 | BlockSec 위클리

이 주간 블록체인 보안 리포트는 2026년 6월 22~28일 발생한 주요 사건 2건을 다루며, 이더리움과 카르다노에서 약 410만 달러의 피해가 확인됐습니다. Taiko 브릿지 공격은 노출된 SGX 서명 키와 디버그 엔클레이브를 거부하지 못한 증명 정책 결함을 이용해 악성 증명자를 등록하고 L2 상태 증명을 위조했습니다. SecondFi 지갑은 Ed25519 논스 도출 시 비밀 입력이 제거되는 결함으로 공개 트랜잭션 데이터만으로 개인 키 복구가 가능했습니다.

~$18M 손실: jaredFromSubway, Aztec 등 | BlockSec 위클리
Security Insights

~$18M 손실: jaredFromSubway, Aztec 등 | BlockSec 위클리

이 주간 블록체인 보안 보고서는 2026년 6월 15일~21일을 다루며, 이더리움과 BNB 체인에서 3건의 주요 사고가 발생해 약 $18.3M의 손실이 발생했습니다. jaredFromSubway 사건은 MEV 봇이 차익거래를 위해 신뢰할 수 없는 제3자 컨트랙트에 자산을 승인한 역방향 승인 공격으로, 가짜 래퍼 토큰과 스왑 풀을 이용해 약 $15M 손실이 발생했습니다. Aztec은 이스케이프 해치 ZK 회로의 제약 누락으로 공격자가 가짜 머클 트리로 온체인 검증을 통과했습니다.

Web3 컴패니언: 오픈소스 보안 에이전틱 지갑

Web3 컴패니언: 오픈소스 보안 에이전틱 지갑

BlockSec가 Web3 Companion을 오픈소스로 공개했습니다. 이 보안 중심의 에이전트 지갑은 자체 AI 에이전트를 신뢰하지 않는 방식으로 설계되었으며, 키 격리, 강력한 정책, Passkey를 활용해 온체인 자산을 보호합니다.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit