
🧙♂️ 스크립트 잭킹에 취약한 Electron 애플리케이션을 위한 Node.js 명령 및 제어
Loki는 취약한 Electron 앱을 스크립트 잭(script-jack)하도록 설계된 Node.js 기반 1단계 C2(명령 및 제어) 프레임워크입니다 MITRE ATT&CK T1218.015. 레드 팀 운영을 위해 개발된 Loki는 신뢰할 수 있는 서명된 Electron 앱을 악용하여 보안 소프트웨어를 우회하고 애플리케이션 제어를 우회할 수 있게 해줍니다.
스크립트 잭킹은 런타임에 로드되는 JavaScript 파일을 임의의 Node.js 코드로 수정하여 Electron 앱의 실행 흐름을 가로챕니다. 이 기술은 다음 용도로 활용될 수 있습니다:
여러 도구가 이미 스크립트 잭킹을 활용해 다른 프로세스로 실행을 연결하는 방법을 다루고 있지만, Loki는 서명된 Electron 앱의 코드 서명을 무효화하지 않으면서 백도어링과 할로우잉을 지원하는 최초의 도구입니다.
Loki가 작동하는 방식에 대한 자세한 내용은 다음 블로그 게시물을 확인하세요:

| 이름 | 기여 |
|---|---|
| Bobby Cooke | 제작자 및 관리자 |
| Dylan Tran | 제작자 |
| Ellis Springe | 알파 테스터 |
| Shawn Jones | 어셈블리 실행 코드 |
| Trusted Sec | COFFLoader 코드 |
| Simon Exley | 영상 제작자 |
| Clinton Elves | 영상 제작자 |
| John Hammond | 영상 제작자 |
John Hammond의 Loki C2로 Cursor AI를 백도어하는 영상을 확인하세요! 🎩
Simon Exley & Clinton Elves의 Loki C2 시작하기 영상도 확인하세요! 🧙♂️
모든 에이전트 명령은 네이티브 Node.JS로 작성되어 추가 종속성이나 라이브러리 로드 이벤트가 필요하지 않습니다. 단, scexec 및 assembly 명령은 keytar.node와 assembly.node에 대한 라이브러리 로드를 수행합니다.
/ 경로를 허용하며, 경로에 \는 작동하지 않습니다.Set - 애플리케이션 제어 제외 경로에서 노드 로드set 명령을 사용하여 assembly.node 및 scexec.node의 로드 경로를 변경할 수 있습니다.ls, cat, cp, mv를 사용하면 애플리케이션 제어 규칙을 열거하여 제외 대상인 쓰기 가능한 디렉터리를 발견할 수 있습니다.set 명령으로 로드 경로를 제외 디렉터리로 변경하여 애플리케이션 제어를 우회할 수 있습니다.[04-04-2025 8:50AM MST] advsim$ help set
Set the Node load paths for assembly node and scexec nodes
set scexec_path C:/Users/user/AppData/ExcludedApp/scexec.node
set assembly_path C:/Users/user/AppData/ExcludedApp/assembly.node
[04-04-2025 8:51AM MST] advsim$ set scexec_path C:/Users/user/AppData/ExcludedApp/scexec.node
SCEXEC Node Load Path Set to : C:/Users/user/AppData/ExcludedApp/scexec.node
클라이언트 기능에 대한 자세한 내용은 여기를 클릭하세요
먼저 ASAR 보안 무결성 검사를 수행하지 않는 취약한 Electron 애플리케이션(예: Microsoft Teams)을 식별해야 합니다. 최신 애플리케이션에는 백도어링을 방지하는 무결성 검사가 있을 수 있습니다. 대상 앱의 이전 버전이 취약할 가능성이 더 높습니다.
Electron 앱을 백도어할 때는 에이전트를 컴파일할 필요가 없습니다. {ELECTRONAPP}/resources/app/의 내용을 Loki 에이전트 파일로 교체하기만 하면 됩니다.
cd로 이동합니다javascript-obfuscator 모듈 설치npm install --save-dev javascript-obfuscator
create_agent_payload.js 스크립트를 실행하여 스토리지 계정 정보로 Loki 페이로드를 생성합니다bobby$ node create_agent_payload.js
[+] Provide Azure storage account information:
- Enter Storage Account : 7f7584ty218ba5dba778.blob.core.windows.net
- Enter SAS Token : se=2025-05-28T23%3A14%3A48Z&sp=rwdlac&spr=https&sv=2022-11-02&ss=b&srt=sco&sig=5MXQzJ6FDZK8yYiBSgJ6FDZKgQzJMXBSgg6qE4ydrJ6FDZKSgg%3D
[+] Configuration:
- Storage Account : 7f7584ty218ba5dba778.blob.core.windows.net
- SAS Token : se=2025-05-28T23%3A14%3A48Z&sp=rwdlac&spr=https&sv=2022-11-02&ss=b&srt=sco&sig=5MXQzJ6FDZK8yYiBSgJ6FDZKgQzJMXBSgg6qE4ydrJ6FDZKSgg%3D
- Meta Container : mllyi2zjmafjm
[+] Updated /Users/bobby/apr2/LokiC2/config.js with storage configuration.
- Enter into the Loki Client UI
Loki Client > Configuration
[+] Modifying PE binaries to have new hashes...
- Payload assembly.node hash : e9d126407264821d3c2d324da0e2d1bc13cbc53e7c56340fe12b07f69b707f02
- Payload keytar.node hash : 292c14ffebd6cae3df99d9fbee525e29a5a704f076b82207eb3e650de45b075d
[+] Payload ready!
- Obfuscated payload in the ./app directory
./app/에 출력됩니다{ELECTRONAPP}/resources/ 디렉터리로 이동합니다./app/ 폴더를 {ELECTRONAPP}/resources/app/에 복사합니다Loki GUI 클라이언트를 실행합니다
메뉴바에서 Loki Client > Configuration을 클릭하여 설정 창을 엽니다
스토리지 계정 정보를 입력하고 Save를 클릭합니다

