
JAW: 클라이언트 측 JavaScript를 위한 그래프 기반 보안 분석 프레임워크
J A W
웹사이트 | 문서 | 설치 | 크롤러 | 빠른 시작 Docker (예제)
esprima 파서와 EsTree SpiderMonkey Spec을 기반으로 한 JavaScript용 속성 그래프(property graph)의 오픈소스 프로토타입 구현입니다. JAW는 웹 애플리케이션의 클라이언트 측과 JavaScript 기반 프로그램을 분석하는 데 사용할 수 있습니다.
이 프로젝트는 GNU AFFERO GENERAL PUBLIC LICENSE V3.0에 따라 라이선스가 부여됩니다. 자세한 내용은 여기를 참조하세요.
JAW는 https://soheilkhodayari.github.io/JAW/에서 깃허브 페이지 웹사이트를 운영하고 있습니다.
릴리스 노트:
JAW-V2 브랜치 참조.JAW-V1 브랜치 참조.JAW의 아키텍처는 아래와 같습니다.
JAW는 두 가지 방법으로 사용할 수 있습니다.
임의의 JavaScript 분석: 프로그램의 파일 시스템 경로를 지정하여 모든 JavaScript 프로그램을 모델링하고 분석하는 데 JAW를 활용합니다.
웹 애플리케이션 분석: 단일 시드 URL을 제공하여 웹 애플리케이션을 분석합니다.
수집된 웹 리소스를 사용하여 HPG(Hybrid Program Graph)를 생성하고, 이를 Neo4j 데이터베이스로 가져옵니다.
선택적으로 HPG 구축 모듈에 의미론적 유형과 사용자 정의 JavaScript 언어 토큰의 매핑을 제공하여 JavaScript 함수를 목적(예: HTTP 요청 함수)에 따라 분류할 수 있습니다.
구축된 Neo4j 그래프 데이터베이스를 다양한 분석에 사용할 수 있습니다. JAW는 데이터 흐름 분석, 제어 흐름 분석, 도달 가능성 분석 및 패턴 매칭을 위한 유틸리티 탐색을 제공합니다. 이러한 탐색을 사용하여 사용자 정의 보안 분석을 개발할 수 있습니다.
JAW는 또한 클라이언트 측 CSRF, DOM Clobbering 및 요청 하이재킹 취약점을 탐지하기 위한 내장 탐색을 포함합니다.
출력은 입력 파일과 동일한 폴더에 저장됩니다.
설치 스크립트는 다음 사전 요구 사항을 필요로 합니다.
npm 패키지 관리자 (node js)python 3.xpip 패키지 관리자그 후, 다음 명령을 통해 필요한 종속성을 설치합니다.
$ ./install.sh
자세한 설치 지침은 여기를 참조하세요.
백그라운드 화면에서 파이프라인 인스턴스를 실행할 수 있습니다:
$ python3 -m run_pipeline --conf=config.yaml
CLI는 다음 옵션을 제공합니다.
$ python3 -m run_pipeline -h
사용법: run_pipeline.py [-h] [--conf FILE] [--site SITE] [--list LIST] [--from FROM] [--to TO]
이 스크립트는 도구 파이프라인을 실행합니다.
선택적 인수:
-h, --help 이 도움말 메시지를 표시하고 종료합니다.
--conf FILE, -C FILE 파이프라인 구성 파일입니다. (기본값: config.yaml)
--site SITE, -S SITE 테스트할 웹사이트로, 구성 파일을 재정의합니다. (기본값: None)
--list LIST, -L LIST 테스트할 사이트 목록으로, 구성 파일을 재정의합니다. (기본값: None)
--from FROM, -F FROM 사이트 목록이 제공될 때 고려할 첫 번째 항목으로, 구성 파일을 재정의합니다. (기본값: -1)
--to TO, -T TO 사이트 목록이 제공될 때 고려할 마지막 항목으로, 구성 파일을 재정의합니다. (기본값: -1)
입력 구성: JAW는 입력으로 .yaml 구성 파일을 필요로 합니다. 예제는 config.yaml을 참조하세요.
힌트. 구성 파일은 각 취약점 클래스에 대해 활성화 또는 비활성화할 수 있는 다른 단계(예: 크롤링, 정적 분석 등)를 지정합니다. 이를 통해 도구 구성 요소를 개별적으로 또는 다른 순서로 실행할 수 있습니다(예: 먼저 모든 웹앱을 크롤링한 다음 보안 분석 수행).
속성 그래프를 구축하고 그 위에서 Cypher 쿼리를 실행하는 방법을 보여주는 빠른 예제를 실행하려면 다음을 수행하세요.
$ python3 -m analyses.example.example_analysis --input=$(pwd)/data/test_program/test.js
이 모듈은 테스트에 필요한 데이터(즉, JavaScript 코드 및 웹 페이지의 상태 값)를 수집합니다. 이미 파일 시스템에 테스트할 특정 JavaScript 파일이 있는 경우 이 단계를 건너뛸 수 있습니다.
JAW는 Selenium (JAW-v1), Puppeteer (JAW-v2, v3) 및 Playwright (JAW-v3)를 기반으로 하는 크롤러를 제공합니다. 최신 기능을 사용하려면 Puppeteer 또는 Playwright 기반 버전을 사용하는 것이 좋습니다.
이 웹 크롤러는 foxhound(계측된 Firefox 버전)를 사용하여 웹 페이지를 탐색하면서 동적 오염 추적을 수행합니다. 크롤러를 시작하려면:
$ cd crawler
$ node crawler-taint.js --seedurl=https://google.com --maxurls=100 --headless=true --foxhoundpath=<선택사항-foxhound-실행-파일-경로>
foxhoundpath는 기본적으로 crawler/foxhound/firefox 디렉토리로 설정되며, 이 디렉토리에는 firefox라는 바이너리가 포함되어 있습니다.
참고: 이 버전을 사용하려면 foxhound 빌드가 필요합니다. 우분투 빌드는 JAW-v3 릴리스에 포함되어 있습니다.
크롤러를 시작하려면:
$ cd crawler
$ node crawler.js --seedurl=https://google.com --maxurls=100 --browser=chrome --headless=true
자세한 내용은 여기를 참조하세요.
크롤러를 시작하려면:
$ cd crawler/hpg_crawler
$ vim docker-compose.yaml # 크롤링할 웹사이트를 여기에 설정하고 저장하세요.
$ docker-compose build
$ docker-compose up -d
자세한 내용은 hpg_crawler 문서 여기를 참조하세요.
주어진 JavaScript 파일(들)에 대한 HPG를 생성하려면:
$ node engine/cli.js --lang=js --graphid=graph1 --input=/in/file1.js --input=/in/file2.js --output=$(pwd)/data/out/ --mode=csv
선택적 인수:
--lang: 입력 프로그램의 언어
--graphid: 생성된 HPG의 식별자
--input: 입력 프로그램의 경로
--output: 출력 HPG의 경로, 반드시
--mode: 출력 형식을 결정합니다 (csv 또는 graphML)
HPG를 neo4j 그래프 데이터베이스(docker 인스턴스)로 가져오려면:
$ python3 -m hpg_neo4j.hpg_import --rpath=<csv-파일-폴더-경로> --id=<xyz> --nodes=<nodes.csv> --edges=<rels.csv>
$ python3 -m hpg_neo4j.hpg_import -h
사용법: hpg_import.py [-h] [--rpath P] [--id I] [--nodes N] [--edges E]
이 스크립트는 속성 그래프의 CSV를 neo4j docker 데이터베이스로 가져옵니다.
선택적 인수:
-h, --help 이 도움말 메시지를 표시하고 종료합니다.
--rpath P `data` 디렉토리 내 그래프 CSV 파일이 포함된 폴더의 상대 경로
--id I 그래프 또는 docker 컨테이너의 식별자
--nodes N 노드 csv 파일의 이름 (기본값: nodes.csv)
--edges E 관계 csv 파일의 이름 (기본값: rels.csv)
hpg_crawler의 출력에 대한 하이브리드 속성 그래프를 생성하고 로컬 neo4j 인스턴스로 가져오려면 다음을 수행할 수도 있습니다.
$ python3 -m engine.api <경로> --js=<program.js> --import=<bool> --hybrid=<bool> --reqs=<requests.out> --evts=<events.out> --cookies=<cookies.pkl> --html=<html_snapshot.html>
매개변수 설명:
<경로>: 분석할 프로그램 파일이 포함된 폴더의 절대 경로(engine/outputs 폴더 아래에 있어야 함).--js=<program.js>: 분석할 JavaScript 프로그램의 이름 (기본값: js_program.js).--import=<bool>: 생성된 속성 그래프를 활성 neo4j 데이터베이스로 가져올지 여부 (기본값: true).--hybrid=bool: 하이브리드 모드 활성화 여부 (기본값: false). 테스터가 JAW 크롤러가 수집한 HTML 스냅샷, 발생한 이벤트, HTTP 요청 및 쿠키 파일 중 하나라도 입력하여 속성 그래프를 보강하려는 경우를 의미합니다.--reqs=<requests.out>: 하이브리드 모드 전용, 관찰된 네트워크 요청 시퀀스가 포함된 파일의 이름, 제외하려면 문자열 false 전달 (기본값: request_logs_short.out).--evts=<events.out>: 하이브리드 모드 전용, 발생한 이벤트 시퀀스가 포함된 파일의 이름, 제외하려면 문자열 false 전달 (기본값: events.out).자세한 내용은 그래프 구축 API와 함께 제공되는 도움말 CLI를 사용할 수 있습니다.
$ python3 -m engine.api -h
구축된 HPG는 Cypher 또는 NeoModel ORM을 사용하여 쿼리할 수 있습니다.
쿼리는 analyses/<ANALYSIS_NAME>에 배치하고 실행해야 합니다.
NeoModel ORM을 사용하여 HPG를 쿼리할 수 있습니다. 쿼리를 작성하려면:
analyses/example 폴더의 example_query_orm.py를 참조하세요.$ python3 -m analyses.example.example_query_orm
자세한 내용은 여기를 참조하세요.
Cypher를 사용하여 사용자 정의 쿼리를 작성할 수 있습니다. 이를 위해:
analyses/example 폴더의 example_query_cypher.py를 참조하세요.$ python3 -m analyses.example.example_query_cypher
자세한 내용은 여기를 참조하세요.
이 섹션에서는 취약점 탐지를 위해 JAW를 구성 및 사용하는 방법과 출력을 해석하는 방법을 설명합니다. JAW에는 클라이언트 측 CSRF 및 DOM Clobbering 탐지를 위한 자체 포함 쿼리 등이 포함되어 있습니다.
1단계. 입력 config.yaml 파일에서 취약점 클래스에 대한 분석 구성 요소를 활성화합니다.
request_hijacking:
enabled: true
# [...]
open_redirect:
enabled: false
# [...]
domclobbering:
enabled: false
# [...]
cs_csrf:
enabled: false
# [...]
2단계. 다음 명령으로 파이프라인 인스턴스를 실행합니다.
$ python3 -m run_pipeline --conf=config.yaml
힌트. 다른 screen에서 여러 파이프라인 인스턴스를 실행할 수 있습니다.
$ screen -dmS s1 bash -c 'python3 -m run_pipeline --conf=conf1.yaml; exec sh'
$ screen -dmS s2 bash -c 'python3 -m run_pipeline --conf=conf2.yaml; exec sh'
$ # [...]
병렬 구성 파일을 자동으로 생성하려면 generate_config.py 스크립트를 사용할 수 있습니다.
출력은 입력 파일과 동일한 폴더에 sink.flows.out이라는 파일에 저장됩니다. 예를 들어 클라이언트 측 CSRF의 경우, 감지된 각 HTTP 요청에 대해 JAW는 요청을 구성하는 요소(즉, 프로그램 슬라이스)와 관련된 의미론적 유형 집합(일명 의미론적 태그 또는 레이블)을 표시하는 항목을 출력합니다. 예를 들어, 의미론적 유형 ['WIN.LOC']로 표시된 HTTP 요청은 window.location 주입 지점을 통해 위조될 수 있습니다. 그러나 ['NON-REACH']로 표시된 요청은 위조할 수 없습니다.
예제 출력 항목은 다음과 같습니다.
[*] Tags: ['WIN.LOC']
[*] NodeId: {'TopExpression': '86', 'CallExpression': '87', 'Argument': '94'}
[*] Location: 29
[*] Function: ajax
[*] Template: ajaxloc + "/bearer1234/"
[*] Top Expression: $.ajax({ xhrFields: { withCredentials: "true" }, url: ajaxloc + "/bearer1234/" })
1:['WIN.LOC'] variable=ajaxloc
0 (loc:6)- var ajaxloc = window.location.href
이 항목은 29번째 줄에 $.ajax 호출 표현식이 있고, 이 호출 표현식은 url 템플릿 값이 ajaxloc + "/bearer1234/"인 ajax 요청을 트리거하며, 매개변수 ajaxloc은 6번째 줄에서 window.location.href에서 값을 읽는 프로그램 슬라이스이므로 ['WIN.LOC']을 통해 위조 가능함을 보여줍니다.
JAW 테스트 프로세스를 간소화하고 설정이 올바른지 확인하기 위해 JAW로 테스트할 수 있는 간단한 node.js 웹 애플리케이션을 제공합니다.
먼저, 다음을 통해 종속성을 설치합니다.
$ cd tests/test-webapp
$ npm install
그런 다음, 새 화면에서 애플리케이션을 실행합니다.
$ screen -dmS jawwebapp bash -c 'PORT=6789 npm run devstart; exec sh'
자세한 내용은 여기에 있는 위키 페이지를 방문하세요. 아래는 빠른 접근을 위한 목차입니다.
풀 리퀘스트는 언제나 환영합니다. 이 프로젝트는 안전하고 환영하는 공간이 되도록 의도되었으며, 기여자는 기여자 행동 강령을 준수해야 합니다.
학술 연구에 JAW를 사용하는 경우 다음 논문을 인용해 주시기 바랍니다.
@inproceedings{JAW,
title = {JAW: Studying Client-side CSRF with Hybrid Property Graphs and Declarative Traversals},
author= {Soheil Khodayari and Giancarlo Pellegrino},
booktitle = {30th {USENIX} Security Symposium ({USENIX} Security 21)},
year = {2021},
address = {Vancouver, B.C.},
publisher = {{USENIX} Association},
}
JAW는 오랜 발전을 거듭해 왔으며 이곳에서 기여자분들께 마땅한 찬사를 보내고자 합니다!
--cookies=<cookies.pkl>: 하이브리드 모드 전용, 쿠키가 포함된 파일의 이름, 제외하려면 문자열 false 전달 (기본값: cookies.pkl).--html=<html_snapshot.html>: 하이브리드 모드 전용, DOM 트리 스냅샷이 포함된 파일의 이름, 제외하려면 문자열 false 전달 (기본값: html_rendered.html).