Back to Blog

주간 Web3 보안 사고 요약 | 2026년 2월 9일 – 2월 15일

Code Auditing
February 18, 2026
12 min read

지난 한 주(2026년 2월 9일~2월 15일) 동안 BlockSec은 세 건의 공격 사건을 탐지하고 분석하였으며, 총 추정 피해액은 약 $657K입니다. 아래 표는 각 사건을 요약하며, 각 사례에 대한 상세 분석은 이후 소절에서 제공됩니다.

날짜 사건 유형 추정 손실
2026/02/10 알 수 없는 사건 잘못된 비즈니스 로직 ~$10K
2026/02/14 OCA 사건 잘못된 비즈니스 로직 ~$422K
2026/02/14 SOF 사건 잘못된 비즈니스 로직 ~$225K

1. 알 수 없는 사건

간략 요약

2026년 2월 10일, BNB 스마트 체인의 컨트랙트 0x560d39가 공격을 받아 약 $10K의 피해가 발생했습니다. 근본 원인은 함수 0xb1a87f2c()의 잘못된 비즈니스 로직으로, 유동성 추가 과정이 샌드위치 공격에 취약하게 만들었습니다.

배경

컨트랙트 0x560d39의 함수 0xb1a87f2c()는 입력 매개변수를 기반으로 사용자로부터 해당 금액의 USDT를 전송합니다. 수령한 USDT는 처리되며, 전체의 **85%**가 이후 유동성 작업에 할당됩니다.

이 85% 중 절반은 PancakeSwap 풀을 통해 AFX로 스왑되며, 획득한 AFX는 컨트랙트 0x671ce4로 전송됩니다. 그런 다음 함수는 0x671ce4에서 AFX를 인출합니다.

다음으로, PancakeSwap V2 라우터를 통해 나머지 절반의 85% USDT0x671ce4에서 인출한 AFX를 사용하여 USDT-AFX 거래 쌍에 유동성을 추가합니다. 남은 USDT 또는 AFX는 사용자에게 환불됩니다.

USDT–AFX 유동성 추가가 완료된 후, 함수는 주소 0x146933에서 추가 AFX 토큰을 가져옵니다. 0x146933에서 가져오는 AFX의 양은 이전에 0x671ce4에서 인출한 양과 일치하도록 설정됩니다. 다음으로, 함수는 PancakeSwap V2 AFX–AHT 유동성 풀의 현재 가격 비율을 기반으로 필요한 AHT의 양을 계산합니다. 그런 다음 0x146933에서 얻은 AFX와 이에 상응하는 AHT(역시 0x146933에서 조달)를 공급하여 AFX–AHT 거래 쌍에 유동성을 추가합니다.

취약점 분석

취약한 컨트랙트는 0x560d39입니다. 컨트랙트 0x146933AFX-AHT 유동성 추가에 사용되는 AFX의 자금 출처 역할을 하며 최종적으로 손실을 부담합니다.

근본 원인은 0x560d39의 함수 0xb1a87f2c()의 잘못된 비즈니스 로직에 있습니다. 컨트랙트 0x671ce4를 통해 USDT를 스왑하여 얻은 AFX를 회수할 때, 함수는 스왑 전후 0x671ce4AFX 잔액 변화를 검증하지 않습니다. 대신, 0x671ce4가 보유한 모든 AFX를 인출합니다.

이로 인해 공격자는 대량의 AFX를 미리 0x671ce4에 기부한 후, 소량의 USDT만으로 0xb1a87f2c()를 호출할 수 있습니다. 0x146933에서 가져오는 AFX의 양이 0x671ce4에서 인출한 AFX와 일치하도록 정의되어 있기 때문에, 0x671ce4에서의 인출량을 부풀리면 0x146933AFX-AHT 유동성 추가에 과도하게 큰 양의 AFX를 제공하도록 강제할 수 있습니다.

공격자는 0x560d39에서 남은 USDTAFX의 환불을 통해 기부금을 회수할 수 있으며, 0x146933이 과도한 유동성 공급의 비용을 부담하게 됩니다.

공격자는 이후 피해 트랜잭션을 둘러싸고 AFX에서 AHT로의 선행 스왑과 AHT에서 AFX로의 후행 스왑으로 AFX-AHT 유동성 추가를 샌드위치 공격함으로써 수익을 얻습니다.

