Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
box-js — JavaScript 악성코드 연구를 위한 도구입니다. | Kitploit
도구/GitHubGitHub/capacitorset/box-js
Indicator of Compromise (IOC) ManagementDynamic Analysis (Sandboxing)ForensicsMalware Analysis
GitHubcapacitorset/box-js

box-js

JavaScript 악성코드 연구를 위한 도구입니다.

저장소 보기
672881개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

box.js

npm Build Status paypal

악성 JavaScript를 분석하는 유틸리티입니다.

설치

npm에서 box-js를 간단히 설치합니다:

root@kitploit:~
npm install box-js --global

box-js는 또한 다음 형태로 제공됩니다:

  • Cuckoo 모듈로 (integrations 디렉토리 및 Nwinternights/Cuckoo_Boxjs 참조);
  • Dockerfile로 (integrations/README.md 참조);
  • 보안 전문가용 배포판의 패키지로 (REMnux, BlackArch);
  • 오픈 소스 애플리케이션의 일부로 (Intel Owl);
  • 상용 타사 서비스의 일부로 (any.run).

사용법

sample.js라는 샘플이 있다고 가정해 봅시다. 분석하려면 다음을 실행하면 됩니다:

root@kitploit:~
box-js sample.js

페이로드를 다운로드하려는 경우가 많을 것입니다. 다운로드를 활성화하려면 --download 플래그를 사용하세요. 그렇지 않으면 엔진이 404 오류를 시뮬레이션하여 스크립트가 배포 사이트가 다운되었다고 속아서 대체 사이트에 접촉하게 됩니다.

Box.js는 Windows JScript 환경을 에뮬레이션하고, 에뮬레이션 결과 요약을 콘솔에 출력하며, sample.js.results라는 폴더를 생성합니다(이미 존재하는 경우 sample.js.1.results 등으로 생성됩니다). 이 폴더에는 다음이 포함됩니다:

  • analysis.log - 화면에 출력된 분석 로그;
  • UUID로 식별되는 일련의 파일들;
  • snippets.json - 샘플이 실행한 코드 조각 목록(JavaScript, 셸 명령 등);
  • urls.json - 접촉한 URL 목록;
  • active_urls.json - 활성 악성코드를 드롭하는 것으로 보이는 URL 목록;
  • resources.json - ADODB 스트림(즉, 스크립트가 디스크에 쓴 파일)과 파일 유형 및 해시;
  • IOC.json - IOC(침해 지표)로 식별된 동작 목록. 레지스트리 접근, 기록된 파일, HTTP 요청 등이 포함됩니다.

직접 분석하거나 Malwr, VirusTotal 또는 Cuckoo 샌드박스에 자동으로 제출할 수 있습니다. 자세한 내용은 box-export --help를 실행하세요.

추가적인 격리를 위해 임시 Docker 컨테이너에서 분석을 실행하는 것이 좋습니다. 자세한 내용은 integrations/README.md를 참조하세요.

분석을 자동화하려면 반환 코드를 사용할 수 있습니다. 반환 코드는 integrations/README.md에 문서화되어 있으며, 다양한 오류 유형을 구분하는 데 도움이 됩니다.

'document' 객체 또는 다른 객체/함수가 없어 분석 실패 시

Git에서 box-js 저장소를 복제하면 boilerplate.js 파일이 포함되어 있습니다. 이 파일은 document와 같은 일반적인 브라우저 객체의 스텁 버전을 정의합니다. --prepended-code=DIR/boilerplate.js 옵션을 사용하여 분석을 다시 실행해 보세요. 여기서 DIR은 복제된 box-js 저장소의 디렉토리입니다. 또는 --prepended-code=default를 사용할 수도 있습니다. --prepended-code 옵션은 box-js가 주어진 파일의 JavaScript를 분석 대상 샘플 앞에 추가하도록 지시합니다.

boilerplate.js를 복사하여 필요에 따라 자신만의 스텁 클래스, 객체 등을 추가할 수 있습니다. --prepended-code=show-default 명령줄 옵션을 사용하면 기본 box-js boilerplate.js 파일의 전체 경로를 출력합니다.

배치 사용

box.js는 일반적으로 단일 파일에 사용되지만, 배치 분석도 실행할 수 있습니다. 분석할 파일 또는 폴더 목록을 전달하면 됩니다:

root@kitploit:~
box-js sample1.js sample2.js /var/data/mySamples ...

기본적으로 box.js는 샘플을 병렬로 처리하며, 코어당 하나의 분석을 실행합니다. --threads 값을 지정하여 다른 설정을 사용할 수 있습니다. 특히 0으로 설정하면 제한이 제거되어 box-js가 가능한 많은 분석 스레드를 생성하여 매우 빠른 분석이 가능하지만 시스템에 과부하가 걸릴 수 있습니다(분석은 일반적으로 CPU 바운드이며 RAM 바운드가 아닙니다).

