
JAW: Un framework di analisi della sicurezza basato su grafi per JavaScript lato client.
J A W
Sito web | Documentazione | Configurazione | Crawler | Avvio rapido Docker (Esempio)
Un'implementazione open-source prototipale di grafi di proprietà per JavaScript basata sul parser esprima e sulla specifica EsTree SpiderMonkey Spec. JAW può essere utilizzato per analizzare il lato client di applicazioni web e programmi basati su JavaScript.
Questo progetto è concesso in licenza GNU AFFERO GENERAL PUBLIC LICENSE V3.0. Vedi qui per maggiori informazioni.
JAW ha un sito web su Github Pages disponibile all'indirizzo https://soheilkhodayari.github.io/JAW/.
Note di rilascio:
JAW-V2.JAW-V1.L'architettura di JAW è mostrata di seguito.
JAW può essere utilizzato in due modi distinti:
Analisi arbitraria di JavaScript: utilizza JAW per modellare e analizzare qualsiasi programma JavaScript specificando il path del file system del programma.
Analisi di applicazioni web: analizza un'applicazione web fornendo un singolo URL seed.
Utilizza le risorse web raccolte per creare un Hybrid Program Graph (HPG), che verrà importato in un database Neo4j.
Opzionalmente, fornisci al modulo di costruzione HPG una mappatura di tipi semantici a token personalizzati del linguaggio JavaScript, facilitando la categorizzazione delle funzioni JavaScript in base al loro scopo (ad esempio, funzioni di richiesta HTTP).
Interroga il database grafico Neo4j costruito per varie analisi. JAW offre attraversamenti di utilità per l'analisi del flusso di dati, l'analisi del flusso di controllo, l'analisi di raggiungibilità e il pattern matching. Questi attraversamenti possono essere utilizzati per sviluppare analisi di sicurezza personalizzate.
JAW include anche attraversamenti integrati per rilevare vulnerabilità di CSRF lato client, DOM Clobbering e dirottamento delle richieste.
Gli output verranno salvati nella stessa cartella dell'input.
Lo script di installazione si basa sui seguenti prerequisiti:
npm package manager (node js)python 3.xpip package managerSuccessivamente, installa le dipendenze necessarie tramite:
$ ./install.sh
Per istruzioni di installazione dettagliate, consulta qui.
Puoi eseguire un'istanza del pipeline in uno screen in background tramite:
$ python3 -m run_pipeline --conf=config.yaml
La CLI fornisce le seguenti opzioni:
$ python3 -m run_pipeline -h
usage: run_pipeline.py [-h] [--conf FILE] [--site SITE] [--list LIST] [--from FROM] [--to TO]
This script runs the tool pipeline.
optional arguments:
-h, --help show this help message and exit
--conf FILE, -C FILE pipeline configuration file. (default: config.yaml)
--site SITE, -S SITE website to test; overrides config file (default: None)
--list LIST, -L LIST site list to test; overrides config file (default: None)
--from FROM, -F FROM the first entry to consider when a site list is provided; overrides config file (default: -1)
--to TO, -T TO the last entry to consider when a site list is provided; overrides config file (default: -1)
Config di input: JAW si aspetta un file di configurazione .yaml come input. Vedi config.yaml per un esempio.
Suggerimento. Il file di configurazione specifica diverse fasi (ad esempio, crawling, analisi statica, ecc.) che possono essere abilitate o disabilitate per ogni classe di vulnerabilità. Ciò consente di eseguire i blocchi dello strumento singolarmente o in un ordine diverso (ad esempio, prima eseguire il crawling di tutte le webapp, poi condurre l'analisi di sicurezza).
Per eseguire un esempio rapido che mostra come costruire un grafo di proprietà ed eseguire query Cypher su di esso, esegui:
$ python3 -m analyses.example.example_analysis --input=$(pwd)/data/test_program/test.js
Questo modulo raccoglie i dati (cioè, codice JavaScript e valori di stato delle pagine web) necessari per i test. Se desideri testare uno specifico file JavaScript già presente sul tuo file system, puoi saltare questo passaggio.
JAW ha crawler basati su Selenium (JAW-v1), Puppeteer (JAW-v2, v3) e Playwright (JAW-v3). Per le funzionalità più aggiornate, si consiglia di utilizzare le versioni basate su Puppeteer o Playwright.
Questo crawler web utilizza foxhound, una versione strumentata di Firefox, per eseguire il tracciamento dinamico delle contaminazioni mentre naviga tra le pagine web. Per avviare il crawler, esegui:
$ cd crawler
$ node crawler-taint.js --seedurl=https://google.com --maxurls=100 --headless=true --foxhoundpath=<percorso-opzionale-eseguibile-foxhound>
Il foxhoundpath è impostato per default sulla seguente directory: crawler/foxhound/firefox che contiene un binario chiamato firefox.
Nota: è necessaria una build di foxhound per utilizzare questa versione. Una build Ubuntu è inclusa nel rilascio JAW-v3.
Per avviare il crawler, esegui:
$ cd crawler
$ node crawler.js --seedurl=https://google.com --maxurls=100 --browser=chrome --headless=true
Vedi qui per maggiori informazioni.
Per avviare il crawler, esegui:
$ cd crawler/hpg_crawler
$ vim docker-compose.yaml # imposta qui i siti web da sottoporre a crawling e salva
$ docker-compose build
$ docker-compose up -d
Fai riferimento alla documentazione di hpg_crawler qui per maggiori informazioni.
Per generare un HPG per un (insieme di) file JavaScript, esegui:
$ node engine/cli.js --lang=js --graphid=graph1 --input=/in/file1.js --input=/in/file2.js --output=$(pwd)/data/out/ --mode=csv
argomenti opzionali:
--lang: linguaggio del programma di input
--graphid: un identificatore per l'HPG generato
--input: percorso/i del/i programma/i di input
--output: percorso dell'HPG di output, deve essere in ...
--mode: determina il formato di output (csv o graphML)
Per importare un HPG all'interno di un database grafico neo4j (istanza docker), esegui:
$ python3 -m hpg_neo4j.hpg_import --rpath=<percorso-cartella-file-csv> --id=<xyz> --nodes=<nodes.csv> --edges=<rels.csv>
$ python3 -m hpg_neo4j.hpg_import -h
usage: hpg_import.py [-h] [--rpath P] [--id I] [--nodes N] [--edges E]
This script imports a CSV of a property graph into a neo4j docker database.
optional arguments:
-h, --help show this help message and exit
--rpath P relative path to the folder containing the graph CSV files inside the `data` directory
--id I an identifier for the graph or docker container
--nodes N the name of the nodes csv file (default: nodes.csv)
--edges E the name of the relations csv file (default: rels.csv)
Per creare un hybrid property graph per l'output di hpg_crawler e importarlo in un'istanza locale di neo4j, puoi anche eseguire:
$ python3 -m engine.api <path> --js=<program.js> --import=<bool> --hybrid=<bool> --reqs=<requests.out> --evts=<events.out> --cookies=<cookies.pkl> --html=<html_snapshot.html>
Specifica dei parametri:
<path>: percorso assoluto della cartella contenente i file del programma da analizzare (deve trovarsi sotto la cartella engine/outputs).--js=<program.js>: nome del programma JavaScript da analizzare (default: js_program.js).--import=<bool>: indica se il grafo di proprietà costruito deve essere importato in un database neo4j attivo (default: true).--hybrid=bool: indica se la modalità ibrida è abilitata (default: false). Implica che il tester desidera arricchire il grafo di proprietà inserendo file per uno qualsiasi degli snapshot HTML, eventi attivati, richieste HTTP e cookie, come raccolti dal crawler JAW.--reqs=<requests.out>: solo per modalità ibrida, nome del file contenente la sequenza di richieste di rete osservate, passa la stringa false per escludere (default: request_logs_short.out).--evts=<events.out>: solo per modalità ibrida, nome del file contenente la sequenza di eventi attivati, passa la stringa per escludere (default: ).Per maggiori informazioni, puoi utilizzare la CLI di aiuto fornita con l'API di costruzione del grafo:
$ python3 -m engine.api -h
L'HPG costruito può quindi essere interrogato utilizzando Cypher o l'ORM NeoModel.
Dovresti inserire ed eseguire le tue query in analyses/<NOME_ANALISI>.
Puoi utilizzare l'ORM NeoModel per interrogare l'HPG. Per scrivere una query:
example_query_orm.py nella cartella analyses/example.$ python3 -m analyses.example.example_query_orm
Per maggiori informazioni, consulta qui.
Puoi utilizzare Cypher per scrivere query personalizzate. Per farlo:
example_query_cypher.py nella cartella analyses/example.$ python3 -m analyses.example.example_query_cypher
Per maggiori informazioni, consulta qui.
Questa sezione descrive come configurare e utilizzare JAW per il rilevamento delle vulnerabilità e come interpretare l'output. JAW contiene, tra le altre, query autonome per rilevare CSRF lato client e DOM Clobbering.
Passo 1. Abilita il componente di analisi per la classe di vulnerabilità nel file di input config.yaml:
request_hijacking:
enabled: true
# [...]
open_redirect:
enabled: false
# [...]
domclobbering:
enabled: false
# [...]
cs_csrf:
enabled: false
# [...]
Passo 2. Esegui un'istanza del pipeline con:
$ python3 -m run_pipeline --conf=config.yaml
Suggerimento. Puoi eseguire più istanze del pipeline in diversi 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'
$ # [...]
Per generare automaticamente file di configurazione paralleli, puoi utilizzare lo script generate_config.py.
Gli output verranno salvati in un file chiamato sink.flows.out nella stessa cartella dell'input. Per il CSRF lato client, ad esempio, per ogni richiesta HTTP rilevata, JAW genera una voce che segna l'insieme di tipi semantici (ovvero, tag o etichette semantiche) associati agli elementi che costruiscono la richiesta (cioè, le slice del programma). Ad esempio, una richiesta HTTP contrassegnata con il tipo semantico ['WIN.LOC'] è falsificabile attraverso il punto di iniezione window.location. Tuttavia, una richiesta contrassegnata con ['NON-REACH'] non è falsificabile.
Un esempio di voce di output è mostrato di seguito:
[*] 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
Questa voce mostra che alla riga 29, c'è un'espressione di chiamata $.ajax, e questa espressione di chiamata attiva una richiesta ajax con il valore del template URL ajaxloc + "/bearer1234/", dove il parametro ajaxloc è una slice del programma che legge il suo valore alla riga 6 da window.location.href, quindi falsificabile attraverso ['WIN.LOC'].
Per semplificare il processo di test per JAW e assicurarti che la tua configurazione sia corretta, forniamo una semplice applicazione web node.js con cui puoi testare JAW.
Per prima cosa, installa le dipendenze tramite:
$ cd tests/test-webapp
$ npm install
Quindi, esegui l'applicazione in un nuovo screen:
$ screen -dmS jawwebapp bash -c 'PORT=6789 npm run devstart; exec sh'
Per maggiori informazioni, visita la nostra pagina wiki qui. Di seguito un sommario per un accesso rapido.
Le pull request sono sempre benvenute. Questo progetto si intende come uno spazio sicuro e accogliente; ci si aspetta che i contributori aderiscano al codice di condotta per i contributori.
Se utilizzi JAW per la ricerca accademica, ti invitiamo a citare il seguente articolo:
@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 ha fatto molta strada e vogliamo ringraziare qui i nostri contributori!
falseevents.out--cookies=<cookies.pkl>: solo per modalità ibrida, nome del file contenente i cookie, passa la stringa false per escludere (default: cookies.pkl).--html=<html_snapshot.html>: solo per modalità ibrida, nome del file contenente lo snapshot dell'albero DOM, passa la stringa false per escludere (default: html_rendered.html).