공격 분석

공격 트랜잭션의 주요 단계는 다음과 같이 요약됩니다:

  • 1단계: 공격자는 PancakeSwap V2에서 1,130,500e18 AFX 토큰을 플래시 론했습니다.

  • 2단계: 공격자는 511,965e18 AFX를 컨트랙트 0x671ce4로 전송했습니다.

  • 3단계: 공격자는 나머지 AFX를 PancakeSwap V2의 AFX-AHT 풀에서 52,316e18 AHT로 스왑했습니다. AHT는 전송 수수료 토큰이므로, 공격자는 최종적으로 26,158e18 AHT만 받았습니다.

  • 4단계: 공격자는 컨트랙트 0x560d39를 호출하여 매개변수를 100으로 설정하고 함수 0xb1a87f2c()를 실행했습니다. 함수가 0x671ce4에서 모든 AFX(공격자가 기부한 토큰 포함)를 인출했기 때문에, USDT-AFXAFX-AHT 쌍 모두에 불균형하게 많은 양의 유동성을 추가하려 했습니다. 쌍을 이루지 못한 남은 USDTAFX는 공격자에게 환불되어 대부분의 비용을 회수할 수 있었습니다.

  • 5단계: 공격자는 26,158e18 AHT1,129,417e18 AFX로 스왑했습니다.

  • 6단계: 공격자는 플래시 론을 상환하고 남은 AFXUSDT로 스왑하여 약 $10K의 수익을 얻었습니다.

결론

이 사건은 컨트랙트 0x560d39USDT 스왑을 통해 얻은 AFX를 회수할 때, 스왑 전후 컨트랙트 0x671ce4AFX 잔액 변화를 검증하지 않고 컨트랙트 0x671ce4에서 모든 AFX를 직접 인출한 것이 원인이었습니다.


2. OCA 사건

간략 요약

2026년 2월 14일, BNB 스마트 체인의 알 수 없는 프로토콜이 공격을 받아 약 $422K의 손실이 발생했습니다. 근본 원인은 잘못된 비즈니스 로직이었습니다: 스왑이 완료된 후, 프로토콜은 OCA 토큰 컨트랙트의 재활용 함수를 호출하여 DEX에서 토큰을 회수하고 이를 호출자 및 다른 지정된 주소들에 반환합니다. 이러한 OCA 토큰의 일방적인 인출은 풀의 OCA 준비금을 인위적으로 감소시켜 온체인 가격을 부풀리며, 공격자가 풀에서 USDC를 반복적으로 탈취할 수 있게 합니다.

배경

프로토콜 컨트랙트(0xe0d5ec)는 사용자가 지정한 양의 OCA를 DEX에서 USDC로 판매하는 sellOCA() 함수(셀렉터 0x9c1dad28)를 제공합니다. OCA에는 디플레이션 "재활용" 메커니즘이 포함되어 있습니다: 스왑 후, 컨트랙트는 방금 풀에 판매된 것과 동일한 양의 OCA를 다시 가져와 호출자 및 다른 지정된 주소들에 재분배합니다. OCA가 이미 USDC가 지불된 후에 풀에서 제거되기 때문에, 풀의 OCA 준비금은 감소하는 반면 USDC 준비금은 더 낮게 유지되어 온체인 OCA 가격이 인위적으로 상승합니다.

취약점 분석

핵심 취약점은 sellOCA()의 스왑 후 클로백이 반복 가능한 가격 조작 기본 요소를 만든다는 것입니다. 각 호출은 DEX 풀에 다음과 같은 순 효과를 가집니다: 풀은 스왑 중에 USDC를 잃고 디플레이션 메커니즘이 풀에서 토큰을 회수할 때 OCA도 잃는 반면, 호출자는 스왑 수익으로 USDC를 받고 재분배를 통해 OCA를 회수합니다. 풀의 OCA 준비금이 거래 균형을 맞출 USDC 유입 없이 감소하기 때문에, 각 사이클은 DEX에서 OCA/USDC 가격을 인위적으로 부풀립니다. 공격자는 OCA를 구매하고 sellOCA()를 호출하여 클로백을 유발한 다음, 회수한 OCA를 부풀려진 가격에 판매하는 과정을 반복함으로써 풀에서 USDC 유동성을 점진적으로 탈취할 수 있습니다.

