1P by GN⁺ 17일전 | ★ favorite | 댓글 1개
  • Lotusbail 패키지는 합법적인 WhatsApp Web API 라이브러리인 Baileys를 포크한 형태로, 6개월간 npm에서 5만6천 회 이상 다운로드된 악성 코드 포함 패키지
  • 정상적으로 작동하는 API 기능을 제공하면서 WhatsApp 인증 정보, 메시지, 연락처, 미디어 파일을 탈취하고 공격자 서버로 전송함
  • 데이터는 RSA, AES, Base-91, LZString 등 다중 암호화 및 난독화 과정을 거쳐 전송되어 보안 모니터링 회피가 가능함
  • 패키지는 하드코드된 페어링 코드를 통해 공격자 기기를 사용자의 WhatsApp 계정에 영구 연결시키는 백도어를 설치함
  • 이 사례는 공급망 공격의 고도화를 보여주며, 정적 분석만으로는 탐지 불가능한 행동 기반 보안 감시의 필요성을 강조함

Lotusbail 패키지 개요

  • lotusbail은 합법적인 @whiskeysockets/baileys의 포크로, WhatsApp Web API 기능을 그대로 제공함
    • 메시지 송수신이 정상적으로 작동해 개발자가 의심 없이 설치할 가능성이 높음
    • npm에 6개월간 등록되어 있으며, 작성 시점 기준으로 여전히 다운로드 가능 상태임
  • 실제 기능 뒤에는 WhatsApp 자격 증명 탈취, 메시지 가로채기, 연락처 수집, 백도어 설치 등의 악성 행위가 숨겨져 있음

탈취되는 정보

  • 인증 토큰과 세션 키, 전체 메시지 기록, 전화번호 포함 연락처 목록, 미디어 파일 및 문서, 지속적 백도어 접근 권한이 포함됨
  • 모든 데이터는 공격자 서버로 전송되기 전 암호화 처리

작동 방식

실제로 동작하는 위장 기능

  • 대부분의 악성 npm 패키지는 오작동하거나 의심스러운 코드로 쉽게 식별되지만, Lotusbail은 정상적으로 작동하는 API로 위장함
  • 합법적인 Baileys 라이브러리를 기반으로 하며, 메시지 송수신 기능이 완전하게 구현되어 있음
  • 이로 인해 개발자들이 “정상 작동하는 코드”에서는 악성 행위를 의심하지 않게 되는 사회공학적 기법이 사용됨

데이터 탈취 및 전송

  • 패키지는 WhatsApp과 통신하는 WebSocket 클라이언트를 감싸는 형태로 동작함
    • 인증 시 자격 증명을 캡처하고, 메시지 수신·발신 시 내용을 모두 복제함
    • 정상 기능은 그대로 유지되며, 단지 모든 데이터가 공격자에게 이중 전송
  • 탈취된 데이터는 커스텀 RSA 구현으로 암호화되어 전송됨
    • WhatsApp 자체의 종단간 암호화와 별도로 존재하며, 네트워크 감시 회피용 암호화로 사용됨
  • 서버 주소는 코드 내에 직접 노출되지 않고, 암호화된 설정 문자열 속에 숨겨짐
    • Unicode 변수 조작, LZString 압축, Base-91 인코딩, AES 암호화 등 4단계 난독화 적용

백도어 설치

  • WhatsApp의 기기 페어링 코드 기능을 악용해 공격자 기기를 사용자의 계정에 연결함
    • 패키지 내에 AES로 암호화된 하드코드 페어링 코드가 포함되어 있음
    • 사용자가 인증할 때 공격자 기기도 동시에 연결되어 지속적 계정 접근 권한을 획득함
  • 공격자는 메시지 열람, 발신, 미디어 다운로드, 연락처 접근 등 전체 계정 제어 가능
  • npm 패키지를 삭제해도 공격자 기기는 여전히 연결 상태로 남으며, WhatsApp 설정에서 수동으로 모든 기기 연결 해제를 해야만 차단 가능함

분석 회피 기법

  • 코드에는 27개의 무한 루프 트랩이 포함되어 있어 디버깅 도구 탐지 시 실행이 중단됨
    • 디버거, 프로세스 인자, 샌드박스 환경 등을 감지해 동적 분석 방해
    • 악성 코드 구간에 주석이 달려 있으며, 체계적인 개발 관리 흔적이 존재함