이제 에이전트가 대시보드에 표시됩니다
대시보드 테이블에서 에이전트를 클릭하여 에이전트 창을 엽니다
Loki가 제대로 작동하는지 테스트합니다
Loki를 사용하는 가장 간단한 방법은 {ELECTRONAPP}/resources/app/의 파일을 Loki 파일로 교체하는 것입니다. 이렇게 하면 앱이 할로우(hollow) 처리되어 정상적으로 작동하지 않게 됩니다 -- Loki가 그 기능을 대체합니다.
Electron 애플리케이션을 계속 실행하면서 백그라운드에서 Loki도 배포하려는 경우 희망은 아직 있습니다! John Hammond과 저는 실제 Electron 애플리케이션을 계속 실행하는 방법을 알아냈습니다. 이 저장소의 /loki/backdoor/init.js에 필요한 파일을 추가해 두었습니다.
현재 John Hammond가 취약하다고 발견한 Cursor에서 작동하도록 설정되어 있습니다.
이를 수행하려면 다음이 필요합니다:
package.json을 제외한 모든 Loki 파일을 cursor/resources/app/에 붙여넣습니다
package.json을 교체하지 마세요/loki/backdoor/init.js를 cursor/resources/app/에 복사합니다cursor/resources/app/package.json의 내용을 다음과 같이 수정합니다:
"main":"init.js",로 설정"type":"module", 삭제"private":true, 삭제Cursor.exe는 클릭/실행 시 init.js를 로드합니다init.js는 package.json을 읽습니다init.js는 "main":"init.js",을 "main":"main.js",로 변경합니다
main.js는 Loki입니다init.js는 Loki를 가리키는 새 Cursor.exe를 생성하고 disown합니다init.js는 package.json을 다시 읽습니다init.js는 "main":"main.js",을 로 변경합니다
이렇게 하면 앱이 지속적으로 백도어된 상태로 정상 작동합니다. Cursor 앱이 종료되어도 Loki는 백그라운드에서 계속 실행됩니다.
향후 이 작업을 자동화하는 스크립트를 만들겠습니다.
에이전트 및 클라이언트 빌드를 위한 컴파일 지침입니다. 이 지침은 Windows, Linux, macOS를 포함한 여러 플랫폼을 다룹니다. 클라이언트는 대상 플랫폼 및 아키텍처에서 컴파일하는 것이 좋습니다.
Electron 애플리케이션을 백도어하는 경우 에이전트를 컴파일할 필요가 없습니다.
에이전트를 컴파일하여 운영에 사용하는 것은 권장하지 않습니다. 에이전트 컴파일 지침은 개발용입니다.
~/Downloads/Teams/Teams.exe)에서 Electron 앱 실행*.blob.core.windows.net으로 비콘(beacon)을 보내는 Electron 앱netstat.exe 또는 whoami.exe와 같은 자식 프로세스를 생성하는 Electron 앱package.json의 이름과 동일한 디렉터리가 ~/AppData/Roaming/{NAME}에 생성됩니다.%LOCALAPPDATA%\Microsoft\Teams\current\app 디렉터리 생성%LOCALAPPDATA%\Microsoft\Teams\current\app.asar 파일이 Teams 설치 프로그램/업데이터가 아닌 다른 항목에 의해 생성/수정됨이 프로젝트는 Business Source License 1.1에 따라 라이선스가 부여됩니다. 비상업적 사용은 라이선스 조건에 따라 허용됩니다. 상업적 사용은 저자의 명시적 허가가 필요합니다. 2030년 4월 3일에 이 라이선스는 Apache 2.0으로 전환됩니다. 전체 내용은 LICENSE를 참조하세요.
| 명령 | 설명 |
|---|
help | 도움말 표시. 사용법: help 또는 help scan |
pwd | 현재 작업 디렉터리 출력 |
ls | 파일 및 디렉터리 목록 |
cat | 파일 내용 표시 |
env | 프로세스 환경 변수 표시 |
spawn | 자식 프로세스 생성 |
drives | 드라이브 목록 |
mv | 파일을 새 대상으로 이동 |
sleep | 지터(jitter)와 함께 초 단위로 대기 |
cp | 원본 파일을 대상으로 복사 |
exit-all | 에이전트 종료, 에이전트는 더 이상 콜백하지 않음 |
load | 디스크에서 프로세스로 node PE 파일 로드 |
scexec | 셸코드 실행 |
assembly | .NET 어셈블리 실행 및 명령 출력 가져오기 |
upload | 로컬 운영자 박스에서 원격 에이전트 박스로 파일 업로드 |
download | 원격 에이전트 박스에서 로컬 운영자 박스로 파일 다운로드 |
scan | 선택한 포트로 CIDR 범위에 대해 TCP 네트워크 스캔 수행 |
dns | DNS 조회. 시스템 DNS 구성 활용 |
set | assembly node 및 scexec node의 Node 로드 경로 설정 |
bof | COFF 파일 실행 및 출력 반환 |
"main":"./out/main.js",./out/main.js"은 실제 Cursor 애플리케이션입니다init.js는 실제 Cursor를 가리키는 새 Cursor.exe를 생성하고 disown합니다init.js가 종료를 감지합니다init.js는 세 번째로 package.json을 읽습니다init.js는 "main":"./out/main.js",을 "main":"init.js",로 변경합니다