공격 분석

공격 트랜잭션의 주요 단계는 다음과 같이 요약됩니다:

  • 1단계: 8,704,860e18 USDC를 플래시 론했습니다.

  • 2단계: PancakeSwap에서 8,704,860e18 USDC940,991e18 OCA로 스왑했습니다.

  • 3단계: 전체 940,991e18 OCA로 sellOCA()를 호출했습니다. 함수는 DEX에서 OCAUSDC로 스왑한 후, 디플레이션 재활용 메커니즘이 판매된 OCA를 풀에서 다시 가져와 재분배하여 — 호출자에게 OCA를 반환했습니다. 결과적으로, 공격자는 스왑 수익으로 USDC를 받는 동시에 OCA 토큰도 회수했습니다. 풀의 OCA 준비금이 급격히 감소하여 OCA 가격이 상승했습니다.

  • 4단계: 회수된 940,991e18 OCA를 PancakeSwap에서 현재 부풀려진 가격으로 USDC로 스왑한 후, 2~4단계를 반복하여 풀을 점진적으로 탈취했습니다.

  • 5단계: 마지막 반복에서, 공격자는 9,999e18 OCA만으로 433,238e18 USDC를 스왑하고(대폭 부풀려진 OCA 가격 반영), 플래시 론을 상환하여 공격을 완료했습니다.

결론

이 공격의 근본적인 원인은 프로토콜의 sellOCA 흐름의 로직 결함이었습니다: 사용자가 공급한 OCAUSDC로 스왑한 후, 컨트랙트는 OCA의 디플레이션 ``회수'' 메커니즘을 통해 DEX에서 OCA 입력의 거의 전부를 회수하여 호출자 및 다른 지정된 주소들에 재분배했습니다. 이 스왑 후 클로백은 유동성 풀에 남아 있는 OCA 잔액을 인위적으로 감소시켜 온체인 OCA 가격이 급격히 상승하도록 만들었습니다. "OCA 구매 → sellOCA 호출로 클로백 유발 → 부풀려진 가격에 OCA 되팔기"를 반복하는 방식으로, 공격자는 비교적 적은 양의 OCA로 거의 모든 USDC 유동성을 탈취할 수 있었습니다.


3. SOF 사건

간략 요약

2026년 2월 14일, BNB 스마트 체인의 SOF 토큰이 _update() 로직 및 수수료 면제 시스템의 잘못된 화이트리스트 메커니즘으로 인해 약 $225K의 피해를 입었습니다. 이 취약점은 공격자가 수수료 면제 주소를 이용해 매수 제한을 우회하고, 이후 Uniswap V2(PancakeSwap) 풀 준비금을 조작하는 매도 시 소각 메커니즘을 유발할 수 있게 했습니다. 풀이 자신의 토큰을 소각 주소로 전송하도록 강제하고 즉시 sync()를 호출함으로써, 공격자는 토큰 가격을 인위적으로 부풀렸습니다. 이를 통해 조작된 환율로 소량의 SOF를 스왑하여 풀에서 USDT를 탈취할 수 있었습니다. 이 공격은 tx.origin을 추적하지 못하는 불충분한 플래시론 가드로 인해 더욱 용이해졌으며, 여러 주소를 사용하여 동일한 트랜잭션 내에서 매수 및 매도 단계를 수행할 수 있었습니다.

배경

SOF는 BNB 스마트 체인에 배포된 BEP-20 토큰으로, 맞춤형 디플레이션 메커니즘과 자동화된 수수료 관리를 갖추도록 설계되었습니다. 이 토큰은 거래를 용이하게 하기 위해 Uniswap V2 호환 유동성 쌍(특히 USDT와의 PancakeSwap)과 상호작용합니다.

수수료 면제 사용자의 경우, 매수 및 매도 작업은 수수료가 없습니다. 그 외 모든 사용자의 경우, 매수 작업은 제한되어 있으며 되돌림(revert)이 발생합니다.