--loglevel=warn을 사용하면 분석 관련 메시지를 숨기고 진행 정보만 표시할 수 있습니다.

분석이 완료된 후에는 다음과 같이 활성 URL을 추출할 수 있습니다:

root@kitploit:~
cat ./*.results/active_urls.json | sort | uniq

플래그

root@kitploit:~
NAME                      설명                                                                           
-h, --help                 도움말 텍스트를 표시하고 종료                                                     
-v, --version              패키지 버전을 표시하고 종료                                                        
--license                  라이선스를 표시하고 종료                                                           
--debug                    에뮬레이션 오류 발생 시 죽음(일괄 모드에서도), 종료 코드를 전달                        
--loglevel                 로깅 수준 (debug, verbose, info, warning, error - 기본값 "info")                  
--threads                  일괄 모드에서 동시에 실행할 분석 수 (0 = 무제한, 기본값: CPU 코어 수)                    
--download                 실제로 페이로드를 다운로드                                                         
--encoding                 입력 샘플의 인코딩 (기본값: 자동 감지)                                              
--timeout                  스크립트가 이 시간(초) 후에 타임아웃됨 (기본값 10)                                    
--output-dir               결과 파일 및 폴더를 쓸 디스크 위치 (기본값: 현재 디렉토리)                              
--preprocess               원본 소스 코드를 전처리 (리버스 엔지니어링을 용이하게 하지만 몇 초 소요)                  
--unsafe-preprocess        더 공격적인 전처리. 종종 더 나은 코드를 생성하지만 일부 경계 케이스(예: 프로토타입 재정의)에서 
                           깨질 수 있음                                                                        
--prepended-code           분석 중인 JS 파일 앞에 추가할 코드가 포함된 입력 파일 또는 디렉토리. 디렉토리인 경우 해당 
                           디렉토리의 모든 파일 내용을 앞에 추가. 'default'인 경우 box-js에 포함된 기본 
                           boilerplate.js 사용. 'show-default'인 경우 boilerplate.js의 경로만 출력하고 종료 
                           (기본 boilerplate 코드를 복사하여 수정하려는 경우 유용).                              
--fake-script-engine       WScript.FullName 및 WScript.Name에 보고할 스크립트 엔진 (예: 'cscript.exe', 
                           'wscript.exe' 또는 'node'). 기본값: wscript.exe.                                     
--fake-cl-args             가짜 스크립트 명령줄 인수. 문자열에서 쉼표로 구분해야 함.                                   
--fake-sample-name         분석 중인 샘플에 사용할 가짜 파일 이름. 전체 경로 또는 파일 이름만 가능. 경로에 '\'가 
                           있으면 이 명령줄 인수 값에서 '\\'로 이스케이프 (예: --fake-sample-name=C:\\foo\\bar.js). 
--fake-language            Win32_OperatingSystem.OSLanguage에 반환할 언어 코드 지정. 지원되는 값: 'spanish', 
                           'english', 'portuguese'.                                                             
--fake-domain              WScript.Network.UserDomain에 반환할 사용자 도메인 지정.
--fake-download            HTTP 요청이 작동하는 것처럼 위장하고 가짜 페이로드 반환                                
--no-kill                  런타임 오류 발생 시 애플리케이션을 종료하지 않음                                         
--no-echo                  스크립트가 데이터를 출력할 때 콘솔에 출력하지 않음                                      
--no-rewrite               `@cc_on` 지원 외에 소스 코드를 전혀 다시 작성하지 않음                                 
--no-catch-rewrite         try..catch 절을 다시 작성하여 예외를 전역 범위로 만들지 않음                            
--no-cc_on-rewrite         `/*@cc_on <...>@*/`를 `<...>`으로 다시 작성하지 않음                                    
--no-eval-rewrite          `eval`의 인수가 다시 작성되도록 `eval`을 다시 작성하지 않음                              
--no-file-exists           Scripting.FileSystemObject.FileExists(x)에 대해 `false` 반환                            
--limit-file-checks        많은 검사가 수행되는 경우 폴더/파일 존재 확인의 기본값 전환 (무한 파일 검사 루프 차단 시도). 
--no-folder-exists         Scripting.FileSystemObject.FolderExists(x)에 대해 `false` 반환                          
--function-rewrite         eval 호출을 잡기 위해 함수 호출 다시 작성                                              
--no-rewrite-prototype     `function A.prototype.B()`와 같은 표현식을 `A.prototype.B = function()`으로 다시 작성하지 않음 
--no-hoist-prototype       `function A.prototype.B()`와 같은 표현식을 호이스트하지 않음 (no-rewrite-prototype에 의해 암시됨) 
--no-shell-error           `WScriptShell.Run` 실행 시 가짜 오류를 발생시키지 않음 (기본값: 가짜 오류를 발생시켜 
                           배포 사이트가 다운된 것처럼 위장하여 스크립트가 모든 사이트를 폴링하도록 함)                  
--no-typeof-rewrite        `typeof`를 다시 작성하지 않음 (예: `typeof ActiveXObject`는 JScript 표준에서 
                           'unknown'을 반환해야 하며 'object'가 아님)                                              
--proxy                    [실험적] 다운로드에 지정된 프록시 사용. --download 플래그가 없으면 관련 없음.               
--windows-xp               Windows XP 에뮬레이션 (환경 변수 값에 영향)                                              
--dangerous-vm             `vm2` 대신 `vm` 모듈 사용. 이 샌드박스는 깨질 수 있으므로 **절대 사용하지 마세요**. 
                           올바른 스택 트레이스를 제공하여 디버깅에 도움.                                            
--rewrite-loops            일부 유형의 루프를 다시 작성하여 분석 속도 향상                                           
--throttle-writes          많은 양의 데이터를 쓰는 파일 쓰기의 보고 및 데이터 추적 제한                               
--throttle-commands        동일한 명령이 매우 많이 실행된 경우 분석 중지                                           
--extract-conditional-code JScript 조건부 주석(/*@if(...)에서 분석할 실제 코드 추출                                
--loose-script-name        == 검사를 다시 작성하여 현재 스크립트 이름과 하드코딩된 스크립트 이름의 비교가 항상 
                           true를 반환하도록 함.                                                                  
--real-script-name         현재 분석 중인 스크립트의 실제 파일 이름을 반환(가짜 이름 대신).                          
--activex-as-ioc           모든 ActiveX 호출을 IOC로 기록하고 JS 소스에서 호출이 난독화되었는지 확인 시도.            
--ignore-wscript-quit      WSCript.Quit() 호출을 무시하고 계속 실행.                                            
--ignore-rewrite-errors    샘플 다시 쓰기 실패 시 원본 샘플 분석.                                                 

출력 분석

콘솔 출력

첫 번째 정보 출처는 콘솔 출력입니다. 성공적인 분석에서는 일반적으로 다음과 같은 내용이 출력됩니다:

root@kitploit:~
Using a 10 seconds timeout, pass --timeout to specify another timeout in seconds
Analyzing sample.js
Header set for http://foo.bar/baz: User-Agent Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Emulating a GET request to http://foo.bar/baz
Downloaded 301054 bytes.
Saved sample.js.results/a0af1253-597c-4eed-9e8f-5b633ff5f66a (301054 bytes)
sample.js.results/a0af1253-597c-4eed-9e8f-5b633ff5f66a has been detected as data.
Saved sample.js.results/f8df7228-7e0a-4241-9dae-c4e1664dc5d8 (303128 bytes)
sample.js.results/f8df7228-7e0a-4241-9dae-c4e1664dc5d8 has been detected as PE32 executable (GUI) Intel 80386, for MS Windows.
http://foo.bar/baz is an active URL.
Executing sample.js.results/d241e130-346f-4c0c-a698-f925dbd68f0c in the WScript shell
Header set for http://somethingelse.com/: User-Agent Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Emulating a GET request to http://somethingelse.com/
...

이 경우, http://foo.bar/baz에서 파일을 다운로드하는 드로퍼를 볼 수 있습니다. HTTP 헤더 User-Agent를 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)로 설정하고 있습니다. 그런 다음 파일을 디코딩하여 결과를 디스크에 기록합니다(PE32 실행 파일). 마지막으로 Windows 셸에서 명령을 실행합니다.

  • sample.js.results/a0af1253-597c-4eed-9e8f-5b633ff5f66a에는 http://foo.bar/baz에서 다운로드한 페이로드가 포함됩니다;
  • sample.js.results/f8df7228-7e0a-4241-9dae-c4e1664dc5d8에는 실제 페이로드(PE 실행 파일)가 포함됩니다;
  • sample.js.results/d241e130-346f-4c0c-a698-f925dbd68f0c에는 Windows 셸에서 실행된 명령이 포함됩니다.

JSON 로그

모든 HTTP 요청은 터미널에 출력될 뿐만 아니라 urls.json에도 기록됩니다. 중복 URL은 삽입되지 않습니다(즉, 동일한 URL을 두 번 요청하면 urls.json에 한 줄만 표시됨).

active_urls.json에는 최종적으로 실행 가능한 페이로드로 이어진 URL 목록이 포함됩니다. 이 파일은 배포 사이트를 차단하려는 경우 가장 흥미로운 파일입니다.

snippets.json에는 box-js가 만난 모든 코드 조각(JavaScript, cmd.exe 명령 또는 PowerShell 스크립트)이 포함됩니다.

resources.json에는 샘플이 디스크에 기록한 모든 파일이 포함됩니다. 예를 들어, 애플리케이션이 Hello world!를 $PATH/foo.txt에 저장하려는 경우 resources.json의 내용은 다음과 같습니다:

root@kitploit:~
{
	"9a24...": {
		"path": "(path)\\foo.txt",
		"type": "ASCII text, with no line terminators",
		"md5": "86fb269d190d2c85f6e0468ceca42a20",
		"sha1": "d3486ae9136e7856bc42212385ea797094475802",
		"sha256": "c0535e4be2b79ffd93291305436bf889314e4a3faec05ecffcbb7df31ad9e51a"
	}
}

resources.json 파일도 중요합니다. 실행 가능한 리소스(예: "type": "PE32 executable (GUI) Intel 80386, for MS Windows")가 있는지 주의하세요.

패칭

일부 악성 스크립트는 new Date().getFullYear() 대신 new Date().getYear()를 사용하는 것으로 관찰되었습니다. 샘플이 의심스러운 동작을 보이지 않으면 Date 검사를 주의하세요.


.JSE 파일을 발견한 경우, 디코더를 컴파일하여 다음과 같이 실행하세요:

root@kitploit:~
cc decoder.c -o decoder
./decoder foo.jse bar.js
node run bar.js

확장

가끔 지원되지 않는 컴포넌트를 만날 수 있습니다. 이 경우 GitHub에 이슈를 등록하거나 JavaScript를 알고 있다면 직접 컴포넌트를 에뮬레이션할 수 있습니다.

오류는 일반적으로 다음과 같이 표시됩니다(줄 번호는 다를 수 있음):

root@kitploit:~
1 Jan 00:00:00 - Unknown ActiveXObject WinHttp.WinHttpRequest.5.1
Trace
    at kill (/home/CapacitorSet/box-js/run.js:24:10)
    at Proxy.ActiveXObject (/home/CapacitorSet/box-js/run.js:75:4)
    at evalmachine.<anonymous>:1:6471
    at ContextifyScript.Script.runInNewContext (vm.js:18:15)
    at ...

예외가 Proxy.ActiveXObject에서 발생했음을 알 수 있습니다. 이 함수는 다음과 같습니다:

root@kitploit:~
function ActiveXObject(name) {
	name = name.toLowerCase();
	/* ... */
	switch (name) {
		case "wscript.shell":
			return require("./emulator/WScriptShell");
		/* ... */
		default:
			kill(`Unknown ActiveXObject ${name}`);
			break;
	}
}

case "winhttp.winhttprequest.5.1"(소문자 주의!)을 추가하고, ES6 Proxy 객체(예: ProxiedWinHttpRequest)를 반환하도록 하세요. 이는 악성 샘플이 요청하는 즉시 구현되지 않은 기능을 포착하는 데 사용됩니다:

root@kitploit:~
/* emulator/WinHttpRequest.exe */
const lib = require("../lib");

module.exports = function ProxiedWinHttpRequest() {
	return new Proxy(new WinHttpRequest(), {
		get: function(target, name, receiver) {
			switch (name) {
				/* 여기에 case 문으로 "특별한" 트랩을 추가 */
				default:
					if (name in target) return target[name];
					else lib.kill(`WinHttpRequest.${name} not implemented!`)
			}
		}
	})
}

function WinHttpRequest() {
	
}

분석을 다시 실행하세요. 정확히 무엇이 구현되지 않았는지 알려주며 다시 실패합니다:

root@kitploit:~
1 Jan 00:00:00 - WinHttpRequest.open not implemented!
Trace
    at kill (/home/CapacitorSet/box-js/run.js:24:10)
    at Object.ProxiedWinHttpRequest.Proxy.get (/home/CapacitorSet/box-js/run.js:89:7)

필요에 따라 WinHttpRequest.open을 에뮬레이션하세요:

root@kitploit:~
function WinHttpRequest() {
	this.open = function(method, url) {
		URLLogger(method, url);
		this.url = url;
	}
}

그리고 코드가 오류 없이 에뮬레이션될 때까지 반복하세요.

기여자

@CapacitorSet: 원 개발자

@kirk-sayre-work: 관리자

@daviesjamie:

  • npm 패키징
  • 명령줄 도움말
  • --output-directory
  • 버그 수정

@ALange:

  • 비 UTF-8 인코딩 지원
  • 버그 보고

@alexlamsl, @kzc

  • box-js에 UglifyJS 통합에 대한 조언
  • 난독화 해제에 사용되는 UglifyJS 기능 개선

@psrok:

  • 버그 수정

@gaelmuller:

  • 버그 수정
도구 다운로드