juice-shop-ctf-cli
Advanced tools
Comparing version 4.0.1 to 4.1.0
@@ -67,3 +67,3 @@ # Contributing [](https://github.com/bkimminich/juice-shop-ctf/graphs/contributors) [](http://waffle.io/bkimminich/juice-shop) | ||
Thean e2e tests simulate real input to the CLI and verify the printed | ||
The e2e tests simulate real input to the CLI and verify the printed | ||
output to the console. | ||
@@ -90,2 +90,1 @@ | ||
> Travis-CI due to their significant execution time. | ||
25
index.js
@@ -7,4 +7,25 @@ const inquirer = require('inquirer') | ||
const writeToZipFile = require('./lib/writeToZipFile') | ||
const readConfigStream = require('./lib/readConfigStream') | ||
const fs = require('fs') | ||
const options = require('./lib/options') | ||
const argv = require('yargs') | ||
.option('config', { | ||
alias: 'c', | ||
describe: 'provide a configuration file' | ||
}) | ||
.option('output', { | ||
alias: 'o', | ||
describe: 'change the output file' | ||
}) | ||
.help() | ||
.argv | ||
function getConfig (argv, questions) { | ||
if (argv.config) { | ||
return readConfigStream(fs.createReadStream(argv.config)) | ||
} | ||
return inquirer.prompt(questions) | ||
} | ||
const juiceShopCtfCli = async () => { | ||
@@ -44,3 +65,3 @@ const questions = [ | ||
try { | ||
const {ctfKey, juiceShopUrl, insertHints, insertHintUrls} = await inquirer.prompt(questions) | ||
const {ctfKey, juiceShopUrl, insertHints, insertHintUrls} = await getConfig(argv, questions) | ||
const [secretKey, challenges] = await Promise.all([ | ||
@@ -51,3 +72,3 @@ fetchSecretKey(ctfKey), | ||
const data = await generateData(challenges, insertHints, insertHintUrls, secretKey) | ||
const file = await writeToZipFile(data) | ||
const file = await writeToZipFile(data, argv.output) | ||
@@ -54,0 +75,0 @@ console.log() |
@@ -9,5 +9,5 @@ const Promise = require('bluebird') | ||
function writeToZipFile ({challenges, hints, flagKeys}) { | ||
function writeToZipFile ({challenges, hints, flagKeys}, desiredFileName) { | ||
return new Promise((resolve, reject) => { | ||
const fileName = 'OWASP_Juice_Shop.' + dateFormat(new Date(), 'yyyy-mm-dd') + '.zip' | ||
const fileName = desiredFileName || 'OWASP_Juice_Shop.' + dateFormat(new Date(), 'yyyy-mm-dd') + '.zip' | ||
zip.file('db/challenges.json', JSON.stringify(challenges)) | ||
@@ -14,0 +14,0 @@ zip.file('db/hints.json', JSON.stringify(hints)) |
{ | ||
"name": "juice-shop-ctf-cli", | ||
"version": "4.0.1", | ||
"description": "Command line client to generate INSERT statements for CTFd with the OWASP Juice Shop challenges", | ||
"version": "4.1.0", | ||
"description": "Capture-the-Flag (CTF) environment setup tools for OWASP Juice Shop", | ||
"author": "Bjoern Kimminich <bjoern.kimminich@owasp.org> (https://www.owasp.org/index.php/User:Bjoern_Kimminich)", | ||
@@ -52,8 +52,11 @@ "contributors": [ | ||
"colors": "~1.2", | ||
"yargs": "~11.1.0", | ||
"dateformat": "~3.0", | ||
"inquirer": "~5.1", | ||
"inquirer": "~5.2.0", | ||
"jssha": "~2.3", | ||
"js-yaml": "3.11.0", | ||
"node-zip": "~1.1", | ||
"path": "~0.12", | ||
"request": "~2.85", | ||
"joi": "13.1.2", | ||
"request-promise": "~4.2" | ||
@@ -78,2 +81,4 @@ }, | ||
"stryker-html-reporter": "~0", | ||
"stryker-javascript-mutator": "~0", | ||
"stryker-mocha-framework": "~0", | ||
"stryker-mocha-runner": "~0" | ||
@@ -94,4 +99,4 @@ }, | ||
"nyc": { | ||
"report-dir": "./reports/coverage" | ||
"report-dir": "./build/reports/coverage" | ||
} | ||
} |
@@ -31,2 +31,4 @@ #  OWASP Juice Shop CTF [](https://www.owasp.org/index.php/OWASP_Project_Inventory#tab=Labs_Projects) [](https://github.com/bkimminich/juice-shop-ctf/releases/latest) [](https://twitter.com/owasp_juiceshop) | ||
### Interactive Mode | ||
Open a command line and run: | ||
@@ -40,2 +42,42 @@ | ||
### Configuration File | ||
Instead of answering questions in the CLI you can also provide your desired configuration in a file with the following format: | ||
```yaml | ||
juiceShopUrl: https://juice-shop.herokuapp.com | ||
ctfKey: https://raw.githubusercontent.com/bkimminich/juice-shop/master/ctf.key # can also be actual key instead URL | ||
insertHints: none | free | paid | ||
insertHintUrls: none | free | paid | ||
``` | ||
You can then run the generator with: | ||
``` | ||
juice-shop-ctf --config myconfig.yml | ||
``` | ||
Optionally you can also choose the name of the output file: | ||
``` | ||
juice-shop-ctf --config myconfig.yml --output challenges.zip | ||
``` | ||
### Docker Container [](https://registry.hub.docker.com/u/bkimminich/juice-shop-ctf/) [](https://registry.hub.docker.com/u/bkimminich/juice-shop-ctf/) [](https://microbadger.com/images/bkimminich/juice-shop-ctf "Get your own image badge on microbadger.com") [](https://microbadger.com/images/bkimminich/juice-shop-ctf "Get your own version badge on microbadger.com") [](https://microbadger.com/images/bkimminich/juice-shop-ctf "Get your own commit badge on microbadger.com") | ||
Share your current directory with the `/data` volume of your `bkimminich/juice-shop-ctf` Docker container and run the interactive mode with: | ||
``` | ||
docker run -ti --rm -v $(pwd):/data bkimminich/juice-shop-ctf | ||
``` | ||
Alternatively you can provide a configuration file via: | ||
``` | ||
docker run -ti --rm -v $(pwd):/data bkimminich/juice-shop-ctf --config myconfig.yml | ||
``` | ||
Choosing the name of the output file is also possible: | ||
``` | ||
docker run -ti --rm -v $(pwd):/data bkimminich/juice-shop-ctf --config myconfig.yml --output challenges.zip | ||
``` | ||
--- | ||
**For detailed step-by-step instructions and examples please refer to | ||
@@ -80,10 +122,15 @@ [the _Setting up CTFd for Juice Shop_ in the _Hosting a CTF event_ chapter](https://bkimminich.gitbooks.io/pwning-owasp-juice-shop/content/part1/ctf.html#setting-up-ctfd-for-juice-shop) | ||
PayPal donations via above button go to the OWASP Foundations and are | ||
earmarked for "Juice Shop". This is the preferred way to support the | ||
project. | ||
earmarked for "Juice Shop". This is the preferred and most convenient | ||
way to support the project. | ||
### Others | ||
### Credit Card (through RegOnline) | ||
[](https://flattr.com/thing/3856930/bkimminichjuice-shop-on-GitHub) | ||
[](https://gratipay.com/juice-shop) | ||
OWASP hosts a | ||
[donation form on RegOnline](https://www.regonline.com/Register/Checkin.aspx?EventID=1044369). | ||
Refer to the | ||
[Credit card donation step-by-step](https://bkimminich.gitbooks.io/pwning-owasp-juice-shop/content/part3/donations.html#credit-card-donation-step-by-step) | ||
guide for help with filling out the donation form correctly. | ||
### Crypto Currency | ||
[](https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm) | ||
@@ -90,0 +137,0 @@ [](https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW) |
@@ -11,4 +11,11 @@ module.exports = function (config) { | ||
coverageAnalysis: 'perTest', | ||
reporter: ['html', 'progress'] | ||
mutator: 'javascript', | ||
reporter: ['html', 'progress'], | ||
htmlReporter: { | ||
baseDir: 'build/reports/mutation' | ||
} | ||
}) | ||
if (process.env.TRAVIS_BUILD_NUMBER) { | ||
config.reporter = ['clear-text', 'progress'] | ||
} | ||
} |
@@ -12,11 +12,24 @@ const chai = require('chai') | ||
const outputFile = 'OWASP_Juice_Shop.' + dateFormat(new Date(), 'yyyy-mm-dd') + '.zip' | ||
const desiredOutputFile = './output.zip' | ||
const configFile = 'config.yml' | ||
const util = require('util') | ||
const execFile = util.promisify(require('child_process').execFile) | ||
const juiceShopCtfCli = [path.join(__dirname, '../../bin/juice-shop-ctf.js')] | ||
function cleanup () { | ||
if (fs.existsSync(outputFile)) { | ||
fs.unlinkSync(outputFile) | ||
} | ||
if (fs.existsSync(configFile)) { | ||
fs.unlinkSync(configFile) | ||
} | ||
if (fs.existsSync(desiredOutputFile)) { | ||
fs.unlinkSync(desiredOutputFile) | ||
} | ||
} | ||
describe('juice-shop-ctf', () => { | ||
beforeEach(() => { | ||
if (fs.existsSync(outputFile)) { | ||
fs.unlinkSync(outputFile) | ||
} | ||
}) | ||
beforeEach(cleanup) | ||
after(cleanup) | ||
@@ -73,2 +86,50 @@ it('should accept defaults for all input questions', function () { | ||
}) | ||
it('should accept a config file', function () { | ||
fs.writeFileSync(configFile, ` | ||
juiceShopUrl: https://juice-shop.herokuapp.com | ||
ctfKey: https://raw.githubusercontent.com/bkimminich/juice-shop/master/ctf.key | ||
insertHints: paid | ||
insertHintUrls: paid`) | ||
this.timeout(15000) | ||
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile]).then(obj => obj.stdout)).to | ||
.eventually.match(/ZIP-archive written to /i) | ||
}) | ||
it('should fail when the config file is unparsable', function () { | ||
fs.writeFileSync(configFile, ` | ||
juiceShopUrl: https://juice-shop.herokuapp.com | ||
ctfKey: https://raw.githubusercontent.com/bkimminich/juice-shop/master/ctf.key | ||
insertHints`) | ||
this.timeout(15000) | ||
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile]).then(obj => obj.stdout)).to | ||
.eventually.match(/can not read /i) | ||
}) | ||
it('should fail when the config file contains invalid values', function () { | ||
fs.writeFileSync(configFile, ` | ||
juiceShopUrl: https://juice-shop.herokuapp.com | ||
ctfKey: https://raw.githubusercontent.com/bkimminich/juice-shop/master/ctf.key | ||
insertHints: paid | ||
insertHintUrls: invalidValue`) | ||
this.timeout(15000) | ||
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile]).then(obj => obj.stdout)).to | ||
.eventually.match(/"insertHintUrls" must be one of /i) | ||
}) | ||
it('should write the output file to the specified location', function () { | ||
fs.writeFileSync(configFile, ` | ||
juiceShopUrl: https://juice-shop.herokuapp.com | ||
ctfKey: https://raw.githubusercontent.com/bkimminich/juice-shop/master/ctf.key | ||
insertHints: paid | ||
insertHintUrls: paid`) | ||
this.timeout(15000) | ||
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile, '--output', desiredOutputFile]) | ||
.then(() => fs.existsSync(desiredOutputFile))).to | ||
.eventually.equal(true) | ||
}) | ||
}) |
@@ -39,2 +39,22 @@ const Promise = require('bluebird') | ||
}) | ||
it('should be written to the desired ZIP file', () => { | ||
writeToZipFile.__set__({ | ||
console: { | ||
log () {} | ||
}, | ||
fs: { | ||
writeFileAsync (path, data) { | ||
expect(data).to.match(/challenges.json/) | ||
expect(data).to.match(/hints.json/) | ||
expect(data).to.match(/keys.json/) | ||
expect(data).to.match(/files.json/) | ||
expect(data).to.match(/tags.json/) | ||
expect(path).to.match(/custom\.zip/) | ||
return new Promise(resolve => { resolve() }) | ||
}} | ||
}) | ||
return expect(writeToZipFile({challenges: {results: []}, flagKeys: {results: []}, hints: {results: []}}, 'custom.zip')) | ||
.to.be.fulfilled | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
780231
40
936
160
12
19
3
1
+ Addedjoi@13.1.2
+ Addedjs-yaml@3.11.0
+ Addedyargs@~11.1.0
+ Addedansi-regex@2.1.1(transitive)
+ Addedargparse@1.0.10(transitive)
+ Addedcamelcase@4.1.0(transitive)
+ Addedcliui@4.1.0(transitive)
+ Addedcode-point-at@1.1.0(transitive)
+ Addedcross-spawn@6.0.6(transitive)
+ Addeddecamelize@1.2.0(transitive)
+ Addedend-of-stream@1.4.4(transitive)
+ Addedesprima@4.0.1(transitive)
+ Addedexeca@1.0.0(transitive)
+ Addedfind-up@2.1.0(transitive)
+ Addedget-caller-file@1.0.3(transitive)
+ Addedget-stream@4.1.0(transitive)
+ Addedhoek@5.0.46.1.3(transitive)
+ Addedinquirer@5.2.0(transitive)
+ Addedinvert-kv@2.0.0(transitive)
+ Addedis-fullwidth-code-point@1.0.0(transitive)
+ Addedis-stream@1.1.0(transitive)
+ Addedisemail@3.2.0(transitive)
+ Addedisexe@2.0.0(transitive)
+ Addedjoi@13.1.2(transitive)
+ Addedjs-yaml@3.11.0(transitive)
+ Addedlcid@2.0.0(transitive)
+ Addedlocate-path@2.0.0(transitive)
+ Addedmap-age-cleaner@0.1.3(transitive)
+ Addedmem@4.3.0(transitive)
+ Addedmimic-fn@2.1.0(transitive)
+ Addednice-try@1.0.5(transitive)
+ Addednpm-run-path@2.0.2(transitive)
+ Addednumber-is-nan@1.0.1(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedos-locale@3.1.0(transitive)
+ Addedp-defer@1.0.0(transitive)
+ Addedp-finally@1.0.0(transitive)
+ Addedp-is-promise@2.1.0(transitive)
+ Addedp-limit@1.3.0(transitive)
+ Addedp-locate@2.0.0(transitive)
+ Addedp-try@1.0.0(transitive)
+ Addedpath-exists@3.0.0(transitive)
+ Addedpath-key@2.0.1(transitive)
+ Addedpump@3.0.2(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedrequire-directory@2.1.1(transitive)
+ Addedrequire-main-filename@1.0.1(transitive)
+ Addedsemver@5.7.2(transitive)
+ Addedset-blocking@2.0.0(transitive)
+ Addedshebang-command@1.2.0(transitive)
+ Addedshebang-regex@1.0.0(transitive)
+ Addedsprintf-js@1.0.3(transitive)
+ Addedstring-width@1.0.2(transitive)
+ Addedstrip-ansi@3.0.1(transitive)
+ Addedstrip-eof@1.0.0(transitive)
+ Addedtopo@3.0.3(transitive)
+ Addedwhich@1.3.1(transitive)
+ Addedwhich-module@2.0.1(transitive)
+ Addedwrap-ansi@2.1.0(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedy18n@3.2.2(transitive)
+ Addedyargs@11.1.1(transitive)
+ Addedyargs-parser@9.0.2(transitive)
- Removedinquirer@5.1.0(transitive)
Updatedinquirer@~5.2.0