결론 및 보안 시사점

  • 공급망 공격의 정교화가 진행 중이며, 정상 작동하는 코드 형태로 위장된 사례가 증가함
  • 정적 분석 및 평판 기반 검증만으로는 탐지가 어렵고, 실행 중 행위 분석(behavioral analysis) 이 필요함
  • Lotusbail 사례는 “코드가 작동한다는 이유로 안전하다고 믿는” 보안 공백을 악용한 사례로, 런타임 행위 감시 시스템 구축의 중요성을 보여줌
  • Koi Security 연구팀은 이러한 런타임 기반 탐지 기술을 통해 기존 검증 절차를 우회하는 위협을 식별함
Hacker News 의견들
  • 악성코드 사건이 생길 때마다 보안팀이 데이터를 과도하게 잠그는 방향으로 가는 게 답답함
    WhatsApp 메시지가 유출된 게 계기였지만, 결국 다른 걸 훔쳤을 것임
    앱을 특정 서명만 읽을 수 있게 막으면, 정당한 백업이나 데이터 접근도 불가능해짐
    보안이 강화된 건 좋지만, 모든 걸 잠그는 식의 과잉 방어는 또 다른 문제라고 생각함

    • 동의함. 참고로 이 패키지는 공식 WhatsApp API의 래퍼가 아니라, 리버스 엔지니어링된 WhatsApp Web 클라이언트
      사용자는 WhatsApp 계정에 다른 클라이언트를 연결하듯 접근하고, 그 결과 전체 데이터 접근이 가능해짐
      WhatsApp이 제대로 된 공식 API를 제공했다면 이런 일이 줄었을 것임
      관련 문서: Baileys Wiki
    • OS가 앱 간 데이터 접근을 중재하고, 사용자에게 명시적으로 권한 요청을 해야 한다고 생각함
    • WhatsApp이 이런 제한을 두는 이유는 보안이 아니라 경쟁 제한 때문이라고 봄
    • 앱을 잠그는 건 결국 기업이 더 많은 통제권과 수익을 얻기 위한 수단임
      예전엔 악성코드가 많았지만, 그만큼 자유와 상호운용성도 더 컸음
    • 이 상황을 잘 풍자한 xkcd 만화가 있음
  • 이런 공격은 이제 예상 가능한 결과라고 봄
    NPM 같은 패키지 매니저는 빌드 직전에 의존성을 가져오는 구조라 근본적으로 취약
    버전 관리 시스템을 우회하면서도, 수많은 의존성을 검증 없이 받아들이는 문화가 문제임

    • 점점 깨닫는 중인데, 우리 개발자들은 보안에 정말 약함
      NPM뿐 아니라 Cargo, Docker, CI/CD 등 모든 생태계가 비슷한 문제를 가짐
      “이름으로 설치하고 끝”인 구조라 신뢰 기반이 너무 큼
      해결책이 마땅치 않음 — 협업을 포기할 수도 없고, 그렇다고 완전한 보안도 불가능함
      결국 괴물은 이미 집 안에 있음
    • 동의하지만, 이건 패키지 매니저만의 문제가 아님
      git URL을 직접 지정해도 결과는 같을 것임
      결국 의존성 관리 자체의 구조적 문제
    • 플랫폼마다 패키지 매니저가 너무 많음
      언어에 구애받지 않는 표준화된 패키지 매니저가 필요하다고 느낌
      서명 검증, 출처 보장, API 표준화 같은 기능이 필수적임
    • apt나 rpm 같은 시스템 패키지 매니저도 완벽하지 않음
      xz 사건처럼 감염된 패키지가 그대로 배포되기도 함
      게다가 시스템 패키지 매니저는 최신 버전 지원이 느려서 개발에 부적합함
      결국 npm, cargo, pip 같은 도구가 필요한 이유임
    • 이건 의존성이 감염된 게 아니라, 처음부터 악성 패키지였음
      패키지 매니저의 문제가 아니라, 애초에 신뢰할 수 없는 코드였음
  • 악성코드 작성자가 함수 이름을 exfiltrateCredentials처럼 노골적으로 쓴 게 웃김
    디버거 탐지까지 넣어놓고 정작 코드 난독화는 안 한 게 아이러니함

    • 실제로는 코드가 난독화되어 있었고, 작성자가 시연용으로 복원한 버전을 공개한 것임
    • 27개의 디버깅 트랩을 테스트하려면 테스트 커버리지가 꽤 필요했을 듯
      악성코드 테스트도 이제는 개발의 한 형태가 된 시대임
  • “개발자가 아무 생각 없이 설치하는 의존성”이라는 말이 섬뜩함

    • 대부분의 개발자는 npm install을 그냥 실행함
      보안 정책이 엄격한 조직이 아니라면 현실적으로 막기 어려움
      결국 해결책은 npm을 덜 쓰는 것뿐일지도 모름
    • Docker 이미지도 마찬가지임
      태그 기반으로 지정하면 언제든 공급망 공격에 노출됨
      업계는 생각보다 훨씬 많은 맹목적 신뢰 위에 돌아감
      자동 배포 시스템은 “두 번 생각할” 여유조차 없음
    • 무섭지만, 대부분의 개발자에게 사실인 현실
    • 약간의 과장도 섞여 있다고 봄
  • JavaScript에도 Apache Commons 같은 신뢰할 만한 대형 라이브러리가 있으면 좋겠음
    Apache Commons 소개

    • 하지만 아무리 큰 라이브러리라도 WhatsApp API는 포함되지 않을 것임
  • lotusbail 패키지는 WhatsApp Web API를 사칭한 악성 npm 패키지임
    6개월간 배포되었고, 자격 증명 탈취·메시지 가로채기·백도어 설치 등 다양한 공격을 수행함

  • JS 생태계에 의존하는 개발자는 현실적으로 위험 완화 전략이 필요함
    Docker나 VM을 활용하는 방법이 언급됨

    • 이전 직장에서 DevOps와 보안을 맡았음
      모든 개발 환경을 컨테이너화하고, 의존성을 고정 버전으로 잠금
      글로벌 설치 금지, 자동 업데이트 금지, 수동 검증 필수
      민감한 프로젝트는 전용 워크스테이션을 주기적으로 초기화함
      귀찮지만 그게 현실적인 보안임
      아니면 JS 생태계를 떠나는 것도 방법임
    • 하지만 이번 사례는 사용자가 의도적으로 설치한 패키지라 이런 조치로 막기 어려움
      OS나 Docker 수준에서 네트워크 연결 허용 여부를 확인할 수 있어야 함
    • 나는 Incus OS를 써서 프로젝트마다 새 컨테이너를 띄워 개발함
      커널을 공유하긴 하지만 JS 생태계의 공격을 막기엔 충분함
      컨테이너 탈출 공격이 npm에 나오면 그때 VM으로 옮길 예정임
      처음엔 과한 보안이라 생각했지만, 지금은 속도도 빠르고 안정적
    • 이런 패키지를 배포하면, 위험은 개발자뿐 아니라 모든 사용자에게 전파
    • 일부 회사는 npm 패키지가 몇 개월 이상 된 것만 허용
      그 사이에 악성 여부가 드러나기 때문임
  • 이 패키지는 처음부터 보안 실패였음
    공식 API가 아닌 클라이언트 인증 재구현을 사용했고, 사용자 비밀키를 제3자가 처리함
    사용자도 주의했어야 하지만, 완전히 탓하기는 어려움

    • 사실 WhatsApp에는 공개 API가 없음
      “WhatsApp Business Platform”에 등록해야만 API 접근이 가능함
      진짜 API가 있었다면 이런 일은 없었을 것임
    • 공식 API가 기능이 부족하면 재구현 자체는 문제 아님
      다만 인증 시 비밀키를 제3자에게 넘기는 건 위험함
      보통은 자신의 계정을 자동화하려고 이런 패키지를 설치함
  • 요즘 LLM이 생성한 블로그 글이 넘쳐남
    품질은 낮지만 비용이 0이라, 마케터 입장에선 효율적임
    전통적인 글쓰기는 이제 레거시가 되어버림

    • 그런데 이 댓글조차 LLM이 쓴 것처럼 느껴져서 웃김
  • 공급망 공격이 늘고 있는 것 같음. 개발자는 어떻게 대응해야 할까?

    • 완화하려면 랜덤 패키지 사용을 중단하고, 근본적으로는 npm 같은 생태계를 벗어나야 함
    • 서버 URL이 난독화·암호화된 패키지는 경고 신호임
      자동 스캔으로 이런 패턴을 탐지하고 검증 절차를 강화해야 함
    • 1999년처럼 의존성을 직접 검토하고 벤더링해야 함
    • 요즘은 의존성이 너무 많고, 아무도 코드를 안 봄
      컨테이너화, 의존성 잠금, 보안 스캔, 지연 업데이트가 필수임
      npm 글로벌 설치는 최악의 선택임
    • 어쩔 수 없이 실행해야 한다면, 최대한 격리된 환경에서 돌려야 함
      rootless podman 같은 컨테이너나 VM을 활용해 위험을 최소화해야 함