매도 작업 중, 컨트랙트는 매도 금액의 90%를 페어에서 _destroyAddress로 직접 전송하고 sync()를 호출하여 준비금이 즉시 감소한 잔액을 반영하도록 업데이트합니다.

취약점 분석

근본 원인은 0x1f3863 컨트랙트의 438번째 줄에 있는 _update() 함수의 잘못된 화이트리스트 메커니즘에서 비롯됩니다. to 주소가 화이트리스트에 등록되어 있으면, 어떤 from이든 매수 작업을 처리할 수 있습니다.

 /// SOF.sol:433-480
433|      function _update(
434|          address from,
435|          address to,
436|          uint256 amount
437|      ) internal override {
438|          if (isExcludedFromFees[to] || isExcludedFromFees[from]) {
439|              super._update(from, to, amount);
440|              return;
441|          }
442|  
443|          require(!_blackList[from] && !_blackList[to], "refuse address");
444|  
445|          if (!inSwap && _isPairs[to]) {
446|              if (feeAmount1 >= swapTokensAtAmount) {
447|                  swapTokenForUsdt(feeAmount1, feeAddress);
448|                  feeAmount1 = 0;
449|              }
450|              if (feeAmount2 >= swapTokensAtAmount) {
451|                  swapTokenForUsdt(feeAmount2, feeAddress2);
452|                  feeAmount2 = 0;
453|              }
454|          }
455|  
456|          bool isSell;
457|          uint256 taxAmount;
458|  
459|          if (_isPairs[from]) {
460|              //buy
461|              revert("not alw buy");
462|          } else if (_isPairs[to]) {
463|              //sell
464|  
465|              isSell = true;
466|              taxAmount = takeFee(from, amount);
467|              super._update(_uniswapV2Pair, _destroyAddress, amount - taxAmount);
468|              IUniswapV2Pair(_uniswapV2Pair).sync();
469|          }
470|  
471|          emit TranserFeeLog(amount, taxAmount);
472|  
473|          if (isSell) {
474|              _antiFlashloanGuard(from, to, false, isSell);
475|          }
476|  
477|          amount = amount - taxAmount;
478|  
479|          super._update(from, to, amount);
480|      }

공격 분석

공격 트랜잭션의 주요 단계는 다음과 같이 요약됩니다:

  • 1단계: 공격자는 2단계를 위해 315,520,309e18 USDT를 플래시 론하고, 3단계를 위해 875e18 SOF를 주소 0xc4DB5B로 전송했습니다.

  • 2단계: swapTokensForExactTokens()를 통해 313,567,718e18 USDT991,223e18 SOF로 스왑했습니다. to 주소는 수수료 면제 주소였으며, 이는 SOF 컨트랙트의 isExcludedFromFees[to] 검사를 충족하여 _isPairs[from] 검사를 건너뜁니다(그렇지 않으면 매수 작업이 되돌아감). 이를 통해 공격자는 3단계에서 풀의 거의 모든 SOF 토큰을 소각할 수 있게 됩니다. 또한 이는 _antiFlashloanGuard() 검사를 우회합니다 — 컨트랙트가 이 매수 작업을 기록하지 않아 3단계가 차단 없이 진행될 수 있습니다. 중요한 점은, 이 대규모 매수가 페어에 787e18 SOF만 남도록(313,816,344e18 USDT와 함께) 설계되었다는 것입니다.

  • 3단계: 주소 0xc4DB5B에서 swapExactTokensForTokensSupportingFeeOnTransferTokens()를 통해 875e18 SOFUSDT로 스왑했습니다. PancakeSwap 라우터 V2는 먼저 SOF.transferFrom()을 실행한 다음 스왑을 처리합니다. SOF.transferFrom() 중에, _update()의 매도 로직이 875e18의 90%(즉, 787e18)를 페어에서 _destroyAddress로 전송합니다 — 2단계에서 설계된 바와 같이, 이는 페어의 SOF 잔액의 거의 전부였습니다. 이 소각과 sync() 이후, 페어는 313,816,344e18 USDT와 단 10e9 SOF만 보유하게 됩니다. SOF 가격이 천문학적으로 부풀려진 상태에서, 이후 스왑은 막대한 USDT 지급을 산출했습니다.

  • 4단계: 공격자는 플래시 론을 상환하고 약 $225K의 수익을 유지했습니다.

결론

이 취약점은 매도 전 소각 메커니즘을 지원하는 토큰의 경우, 토큰을 매수할 수 있는 자를 제어하는 것이 매우 중요함을 보여줍니다. 토큰을 매도할 수 있는 자는 누구든 수익을 얻을 수 있으며; 공격자가 풀에서 토큰을 매수할 수 있다면, 가격을 인위적으로 부풀린 후 되팔아 전체 풀을 탈취할 수 있습니다.

조사에 따르면 _antiFlashloanGuard() 함수가 부적절하게 구현되어 있습니다. 이 함수는 tx.origin을 추적하는 대신 동일한 msg.sender의 매수 및 매도만을 제한합니다. 이로 인해 공격자는 매수 작업 중 수수료 면제 주소를 to(수신자) 주소로 선택하여 가드를 우회할 수 있습니다.

유사한 공격을 방지하기 위해, 개발자는 권한이 부여된 역할만 풀에서 매수할 수 있도록 보장해야 합니다. 또한, _antiFlashloanGuard() 구현은 공격자가 동일한 트랜잭션 내에서 여러 주소를 사용하여 매수 및 매도 작업을 실행하는 것을 방지하기 위해 tx.origin과 사용자 주소를 모두 기록해야 합니다.


BlockSec 소개

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

BlockSec은 권위 있는 컨퍼런스에 다수의 블록체인 보안 논문을 발표하고, DeFi 애플리케이션의 여러 제로데이 공격을 보고하였으며, 다수의 해킹을 차단하여 2,000만 달러 이상을 구제하고, 수십억 달러 규모의 암호화폐를 보호해왔습니다.

Sign up for the latest updates
~$160만 손실: Moke 토큰, LpdFi 익스플로잇 | BlockSec 위클리
Security Insights

~$160만 손실: Moke 토큰, LpdFi 익스플로잇 | BlockSec 위클리

2026년 8월 3~9일, BNB 체인에서 2건의 보안 사고가 발생해 총 약 160만 달러의 손실이 발생했으며, 모두 가격 조작이 원인이었습니다. LpdFi(약 69.7만 달러)는 PancakeSwap 유동성 풀을 주문 평가와 이자 정산에 동시 사용해 공격자가 원금을 부풀리고 과도한 이자를 탈취했습니다. Moke Token(약 90.6만 달러)은 조작 가능한 현물 가격과 중복 LP 배당 회계를 결합해 MOKE를 부풀려 BNB 배당을 반복 수령했습니다.

COLDCARD 사건: 지갑의 "무작위" 시드가 무작위가 아니었을 때
Security Insights

COLDCARD 사건: 지갑의 "무작위" 시드가 무작위가 아니었을 때

COLDCARD 펌웨어의 빌드 통합 버그로 비트코인 시드 생성이 취약한 소프트웨어 RNG로 라우팅되어 지갑 시드가 오프라인 복구 가능해졌습니다. 시드 자체의 취약점이므로 펌웨어 업데이트로 해결 불가하며, 2026년 8월 7일 기준 확인된 피해는 1,405 BTC(~9,100만 달러), 비공개 추정치는 최대 2,055 BTC입니다.

~$88M 손실: COLDCARD 및 LULA 익스플로잇 | BlockSec 위클리
Security Insights

~$88M 손실: COLDCARD 및 LULA 익스플로잇 | BlockSec 위클리

2026년 7월 27일~8월 2일, 비트코인과 BNB 체인에서 약 8,800만 달러 손실을 유발한 두 건의 보안 사고가 발생했습니다. COLDCARD 사고는 하드웨어 지갑 펌웨어의 엔트로피 오류로, RNG 매크로 활성화 여부 미확인으로 결정론적 폴백이 실행되어 약 1,370 BTC(~8,800만 달러)가 탈취됐습니다. BNB 체인의 LULA 토큰은 비즈니스 로직 취약점으로 `recycle()` 함수가 악용되어 PancakeSwap V2 유동성에서 약 57만 8천 달러가 유출됐습니다.

Best Security Auditor for Web3

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

BlockSec Audit
주간 Web3 보안 사고 요약 | 2026년 2월 9일 – 2월 15일