├── packages ├── engine │ ├── lib │ │ ├── index.js │ │ ├── util.js │ │ ├── entropy.js │ │ ├── async.js │ │ └── trace.js │ ├── .npmignore │ ├── test │ │ └── env.test.js │ ├── examples │ │ ├── cascade.yaml │ │ ├── request.yaml │ │ ├── secrets.yaml │ │ ├── cascade.js │ │ ├── workflow.yaml │ │ ├── secrets.js │ │ ├── analyzer.js │ │ ├── analyzer.yaml │ │ ├── workflow.js │ │ └── request.js │ ├── types │ │ └── index.tsbuildinfo │ ├── tsconfig.json │ ├── LICENSE │ └── package.json ├── lau │ ├── lib │ │ ├── index.js │ │ ├── modules │ │ │ ├── index.js │ │ │ └── alienvault.js │ │ └── scheduler.js │ ├── .npmignore │ ├── commands │ │ └── lau │ │ │ ├── sub │ │ │ ├── lau.js │ │ │ ├── alienvault.js │ │ │ ├── webarchive.js │ │ │ └── commoncrawl.js │ │ │ └── index.js │ ├── test │ │ └── env.test.js │ ├── README.md │ ├── LICENSE │ └── package.json ├── leaks │ ├── lib │ │ ├── index.js │ │ ├── database.js │ │ ├── scanners │ │ │ ├── index.js │ │ │ └── npm │ │ │ │ └── index.js │ │ └── entropy.js │ ├── .npmignore │ ├── database │ │ ├── telegram.yaml │ │ ├── mailchimp.yaml │ │ ├── trello.yaml │ │ ├── sauce.yaml │ │ ├── square.yaml │ │ ├── sendgrid.yaml │ │ ├── outlook.yaml │ │ ├── sonarqube.yaml │ │ ├── stackhawk.yaml │ │ ├── braintree.yaml │ │ ├── github.yaml │ │ ├── hockeyapp.yaml │ │ ├── heroku.yaml │ │ ├── twilio.yaml │ │ ├── mailgun.yaml │ │ ├── codeclimate.yaml │ │ ├── artifactory.yaml │ │ ├── slack.yaml │ │ ├── linkedin.yaml │ │ ├── twitter.yaml │ │ ├── nuget.yaml │ │ ├── facebook.yaml │ │ ├── stripe.yaml │ │ ├── crypto.yaml │ │ └── google.yaml │ ├── test │ │ ├── env.test.js │ │ └── dataset.test.js │ ├── commands │ │ └── leaks │ │ │ └── index.js │ ├── README.md │ ├── scripts │ │ └── generate-database.js │ ├── LICENSE │ └── package.json ├── pown │ ├── lib │ │ ├── index.js │ │ └── splash.js │ ├── .npmignore │ ├── test │ │ └── env.test.js │ ├── scripts │ │ └── postinstall.js │ ├── bin │ │ └── pown.js │ ├── commands │ │ └── update │ │ │ └── index.js │ ├── LICENSE │ └── package.json ├── script │ ├── lib │ │ └── index.js │ ├── examples │ │ ├── mem.pown │ │ ├── exit.pown │ │ ├── args.pown │ │ ├── env.pown │ │ ├── js.pown │ │ ├── script.pown │ │ ├── sh.pown │ │ ├── sleep.pown │ │ ├── throw.pown │ │ ├── echo.pown │ │ └── verbose.pown │ ├── .npmignore │ ├── commands │ │ └── script │ │ │ ├── globals │ │ │ └── options.js │ │ │ └── sub │ │ │ ├── throw.js │ │ │ ├── index.js │ │ │ ├── exit.js │ │ │ ├── sleep.js │ │ │ ├── echo.js │ │ │ ├── mem.js │ │ │ ├── sh.js │ │ │ ├── set.js │ │ │ └── js.js │ ├── test │ │ └── env.test.js │ ├── README.md │ ├── LICENSE │ └── package.json ├── shell │ ├── lib │ │ └── index.js │ ├── .npmignore │ ├── test │ │ └── env.test.js │ ├── README.md │ ├── LICENSE │ └── package.json ├── credits │ ├── lib │ │ └── index.js │ ├── .npmignore │ ├── test │ │ └── env.test.js │ ├── README.md │ ├── package.json │ └── LICENSE ├── cli │ ├── lib │ │ ├── index.js │ │ ├── colors.js │ │ ├── progress.js │ │ ├── wrap.js │ │ ├── table.js │ │ ├── prompt.js │ │ ├── bar.js │ │ ├── json.js │ │ └── line.js │ ├── .npmignore │ ├── test │ │ ├── env.test.js │ │ ├── colors.test.js │ │ └── wrap.test.js │ ├── examples │ │ ├── bar.js │ │ └── table.js │ ├── bin │ │ └── cli.js │ ├── README.md │ ├── LICENSE │ └── package.json ├── recon │ ├── lib │ │ ├── index.js │ │ ├── cytoscape.js │ │ ├── normalize.js │ │ ├── utils.js │ │ ├── common.js │ │ ├── cache │ │ │ └── memcached.js │ │ ├── worker │ │ │ └── utils.js │ │ ├── options.js │ │ └── types.js │ ├── .npmignore │ ├── examples │ │ ├── noop.pown │ │ ├── measure.pown │ │ ├── dns.pown │ │ ├── script-traversals.pown │ │ ├── githubenum.pown │ │ ├── auto.pown │ │ ├── request.pown │ │ ├── whodev.pown │ │ ├── whocode.pown │ │ ├── worker.js │ │ ├── exec-script.js │ │ ├── exec-embedded.js │ │ ├── request.yaml │ │ ├── traverse.pown │ │ ├── group.pown │ │ ├── permissive-cors-1.pown │ │ ├── permissive-cors-2.pown │ │ ├── cache-options.pown │ │ ├── coderecon.pown │ │ ├── named-traversals.pown │ │ ├── permissive-cors-1.yaml │ │ └── permissive-cors-2.yaml │ ├── commands │ │ └── recon │ │ │ ├── lib │ │ │ └── globals │ │ │ │ ├── options.js │ │ │ │ ├── cache.js │ │ │ │ └── recon.js │ │ │ ├── sub │ │ │ ├── export │ │ │ │ └── index.js │ │ │ ├── show │ │ │ │ ├── index.js │ │ │ │ └── sub │ │ │ │ │ └── selected.js │ │ │ ├── template │ │ │ │ └── index.js │ │ │ ├── cache │ │ │ │ ├── index.js │ │ │ │ └── sub │ │ │ │ │ └── clear.js │ │ │ ├── remote │ │ │ │ ├── index.js │ │ │ │ ├── remove.js │ │ │ │ ├── list.js │ │ │ │ └── add.js │ │ │ ├── traverse │ │ │ │ ├── sub │ │ │ │ │ ├── del.js │ │ │ │ │ ├── get.js │ │ │ │ │ ├── set.js │ │ │ │ │ └── traverse.js │ │ │ │ └── index.js │ │ │ ├── options │ │ │ │ ├── index.js │ │ │ │ └── sub │ │ │ │ │ ├── clear.js │ │ │ │ │ ├── delete.js │ │ │ │ │ ├── get.js │ │ │ │ │ ├── list.js │ │ │ │ │ └── set.js │ │ │ ├── load │ │ │ │ └── index.js │ │ │ ├── save │ │ │ │ └── index.js │ │ │ ├── select │ │ │ │ └── index.js │ │ │ ├── ungroup │ │ │ │ └── index.js │ │ │ ├── remove │ │ │ │ └── index.js │ │ │ ├── group │ │ │ │ └── index.js │ │ │ ├── layout │ │ │ │ └── index.js │ │ │ └── transform │ │ │ │ └── transforms.js │ │ │ └── index.js │ ├── test │ │ ├── env.test.js │ │ ├── normalize.test.js │ │ └── detect.test.js │ ├── transforms │ │ ├── omnisint │ │ │ └── index.js │ │ ├── gravatar │ │ │ └── index.js │ │ ├── ipinfoio │ │ │ └── index.js │ │ └── securitytrails │ │ │ └── index.js │ └── LICENSE ├── connect │ ├── lib │ │ ├── index.js │ │ └── scheduler.js │ ├── .npmignore │ ├── test │ │ └── env.test.js │ ├── commands │ │ └── connect │ │ │ └── options │ │ │ ├── scheduler │ │ │ ├── index.js │ │ │ └── handler.js │ │ │ ├── output │ │ │ ├── index.js │ │ │ └── handler.js │ │ │ └── connect │ │ │ ├── handler.js │ │ │ └── index.js │ ├── LICENSE │ ├── package.json │ └── examples │ │ └── request-smuggling.js ├── modules │ ├── lib │ │ └── index.js │ ├── .npmignore │ ├── test │ │ └── env.test.js │ ├── commands │ │ └── modules │ │ │ ├── index.js │ │ │ └── sub │ │ │ ├── search.js │ │ │ ├── uninstall.js │ │ │ ├── update.js │ │ │ ├── list.js │ │ │ └── install.js │ ├── README.md │ ├── LICENSE │ └── package.json ├── regexp │ ├── lib │ │ ├── index.js │ │ ├── eachMatch.js │ │ └── regexp.js │ ├── .npmignore │ ├── test │ │ ├── env.test.js │ │ ├── regexp.test.js │ │ └── eachMatch.test.js │ ├── README.md │ ├── package.json │ └── LICENSE ├── request │ ├── lib │ │ ├── index.js │ │ ├── limiter.js │ │ └── error.js │ ├── .npmignore │ ├── commands │ │ └── request │ │ │ ├── options │ │ │ ├── proxy │ │ │ │ ├── index.js │ │ │ │ └── handler.js │ │ │ ├── scheduler │ │ │ │ ├── index.js │ │ │ │ └── handler.js │ │ │ ├── url │ │ │ │ ├── index.js │ │ │ │ └── handler.js │ │ │ ├── output │ │ │ │ ├── index.js │ │ │ │ └── handler.js │ │ │ └── request │ │ │ │ ├── index.js │ │ │ │ └── handler.js │ │ │ └── index.js │ ├── test │ │ └── env.test.js │ ├── README.md │ ├── LICENSE │ └── package.json ├── async │ ├── lib │ │ ├── index.js │ │ ├── nextTick.js │ │ ├── eachOfParallel.js │ │ ├── idle.js │ │ ├── sleep.js │ │ ├── iterateOverStream.js │ │ ├── mutex.js │ │ ├── iterateOfParallel.js │ │ ├── unrollOfParallel.js │ │ ├── iterateOfLimit.js │ │ ├── unrollOfLimit.js │ │ ├── eachOfLimit.js │ │ ├── utils.js │ │ ├── semaphore.js │ │ └── iterateOverEmitter.js │ ├── .npmignore │ ├── test │ │ ├── env.test.js │ │ ├── idle.test.js │ │ ├── nextTick.test.js │ │ ├── sleep.test.js │ │ ├── utils.test.js │ │ ├── unrollOfLimit.test.js │ │ ├── unrollOfParallel.test.js │ │ ├── semaphore.test.js │ │ └── iterateOverStream.test.js │ ├── examples │ │ ├── mutex.js │ │ ├── eachOfLimit.js │ │ └── semaphore.js │ ├── package.json │ ├── README.md │ └── LICENSE └── preferences │ ├── lib │ └── index.js │ ├── .npmignore │ ├── test │ ├── env.test.js │ └── preferences.test.js │ ├── commands │ └── preferences │ │ ├── index.js │ │ └── sub │ │ ├── get.js │ │ └── set.js │ ├── README.md │ ├── package.json │ └── LICENSE ├── .prettierignore ├── .npmignore ├── scripts ├── fix-package-lock-json.sh ├── fix-license.sh ├── fix-npm.sh ├── fix-main.sh ├── fix-test.sh ├── on-version.js └── fix-package-json.js ├── .prettierrc.json ├── test └── env.test.js ├── .eslintrc.json ├── .gitignore └── LICENSE /packages/engine/lib/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/lau/lib/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/leaks/lib/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/pown/lib/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/script/lib/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/shell/lib/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/credits/lib/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/script/examples/mem.pown: -------------------------------------------------------------------------------- 1 | mem 2 | -------------------------------------------------------------------------------- /packages/script/examples/exit.pown: -------------------------------------------------------------------------------- 1 | exit 1 2 | -------------------------------------------------------------------------------- /packages/script/examples/args.pown: -------------------------------------------------------------------------------- 1 | echo -t info $@ 2 | -------------------------------------------------------------------------------- /packages/cli/lib/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./cli') 2 | -------------------------------------------------------------------------------- /packages/script/examples/env.pown: -------------------------------------------------------------------------------- 1 | echo -t info $HOME $1 2 | -------------------------------------------------------------------------------- /packages/cli/lib/colors.js: -------------------------------------------------------------------------------- 1 | module.exports = require('chalk') 2 | -------------------------------------------------------------------------------- /packages/recon/lib/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./recon') 2 | -------------------------------------------------------------------------------- /packages/connect/lib/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./connect') 2 | -------------------------------------------------------------------------------- /packages/modules/lib/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./modules') 2 | -------------------------------------------------------------------------------- /packages/regexp/lib/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./regexp') 2 | -------------------------------------------------------------------------------- /packages/request/lib/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./request') 2 | -------------------------------------------------------------------------------- /packages/script/examples/js.pown: -------------------------------------------------------------------------------- 1 | js -e 'console.log("Hello world!")' 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/async/lib/index.js: -------------------------------------------------------------------------------- 1 | throw new Error('Use specific submodule.') 2 | -------------------------------------------------------------------------------- /packages/cli/lib/progress.js: -------------------------------------------------------------------------------- 1 | module.exports = require('are-we-there-yet') 2 | -------------------------------------------------------------------------------- /packages/leaks/lib/database.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./database.json') 2 | -------------------------------------------------------------------------------- /packages/script/examples/script.pown: -------------------------------------------------------------------------------- 1 | set -xe 2 | 3 | script ./echo.pown 4 | -------------------------------------------------------------------------------- /packages/preferences/lib/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./preferences') 2 | -------------------------------------------------------------------------------- /packages/script/examples/sh.pown: -------------------------------------------------------------------------------- 1 | sh echo -- Hello world! 2 | 3 | sh -c "ls -lah" 4 | -------------------------------------------------------------------------------- /packages/async/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/cli/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/connect/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/credits/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/engine/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/lau/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/leaks/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/modules/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/pown/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/recon/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/recon/examples/noop.pown: -------------------------------------------------------------------------------- 1 | recon t noop a 2 | recon t noop b 3 | recon t noop c 4 | -------------------------------------------------------------------------------- /packages/regexp/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/request/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/script/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/shell/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/preferences/.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | test 4 | examples 5 | screenshots 6 | -------------------------------------------------------------------------------- /packages/cli/lib/wrap.js: -------------------------------------------------------------------------------- 1 | const wordwrap = require('wordwrap') 2 | 3 | module.exports = wordwrap(79) 4 | -------------------------------------------------------------------------------- /packages/script/examples/sleep.pown: -------------------------------------------------------------------------------- 1 | echo Sleeping for 30 seconds 2 | sleep 30 3 | echo Done sleeping 4 | -------------------------------------------------------------------------------- /packages/script/examples/throw.pown: -------------------------------------------------------------------------------- 1 | set -x 2 | 3 | echo -t info Hello 4 | throw Boom 5 | echo -t info World! 6 | -------------------------------------------------------------------------------- /packages/leaks/lib/scanners/index.js: -------------------------------------------------------------------------------- 1 | const npm = require('./npm') 2 | 3 | module.exports = { 4 | npm, 5 | } 6 | -------------------------------------------------------------------------------- /scripts/fix-package-lock-json.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | rm -rf packages/*/package-lock.json 6 | -------------------------------------------------------------------------------- /packages/recon/examples/measure.pown: -------------------------------------------------------------------------------- 1 | echo Measure Example 2 | recon a a 3 | recon a b 4 | recon e --auto-weight '*' 5 | -------------------------------------------------------------------------------- /packages/script/examples/echo.pown: -------------------------------------------------------------------------------- 1 | echo -t info Hello World! 2 | echo -t warn Hello World! 3 | echo -t error Hello World! 4 | -------------------------------------------------------------------------------- /scripts/fix-license.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | find packages/* -maxdepth 0 -type d -exec cp LICENSE '{}' ';' 6 | -------------------------------------------------------------------------------- /scripts/fix-npm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | find packages/* -maxdepth 0 -type d -exec cp .npmignore '{}' ';' 6 | -------------------------------------------------------------------------------- /scripts/fix-main.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | find packages/* -maxdepth 0 -type d -exec touch '{}'/lib/index.js ';' 6 | -------------------------------------------------------------------------------- /packages/cli/lib/table.js: -------------------------------------------------------------------------------- 1 | const Table3 = require('cli-table3') 2 | 3 | class Table extends Table3 {} 4 | 5 | module.exports = { Table } 6 | -------------------------------------------------------------------------------- /packages/recon/examples/dns.pown: -------------------------------------------------------------------------------- 1 | echo DNS Recon Example 2 | recon t auto --name 'dnsresolve' --node-type domain secapps.com websecurify.com 3 | -------------------------------------------------------------------------------- /packages/script/examples/verbose.pown: -------------------------------------------------------------------------------- 1 | set -x 2 | 3 | echo -t info Hello World! 4 | echo -t warn Hello World! 5 | echo -t error Hello World! 6 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "trailingComma": "es5", 4 | "singleQuote": true, 5 | "tabWidth": 2, 6 | "useTabs": false 7 | } 8 | -------------------------------------------------------------------------------- /packages/recon/examples/script-traversals.pown: -------------------------------------------------------------------------------- 1 | set -xe 2 | 3 | recon add --node-type number 1 2 3 4 5 4 | recon v 'traverseByScript node.data("label") % 2 === 0' 5 | -------------------------------------------------------------------------------- /packages/leaks/database/telegram.yaml: -------------------------------------------------------------------------------- 1 | title: Telegram Secrets 2 | checks: 3 | - title: Telegram Secret 4 | severity: 7 5 | regex: \d{5,}:A[0-9a-z_\-]{34,34} 6 | -------------------------------------------------------------------------------- /packages/leaks/database/mailchimp.yaml: -------------------------------------------------------------------------------- 1 | title: Mailchimp Secrets 2 | checks: 3 | - title: Mailchimp API Key 4 | severity: 9 5 | regex: '[0-9a-f]{32}-us[0-9]{1,2}' 6 | -------------------------------------------------------------------------------- /packages/leaks/database/trello.yaml: -------------------------------------------------------------------------------- 1 | title: Trello Secrets 2 | checks: 3 | - title: Trello URL 4 | severity: 1 5 | regex: https://trello.com/b/[0-9a-z]/[0-9a-z_-]+ 6 | -------------------------------------------------------------------------------- /packages/leaks/database/sauce.yaml: -------------------------------------------------------------------------------- 1 | title: Sauce Secrets 2 | checks: 3 | - title: Sauce Token 4 | severity: 9 5 | regex: "sauce.{0,50}(\\\"|'|`)?[0-9a-f-]{36}(\\\"|'|`)?" 6 | -------------------------------------------------------------------------------- /packages/leaks/database/square.yaml: -------------------------------------------------------------------------------- 1 | title: Square Secrets 2 | checks: 3 | - title: Square API Token / Secret 4 | severity: 9 5 | regex: sq0(atp|csp)-[0-9a-z\-_]{22,43} 6 | -------------------------------------------------------------------------------- /packages/recon/examples/githubenum.pown: -------------------------------------------------------------------------------- 1 | echo Listing members 2 | recon t ghlm pownjs 3 | 4 | echo Extracting member repositories 5 | recon t ghlr -s 'node[type="github:member"]' 6 | -------------------------------------------------------------------------------- /packages/async/lib/nextTick.js: -------------------------------------------------------------------------------- 1 | const nextTick = () => { 2 | return new Promise((resolve) => { 3 | process.nextTick(resolve) 4 | }) 5 | } 6 | 7 | module.exports = { nextTick } 8 | -------------------------------------------------------------------------------- /packages/cli/lib/prompt.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer') 2 | 3 | const prompt = (...args) => { 4 | return inquirer.prompt(...args) 5 | } 6 | 7 | module.exports = { prompt } 8 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/lib/globals/options.js: -------------------------------------------------------------------------------- 1 | const { Options } = require('../../../../lib/options') 2 | 3 | const options = new Options() 4 | 5 | module.exports = { options } 6 | -------------------------------------------------------------------------------- /packages/leaks/database/sendgrid.yaml: -------------------------------------------------------------------------------- 1 | title: SendGrid Secrets 2 | checks: 3 | - title: SendGrid API Key 4 | severity: 9 5 | regex: 'SG\.[0-9A-Za-z\-_]{22}\.[0-9A-Za-z\-_]{43}' 6 | -------------------------------------------------------------------------------- /packages/leaks/database/outlook.yaml: -------------------------------------------------------------------------------- 1 | title: Outlook Secrets 2 | checks: 3 | - title: Outlook Team 4 | severity: 9 5 | regex: '(https\\://outlook\\.office.com/webhook/[0-9a-f-]{36}\\@)' 6 | -------------------------------------------------------------------------------- /packages/leaks/database/sonarqube.yaml: -------------------------------------------------------------------------------- 1 | title: SonarQube Secrets 2 | checks: 3 | - title: SonarQube API Key 4 | severity: 9 5 | regex: "sonar.{0,50}(\\\"|'|`)?[0-9a-f]{40}(\\\"|'|`)?" 6 | -------------------------------------------------------------------------------- /packages/leaks/database/stackhawk.yaml: -------------------------------------------------------------------------------- 1 | title: StackHawk Secrets 2 | checks: 3 | - title: StackHawk API Key 4 | severity: 9 5 | regex: 'hawk\.[0-9A-Za-z\-_]{20}\.[0-9A-Za-z\-_]{20}' 6 | -------------------------------------------------------------------------------- /packages/leaks/database/braintree.yaml: -------------------------------------------------------------------------------- 1 | title: Braintree Secrets 2 | checks: 3 | - title: Braintree API Key 4 | severity: 9 5 | regex: access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32} 6 | -------------------------------------------------------------------------------- /packages/leaks/database/github.yaml: -------------------------------------------------------------------------------- 1 | title: GitHhub Secrets 2 | checks: 3 | - title: GitHub Token 4 | severity: 9 5 | regex: github(.{0,20})?['\"][0-9a-z]{35,40}['\"] 6 | safe: false 7 | -------------------------------------------------------------------------------- /packages/recon/lib/cytoscape.js: -------------------------------------------------------------------------------- 1 | const cytoscape = require('cytoscape') 2 | 3 | const { traverse } = require('./plugins/traverse') 4 | 5 | cytoscape.use(traverse) 6 | 7 | module.exports = { cytoscape } 8 | -------------------------------------------------------------------------------- /packages/script/commands/script/globals/options.js: -------------------------------------------------------------------------------- 1 | // TODO: make this into a global singleton 2 | 3 | const options = { 4 | exit: false, 5 | expand: false, 6 | } 7 | 8 | module.exports = { options } 9 | -------------------------------------------------------------------------------- /scripts/fix-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | for dir in packages/*; do mkdir -p $dir/test; done 6 | 7 | find packages -maxdepth 2 -type d -name test -exec cp test/env.test.js '{}' ';' 8 | -------------------------------------------------------------------------------- /packages/recon/examples/auto.pown: -------------------------------------------------------------------------------- 1 | echo Setting brand 2 | recon a --node-type brand pownjs 3 | 4 | echo Auto recon phase 1 5 | recon t auto -s 'node' 6 | 7 | echo Auto recon phase 2 8 | recon t auto -s 'node' 9 | -------------------------------------------------------------------------------- /packages/leaks/database/hockeyapp.yaml: -------------------------------------------------------------------------------- 1 | title: HockeyApp Secrets 2 | checks: 3 | - title: HockeyApp API Key 4 | severity: 9 5 | regex: "hockey.{0,50}(\\\"|'|`)?[0-9a-f]{32}(\\\"|'|`)?" 6 | safe: false 7 | -------------------------------------------------------------------------------- /packages/request/commands/request/options/proxy/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'proxy-url': { 3 | alias: ['proxy'], 4 | type: 'string', 5 | describe: 'Setup proxy', 6 | default: '', 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /packages/lau/commands/lau/sub/lau.js: -------------------------------------------------------------------------------- 1 | const { buildTool } = require('../lib/tool') 2 | 3 | exports.yargs = buildTool('*', () => { 4 | const { listURIs } = require('../../../lib/modules') 5 | 6 | return listURIs 7 | }) 8 | -------------------------------------------------------------------------------- /test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/leaks/database/heroku.yaml: -------------------------------------------------------------------------------- 1 | title: Heroku Secrets 2 | checks: 3 | - title: Heroku API Key 4 | severity: 9 5 | regex: heroku(.{0,20})?['"][0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}['"] 6 | safe: false 7 | -------------------------------------------------------------------------------- /packages/cli/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/lau/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/pown/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/async/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/connect/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/credits/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/engine/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/leaks/database/twilio.yaml: -------------------------------------------------------------------------------- 1 | title: Twilio Secrets 2 | checks: 3 | - title: Twilio API Key 4 | severity: 8 5 | regex: SK[0-9a-fA-F]{32} 6 | tests: 7 | negative: 8 | - sKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9 | -------------------------------------------------------------------------------- /packages/leaks/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/modules/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/export/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'export ', 3 | describe: 'Export to file', 4 | aliases: ['x'], 5 | 6 | builder: () => {}, 7 | 8 | handler: async () => {}, 9 | } 10 | -------------------------------------------------------------------------------- /packages/recon/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/regexp/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/request/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/script/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/shell/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/preferences/test/env.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | describe('env', () => { 4 | it('ensure env is test', async () => { 5 | assert.equal(process.env.NODE_ENV, 'test', 'the env is set to test') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/recon/examples/request.pown: -------------------------------------------------------------------------------- 1 | set -x 2 | 3 | # TODO: files cannot be relative to the script because of bug in the script module 4 | # the script should be setting the cwd to its folder 5 | 6 | recon template run ./examples/request.yaml 7 | -------------------------------------------------------------------------------- /packages/cli/lib/bar.js: -------------------------------------------------------------------------------- 1 | const { Bar: _Bar, Presets } = require('cli-progress') 2 | 3 | class Bar extends _Bar { 4 | constructor(options) { 5 | super(options, Presets.shades_classic) 6 | } 7 | } 8 | 9 | module.exports = { Bar } 10 | -------------------------------------------------------------------------------- /packages/cli/lib/json.js: -------------------------------------------------------------------------------- 1 | const replacer = (key, value) => { 2 | if (value instanceof Error) { 3 | return (value.message || value).toString() 4 | } else { 5 | return value 6 | } 7 | } 8 | 9 | module.exports = { replacer } 10 | -------------------------------------------------------------------------------- /packages/recon/examples/whodev.pown: -------------------------------------------------------------------------------- 1 | set -x 2 | 3 | recon add --node-type brand "$1" 4 | 5 | recon options set -c whoaretheyreport categories -j ["coding"] 6 | recon options list -c whoaretheyreport 7 | 8 | recon t auto -s 'node[type="brand"]' 9 | -------------------------------------------------------------------------------- /packages/async/lib/eachOfParallel.js: -------------------------------------------------------------------------------- 1 | const { eachOfLimit } = require('./eachOfLimit') 2 | 3 | const eachOfParallel = async (iterable, handler) => { 4 | return eachOfLimit(iterable, handler, Infinity) 5 | } 6 | 7 | module.exports = { eachOfParallel } 8 | -------------------------------------------------------------------------------- /packages/cli/test/colors.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const colors = require('../lib/colors') 4 | 5 | describe('colors', () => { 6 | it('should color', () => { 7 | assert(colors.red('test').length > 0) 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/recon/examples/whocode.pown: -------------------------------------------------------------------------------- 1 | set -x 2 | 3 | recon add --node-type brand "$1" 4 | 5 | recon options set -c whoaretheyreport categories -j ["coding"] 6 | recon options list -c whoaretheyreport 7 | 8 | recon t whoaretheyreport -s 'node[type="brand"]' 9 | -------------------------------------------------------------------------------- /packages/engine/examples/cascade.yaml: -------------------------------------------------------------------------------- 1 | id: cascade 2 | 3 | task: 4 | - extract: 5 | value: ip0 6 | name: ip1 7 | 8 | - extract: 9 | value: ip1 10 | name: ip2 11 | 12 | - extract: 13 | value: ip2 14 | name: ip3 15 | -------------------------------------------------------------------------------- /packages/lau/commands/lau/sub/alienvault.js: -------------------------------------------------------------------------------- 1 | const { buildTool } = require('../lib/tool') 2 | 3 | exports.yargs = buildTool('alienvault', () => { 4 | const { listAlienVaultURIs } = require('../../../lib/modules/alienvault') 5 | 6 | return listAlienVaultURIs 7 | }) 8 | -------------------------------------------------------------------------------- /packages/lau/commands/lau/sub/webarchive.js: -------------------------------------------------------------------------------- 1 | const { buildTool } = require('../lib/tool') 2 | 3 | exports.yargs = buildTool('webarchive', () => { 4 | const { listWebArchiveURIs } = require('../../../lib/modules/webarchive') 5 | 6 | return listWebArchiveURIs 7 | }) 8 | -------------------------------------------------------------------------------- /packages/request/commands/request/options/scheduler/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'request-concurrency': { 3 | alias: ['c'], 4 | type: 'number', 5 | describe: 'The number of requests to send at the same time', 6 | default: Infinity, 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /packages/async/lib/idle.js: -------------------------------------------------------------------------------- 1 | const { setImmediate } = require('timers') 2 | 3 | const idle = (value) => { 4 | return new Promise((resolve) => { 5 | setImmediate(() => { 6 | resolve(value) 7 | }) 8 | }) 9 | } 10 | 11 | module.exports = { idle } 12 | -------------------------------------------------------------------------------- /packages/cli/test/wrap.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const wrap = require('../lib/wrap') 4 | 5 | describe('wrap', () => { 6 | it('should wrap', () => { 7 | assert(wrap(Array(100).fill('a').join(' ')).indexOf('\n') === 77) 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/connect/commands/connect/options/scheduler/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'connect-concurrency': { 3 | alias: ['c'], 4 | type: 'number', 5 | describe: 'The number of connections to open at the same time', 6 | default: Infinity, 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /packages/lau/commands/lau/sub/commoncrawl.js: -------------------------------------------------------------------------------- 1 | const { buildTool } = require('../lib/tool') 2 | 3 | exports.yargs = buildTool('commoncrawl', () => { 4 | const { listCommonCrawlURIs } = require('../../../lib/modules/commoncrawl') 5 | 6 | return listCommonCrawlURIs 7 | }) 8 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/show/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'show ', 3 | describe: 'Show recon state', 4 | aliases: ['view'], 5 | 6 | builder: (yargs) => { 7 | yargs.command(require('./sub/selected').yargs) 8 | }, 9 | } 10 | -------------------------------------------------------------------------------- /packages/recon/examples/worker.js: -------------------------------------------------------------------------------- 1 | const { parentPort } = require('worker_threads') 2 | 3 | parentPort.on('message', () => { 4 | parentPort.postMessage({ 5 | type: 'new-type', 6 | label: 'new-label', 7 | props: { title: 'It works!' }, 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/script/commands/script/sub/throw.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'throw [message...]', 3 | describe: 'Throw message', 4 | 5 | handler: (argv) => { 6 | const { message } = argv 7 | 8 | throw new Error(message.join(' ')) 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /packages/leaks/database/mailgun.yaml: -------------------------------------------------------------------------------- 1 | title: Mailgun Secrets 2 | checks: 3 | - title: Mailgun API Key 4 | regex: key-[0-9a-zA-Z]{32} 5 | severity: 9 6 | tests: 7 | negative: 8 | - >- 9 | propertyKey-68ecc0e37e9cc9197b98823e56976888 10 | -------------------------------------------------------------------------------- /packages/leaks/database/codeclimate.yaml: -------------------------------------------------------------------------------- 1 | # source: https://github.com/deepfence/SecretScanner/blob/master/config.yaml 2 | 3 | title: CodeClimate Secrets 4 | checks: 5 | - title: CodeClimate Key 6 | severity: 9 7 | regex: "codeclima.{0,50}(\\\"|'|`)?[0-9a-f]{64}(\\\"|'|`)?" 8 | -------------------------------------------------------------------------------- /packages/recon/examples/exec-script.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ recon }) => { 2 | recon.add([ 3 | { 4 | type: 'domain', 5 | label: 'secapps.com', 6 | }, 7 | { 8 | type: 'domain', 9 | label: 'websecurify.com', 10 | }, 11 | ]) 12 | } 13 | -------------------------------------------------------------------------------- /packages/recon/examples/exec-embedded.js: -------------------------------------------------------------------------------- 1 | module.exports = async ({ shq }) => { 2 | const message = 'adding targets...' 3 | 4 | await shq`echo ${message}` 5 | 6 | await shq`echo TEST=${process.env.TEST}` 7 | 8 | await shq`recon add --node-type domain target.com` 9 | } 10 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/template/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'template ', 3 | describe: 'Recon template commands', 4 | aliases: ['p', 'templates'], 5 | 6 | builder: (yargs) => { 7 | yargs.command(require('./sub/run').yargs) 8 | }, 9 | } 10 | -------------------------------------------------------------------------------- /packages/recon/examples/request.yaml: -------------------------------------------------------------------------------- 1 | id: request 2 | 3 | request: 4 | uri: https://httpbin.org/status/200 5 | 6 | extract: 7 | value: responseCode 8 | name: code 9 | 10 | add: 11 | type: string 12 | label: HTTP/${code} 13 | props: 14 | string: HTTP/${code} 15 | -------------------------------------------------------------------------------- /packages/regexp/test/regexp.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { RegExp } = require('../lib/regexp') 4 | 5 | describe('RegExp', () => { 6 | it('test', () => { 7 | const r = new RegExp('test', 'i') 8 | 9 | assert.ok(r.test('TEST')) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/async/lib/sleep.js: -------------------------------------------------------------------------------- 1 | const { setTimeout } = require('timers') 2 | 3 | const sleep = (milliseconds, value) => { 4 | return new Promise((resolve) => { 5 | setTimeout(() => { 6 | resolve(value) 7 | }, milliseconds) 8 | }) 9 | } 10 | 11 | module.exports = { sleep } 12 | -------------------------------------------------------------------------------- /packages/connect/commands/connect/options/scheduler/handler.js: -------------------------------------------------------------------------------- 1 | const init = (options, scheduler) => { 2 | const { connectConcurrency } = options 3 | 4 | if (connectConcurrency) { 5 | scheduler.update({ maxConcurrent: connectConcurrency }) 6 | } 7 | } 8 | 9 | module.exports = { init } 10 | -------------------------------------------------------------------------------- /packages/request/commands/request/options/scheduler/handler.js: -------------------------------------------------------------------------------- 1 | const init = (options, scheduler) => { 2 | const { requestConcurrency } = options 3 | 4 | if (requestConcurrency) { 5 | scheduler.reset({ maxConcurrent: requestConcurrency }) 6 | } 7 | } 8 | 9 | module.exports = { init } 10 | -------------------------------------------------------------------------------- /packages/script/commands/script/sub/index.js: -------------------------------------------------------------------------------- 1 | const sub = [ 2 | require('./js'), 3 | require('./sh'), 4 | require('./set'), 5 | require('./mem'), 6 | require('./exit'), 7 | require('./echo'), 8 | require('./sleep'), 9 | require('./throw'), 10 | ] 11 | 12 | module.exports = { sub } 13 | -------------------------------------------------------------------------------- /packages/engine/examples/request.yaml: -------------------------------------------------------------------------------- 1 | id: request 2 | 3 | request: 4 | uri: https://${hostname}/status/500 5 | matches: 6 | - script: responseCode === 500 7 | - word: INTERNAL 8 | part: responseMessage 9 | extracts: 10 | - jsonpath: $.responseCode 11 | name: responseCode 12 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/cache/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'cache ', 3 | describe: 'Manage cache', 4 | aliases: [], 5 | 6 | builder: (yargs) => { 7 | yargs.command(require('./sub/set').yargs) 8 | yargs.command(require('./sub/clear').yargs) 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /packages/pown/lib/splash.js: -------------------------------------------------------------------------------- 1 | console.log(` 2 | 88888b. .d88b. 888 888 888 88888b. 3 | 888 "88b d88""88b 888 888 888 888 "88b 4 | 888 888 888 888 888 888 888 888 888 5 | 888 d88P Y88..88P Y88b 888 d88P 888 888 6 | 88888P" "Y88P" "Y8888888P" 888 888 7 | 888 8 | 888 JS 9 | 888 10 | `) 11 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/lib/globals/cache.js: -------------------------------------------------------------------------------- 1 | let cache 2 | 3 | const getCache = () => { 4 | return cache 5 | } 6 | 7 | const setCache = (c) => { 8 | cache = c 9 | } 10 | 11 | const clearCache = () => { 12 | cache = undefined 13 | } 14 | 15 | module.exports = { getCache, setCache, clearCache } 16 | -------------------------------------------------------------------------------- /packages/async/lib/iterateOverStream.js: -------------------------------------------------------------------------------- 1 | const iterateOverStream = async function* (stream, handler) { 2 | if (!handler) { 3 | handler = (chunk) => chunk 4 | } 5 | 6 | for await (const chunk of stream) { 7 | yield await handler(chunk) 8 | } 9 | } 10 | 11 | module.exports = { iterateOverStream } 12 | -------------------------------------------------------------------------------- /packages/leaks/database/artifactory.yaml: -------------------------------------------------------------------------------- 1 | # source: https://github.com/deepfence/SecretScanner/blob/master/config.yaml 2 | 3 | title: Artifactory Secrets 4 | checks: 5 | - title: Artifactory Session Token 6 | severity: 9 7 | regex: "artifactory.{0,50}(\\\"|'|`)?[a-zA-Z0-9=]{112}(\\\"|'|`)?" 8 | safe: false 9 | -------------------------------------------------------------------------------- /packages/preferences/commands/preferences/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'preferences ', 3 | describe: 'Preferences', 4 | aliases: ['prefs'], 5 | 6 | builder: (yargs) => { 7 | yargs.command(require('./sub/get').yargs) 8 | yargs.command(require('./sub/set').yargs) 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /packages/recon/lib/normalize.js: -------------------------------------------------------------------------------- 1 | const normalizeDomain = (input) => { 2 | return input 3 | .trim() 4 | .toLowerCase() 5 | .replace(/\.+/g, '.') 6 | .replace(/^(\*\.)+/, '') 7 | .replace(/^\.+/, '') 8 | .replace(/\.+$/, '') 9 | } 10 | 11 | module.exports = { 12 | normalizeDomain, 13 | } 14 | -------------------------------------------------------------------------------- /packages/leaks/commands/leaks/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'leaks ', 3 | describe: 'Leaks / secrets detection tool', 4 | aliases: ['leak'], 5 | 6 | builder: (yargs) => { 7 | yargs.command(require('./sub/find').yargs) 8 | yargs.command(require('./sub/export').yargs) 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /packages/leaks/database/slack.yaml: -------------------------------------------------------------------------------- 1 | title: Slack Secrets 2 | checks: 3 | - title: Slack Token 4 | regex: xox[baprs]-([0-9a-z-]{10,48}) 5 | severity: 9 6 | 7 | - title: Slack Webhook 8 | regex: https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8,12}/[a-zA-Z0-9_]{24} 9 | severity: 8 10 | -------------------------------------------------------------------------------- /packages/request/commands/request/options/url/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'url-prefix': { 3 | alias: [], 4 | type: 'string', 5 | describe: 'Add prefix to each url', 6 | }, 7 | 8 | 'url-suffix': { 9 | alias: [], 10 | type: 'string', 11 | describe: 'Add suffix to each url', 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /packages/cli/examples/bar.js: -------------------------------------------------------------------------------- 1 | const { Bar } = require('../lib/bar') 2 | 3 | const b = new Bar() 4 | 5 | b.start(100, 0) 6 | 7 | let i = 1 8 | 9 | const t = () => { 10 | b.update(i) 11 | 12 | if (i === 100) { 13 | b.stop() 14 | } else { 15 | setTimeout(t, 100) 16 | } 17 | 18 | i += 1 19 | } 20 | 21 | t() 22 | -------------------------------------------------------------------------------- /packages/recon/examples/traverse.pown: -------------------------------------------------------------------------------- 1 | set -xe 2 | 3 | recon add --node-type uri http://0.0.0.0 4 | recon add --node-type uri http://google.com 5 | 6 | recon t http_fingerprint --auto-group --auto-weight -s 'node[type="uri"]' 7 | 8 | recon remove -v 'filter node[type="code"] | neighborhood node[type="uri"]' 9 | 10 | recon select node 11 | -------------------------------------------------------------------------------- /packages/cli/examples/table.js: -------------------------------------------------------------------------------- 1 | const { Table } = require('../lib/table') 2 | 3 | const t1 = new Table() 4 | 5 | t1.push([1, 2, 3, 4, 5]) 6 | t1.push([1, 2, 3, 4, 5]) 7 | t1.push([1, 2, 3, 4, 5]) 8 | 9 | console.log(t1.toString()) 10 | 11 | const t2 = new Table() 12 | 13 | t2.push({ a: 'b', c: 'd' }) 14 | 15 | console.log(t2.toString()) 16 | -------------------------------------------------------------------------------- /packages/leaks/database/linkedin.yaml: -------------------------------------------------------------------------------- 1 | title: LinkedIn Secrets 2 | checks: 3 | - title: LinkedIn Client ID 4 | severity: 6 5 | regex: linkedin(.{0,20})?['\"][0-9a-z]{12}['\"] 6 | safe: false 7 | 8 | - title: LinkedIn Secret Key 9 | severity: 7 10 | regex: linkedin(.{0,20})?['\"][0-9a-z]{16}['\"] 11 | safe: false 12 | -------------------------------------------------------------------------------- /packages/leaks/database/twitter.yaml: -------------------------------------------------------------------------------- 1 | title: Twitter Secrets 2 | checks: 3 | - title: Twitter Client ID 4 | severity: 6 5 | regex: twitter(.{0,20})?['\"][0-9a-z]{18,25}['\"] 6 | safe: false 7 | 8 | - title: Twitter Secret Key 9 | severity: 7 10 | regex: twitter(.{0,20})?['\"][0-9a-z]{35,44}['\"] 11 | safe: false 12 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/cache/sub/clear.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'clear [options]', 3 | describe: 'Clear cache configuration', 4 | aliases: ['c'], 5 | 6 | builder: () => {}, 7 | 8 | handler: () => { 9 | const { clearCache } = require('../../../lib/globals/cache') 10 | 11 | clearCache() 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /packages/script/commands/script/sub/exit.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'exit ', 3 | describe: 'Exit', 4 | 5 | builder: {}, 6 | 7 | handler: (argv) => { 8 | const { code } = argv 9 | 10 | const error = new Error('Forced exit') 11 | 12 | error.exitCode = parseInt(code) 13 | 14 | throw error 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /packages/async/examples/mutex.js: -------------------------------------------------------------------------------- 1 | const { Mutex } = require('../lib/mutex') 2 | 3 | const main = async () => { 4 | const mutex = new Mutex() 5 | 6 | setTimeout(() => { 7 | mutex.unlock() 8 | }, 5000) 9 | 10 | console.log('locked') 11 | 12 | await mutex.lock() 13 | 14 | console.log('unlocked') 15 | } 16 | 17 | main().catch(console.error) 18 | -------------------------------------------------------------------------------- /packages/leaks/database/nuget.yaml: -------------------------------------------------------------------------------- 1 | title: Nuget Secrets 2 | checks: 3 | - title: Nuget API Key 4 | severity: 9 5 | regex: \b(?oy2[a-z0-9]{43}) 6 | tests: 7 | positive: 8 | - oy2res2ip44zphcfttbar7i5kn4tttzulg6yhpkvzx3dcs 9 | negative: 10 | - ASDADsddsaoy2res2ip44zphcfttbar7i5kn4tttzulg6yhpkvzx3dcsdsfdfsdsdSDF 11 | -------------------------------------------------------------------------------- /packages/recon/examples/group.pown: -------------------------------------------------------------------------------- 1 | set -xe 2 | 3 | # The following script demonstrates that grouped nodes can be regroupd into new groups. 4 | 5 | recon add a b 6 | recon group 'AB' 'node[type!="group"]' 7 | recon s 'node[id="group:AB"] > node' 8 | 9 | recon add c d 10 | recon group 'CD' 'node[type!="group"]' 11 | recon s 'node[id="group:CD"] > node' 12 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/remote/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'remote ', 3 | describe: 'Remote managment', 4 | aliases: ['remotes', 'f'], 5 | 6 | builder: (yargs) => { 7 | yargs.command(require('./list').yargs) 8 | yargs.command(require('./add').yargs) 9 | yargs.command(require('./remove').yargs) 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /packages/async/lib/mutex.js: -------------------------------------------------------------------------------- 1 | class Mutex { 2 | lock() { 3 | if (this.unlock) { 4 | throw new Error(`Already locked`) 5 | } 6 | 7 | return new Promise((resolve) => { 8 | this.unlock = (value) => { 9 | delete this.unlock 10 | 11 | resolve(value) 12 | } 13 | }) 14 | } 15 | } 16 | 17 | module.exports = { Mutex } 18 | -------------------------------------------------------------------------------- /packages/async/test/idle.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { idle } = require('../lib/idle') 4 | 5 | describe('idle', () => { 6 | describe('#idle', () => { 7 | it('idles', async () => { 8 | await idle() 9 | await idle() 10 | await idle() 11 | 12 | assert.ok(true, 'done') 13 | }).timeout(1000) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/traverse/sub/del.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'del ', 3 | describe: 'Delete named traversal', 4 | 5 | builder: () => {}, 6 | 7 | handler: async (argv) => { 8 | const { name } = argv 9 | 10 | const { recon } = require('../../../lib/globals/recon') 11 | 12 | recon.cy.delTraversalByName(name) 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /packages/async/test/nextTick.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { nextTick } = require('../lib/nextTick') 4 | 5 | describe('process', () => { 6 | describe('#nextTick', () => { 7 | it('ticks', async () => { 8 | await nextTick() 9 | await nextTick() 10 | await nextTick() 11 | 12 | assert.ok(true, 'done') 13 | }) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /packages/async/test/sleep.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { sleep } = require('../lib/sleep') 4 | 5 | describe('sleep', () => { 6 | describe('#sleep', () => { 7 | it('sleeps', async () => { 8 | await sleep(300) 9 | await sleep(300) 10 | await sleep(300) 11 | 12 | assert.ok(true, 'done') 13 | }).timeout(1000) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /packages/lau/commands/lau/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'lau ', 3 | describe: 'List all URLs', 4 | 5 | builder: (yargs) => { 6 | yargs.command(require('./sub/lau').yargs) 7 | yargs.command(require('./sub/alienvault').yargs) 8 | yargs.command(require('./sub/webarchive').yargs) 9 | yargs.command(require('./sub/commoncrawl').yargs) 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/traverse/sub/get.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'get ', 3 | describe: 'Get named traversal', 4 | 5 | builder: () => {}, 6 | 7 | handler: async (argv) => { 8 | const { name } = argv 9 | 10 | const { recon } = require('../../../lib/globals/recon') 11 | 12 | console.log(recon.cy.getTraversalByName(name)) 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /packages/regexp/test/eachMatch.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { eachMatch } = require('../lib/eachMatch') 4 | 5 | describe('eachMatch', () => { 6 | it('produces results', () => { 7 | const results = [] 8 | 9 | for (let result of eachMatch(/(.)/g, 'abc')) { 10 | results.push(result) 11 | } 12 | 13 | assert.equal(results.length, 3) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /packages/regexp/lib/eachMatch.js: -------------------------------------------------------------------------------- 1 | const eachMatch = function* (regexp, input) { 2 | if (process.env.NODE_ENV !== 'production') { 3 | if (!regexp.global) { 4 | throw new Error(`Regex ${regexp} does not have global flag`) 5 | } 6 | } 7 | 8 | let match 9 | 10 | while ((match = regexp.exec(input)) !== null) { 11 | yield match 12 | } 13 | } 14 | 15 | module.exports = { eachMatch } 16 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/traverse/sub/set.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'set ', 3 | describe: 'Set named traversal', 4 | 5 | builder: () => {}, 6 | 7 | handler: async (argv) => { 8 | const { name, expression } = argv 9 | 10 | const { recon } = require('../../../lib/globals/recon') 11 | 12 | recon.cy.setTraversalByName(name, expression) 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /packages/recon/examples/permissive-cors-1.pown: -------------------------------------------------------------------------------- 1 | set -x 2 | 3 | recon a --node-type uri 'https://www.googleoptimize.com/optimize.js?id=GTM-WLFPCHW' 4 | 5 | recon t http_fingerprint -s 'node[type="uri"]' 6 | 7 | # TODO: files cannot be relative to the script because of bug in the script module 8 | # the script should be setting the cwd to its folder 9 | 10 | recon template run ./examples/permissive-cors-1.yaml 11 | -------------------------------------------------------------------------------- /packages/recon/examples/permissive-cors-2.pown: -------------------------------------------------------------------------------- 1 | set -x 2 | 3 | recon a --node-type uri 'https://www.googleoptimize.com/optimize.js?id=GTM-WLFPCHW' 4 | 5 | recon t http_fingerprint -s 'node[type="uri"]' 6 | 7 | # TODO: files cannot be relative to the script because of bug in the script module 8 | # the script should be setting the cwd to its folder 9 | 10 | recon template run ./examples/permissive-cors-2.yaml 11 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "eslint:recommended", 4 | "plugin:require-path-exists/recommended", 5 | "prettier" 6 | ], 7 | "plugins": ["require-path-exists"], 8 | "rules": {}, 9 | "parserOptions": { 10 | "ecmaVersion": "latest" 11 | }, 12 | "env": { 13 | "browser": true, 14 | "node": true, 15 | "es6": true 16 | }, 17 | "ignorePatterns": "**/*.test.js" 18 | } 19 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/traverse/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'traverse ', 3 | describe: 'Traverse nodes', 4 | aliases: ['v'], 5 | 6 | builder: (yargs) => { 7 | yargs.command(require('./sub/traverse').yargs) 8 | yargs.command(require('./sub/set').yargs) 9 | yargs.command(require('./sub/get').yargs) 10 | yargs.command(require('./sub/del').yargs) 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /packages/recon/examples/cache-options.pown: -------------------------------------------------------------------------------- 1 | # The following script demonstrates how to use cache features with options. The options 2 | # can be used to persist cache configurations across multiple transforms 3 | 4 | set -x 5 | 6 | recon cache set --dynamodb-table Cache 7 | 8 | recon add --node-type domain "secapps.com" 9 | 10 | recon t build_uri -s 'node[type="domain"]' 11 | recon t http_fingerprint -s 'node[type="uri"]' 12 | -------------------------------------------------------------------------------- /packages/leaks/database/facebook.yaml: -------------------------------------------------------------------------------- 1 | title: Facebook Secrets 2 | checks: 3 | - title: Facebook Client ID 4 | severity: 1 5 | regex: (facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"] 6 | safe: false 7 | 8 | - title: Facebook Access Token 9 | severity: 6 10 | regex: EAACEdEose0cBA[0-9a-z]+ 11 | 12 | - title: Facebook Secret Key 13 | severity: 7 14 | regex: (facebook|fb)(.{0,20})?['\"][0-9a-f]{32}['\"] 15 | safe: false 16 | -------------------------------------------------------------------------------- /packages/script/commands/script/sub/sleep.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'sleep [options] ', 3 | describe: 'Sleep seconds', 4 | 5 | builder: {}, 6 | 7 | handler: (argv) => { 8 | const { seconds } = argv 9 | 10 | const { setTimeout } = require('timers') 11 | 12 | const milliseconds = parseInt(seconds) * 1000 13 | 14 | return new Promise((resolve) => { 15 | setTimeout(resolve, milliseconds) 16 | }) 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/options/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'options ', 3 | describe: 'Manage options', 4 | aliases: ['option'], 5 | 6 | builder: (yargs) => { 7 | yargs.command(require('./sub/list').yargs) 8 | yargs.command(require('./sub/set').yargs) 9 | yargs.command(require('./sub/get').yargs) 10 | yargs.command(require('./sub/delete').yargs) 11 | yargs.command(require('./sub/clear').yargs) 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /packages/leaks/database/stripe.yaml: -------------------------------------------------------------------------------- 1 | title: Stripe Secrets 2 | checks: 3 | - title: Stripe Secret Live Key 4 | severity: 10 5 | regex: (sk|rk)_live_[0-9a-z]{24} 6 | 7 | - title: Stripe Secret Test Key 8 | severity: 5 9 | regex: (sk|rk)_test_[0-9a-z]{24} 10 | 11 | - title: Stripe Public Live Key 12 | severity: 1 13 | regex: pk_live_[0-9a-z]{24} 14 | 15 | - title: Stripe Public Test Key 16 | severity: 1 17 | regex: pk_test_[0-9a-z]{24} 18 | -------------------------------------------------------------------------------- /packages/recon/examples/coderecon.pown: -------------------------------------------------------------------------------- 1 | set -x 2 | 3 | recon add --node-type brand "$1" 4 | 5 | recon t auto --auto-group --auto-weight --name 'github*' -s 'node[type="brand"]' 6 | recon t auto --auto-group --auto-weight --name 'bitbucket*' -s 'node[type="brand"]' 7 | recon t auto --auto-group --auto-weight --name 'dockerhub*' -s 'node[type="brand"]' 8 | 9 | recon t auto --auto-group --auto-weight --name 'github*' -s 'node[type="github:member"]' 10 | 11 | recon save "$2" 12 | -------------------------------------------------------------------------------- /packages/preferences/commands/preferences/sub/get.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'get [name]', 3 | describe: 'get preferences', 4 | 5 | handler: async (argv) => { 6 | const { tool, name } = argv 7 | 8 | const { getPreferences } = require('../../../lib/preferences') 9 | 10 | const preferences = await getPreferences(tool) 11 | 12 | console.log( 13 | JSON.stringify(name ? preferences[name] : preferences, '', ' ') 14 | ) 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /packages/modules/commands/modules/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'modules ', 3 | describe: 'Module manager', 4 | aliases: ['module', 'mo', 'm'], 5 | 6 | builder: (yargs) => { 7 | yargs.command(require('./sub/install').yargs) 8 | yargs.command(require('./sub/uninstall').yargs) 9 | yargs.command(require('./sub/update').yargs) 10 | yargs.command(require('./sub/list').yargs) 11 | yargs.command(require('./sub/search').yargs) 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /packages/script/commands/script/sub/echo.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'echo [message...]', 3 | describe: 'Echos message', 4 | 5 | builder: { 6 | type: { 7 | describe: 'Message type', 8 | default: 'info', 9 | alias: ['t'], 10 | choices: ['info', 'warn', 'error'], 11 | }, 12 | }, 13 | 14 | handler: (argv) => { 15 | const { type, message } = argv 16 | 17 | if (message) { 18 | console[type](...message) 19 | } 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /packages/engine/examples/secrets.yaml: -------------------------------------------------------------------------------- 1 | id: aws-secrets 2 | 3 | analyzer: 4 | - id: aws-client-id 5 | title: AWS Client ID 6 | severity: 6 7 | matcher: 8 | - type: regex 9 | regex: \b(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16} 10 | part: data 11 | 12 | - id: aws-secret-key 13 | title: AWS Secret Key 14 | severity: 7 15 | matcher: 16 | - type: regex 17 | regex: \baws(.{0,20})?['\"][0-9a-z\/+]{40}['\"] 18 | part: data 19 | -------------------------------------------------------------------------------- /packages/request/lib/limiter.js: -------------------------------------------------------------------------------- 1 | const Bottleneck = require('bottleneck') 2 | 3 | /** 4 | * Setup for future extensions. 5 | */ 6 | class SystemLimiter extends Bottleneck {} 7 | 8 | /** 9 | * The system limiter is a global throttle for all requests. 10 | */ 11 | const systemLimiter = new SystemLimiter() 12 | 13 | /** 14 | * Setup for future extensions. 15 | */ 16 | class Limiter extends SystemLimiter {} 17 | 18 | module.exports = { 19 | SystemLimiter, 20 | 21 | systemLimiter, 22 | 23 | Limiter, 24 | } 25 | -------------------------------------------------------------------------------- /packages/regexp/lib/regexp.js: -------------------------------------------------------------------------------- 1 | let Re2 2 | 3 | try { 4 | Re2 = require('re2') 5 | } catch (e) { 6 | void 0 7 | } 8 | 9 | const _RegExp = typeof Re2 === 'function' ? Re2 : RegExp 10 | 11 | const regExp = (source, flags) => { 12 | try { 13 | return new _RegExp(source, flags) 14 | } catch (e) { 15 | if (/invalid perl operator/.test(e.message)) { 16 | return new RegExp(source, flags) 17 | } else { 18 | throw e 19 | } 20 | } 21 | } 22 | 23 | module.exports = { RegExp: _RegExp, regExp } 24 | -------------------------------------------------------------------------------- /packages/shell/README.md: -------------------------------------------------------------------------------- 1 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 2 | [![NPM](https://img.shields.io/npm/v/pown.svg)](https://www.npmjs.com/package/pown) 3 | [![Fury](https://img.shields.io/badge/version-3x%20Rage-red.svg)](https://github.com/pownjs/lobby) 4 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 5 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 6 | 7 | # Pown Shell 8 | -------------------------------------------------------------------------------- /packages/engine/types/index.tsbuildinfo: -------------------------------------------------------------------------------- 1 | {"bundle":{"commonSourceDirectory":"..","sourceFiles":["../lib/trace.js","../lib/entropy.js","../lib/async.js","../lib/util.js","../lib/template.js","../examples/analyzer.js","../examples/cascade.js","../examples/request.js","../examples/secrets.js","../examples/workflow.js","../lib/helper.js","../lib/index.js","../test/env.test.js","../test/template.test.js"],"dts":{"sections":[{"pos":0,"end":15281,"kind":"text"}],"hash":"edc45ad73d5dd5671c4b807723cbcd4d451fc74d3be9017e3c96fb7bc762db5a"}},"version":"4.8.4"} -------------------------------------------------------------------------------- /packages/modules/README.md: -------------------------------------------------------------------------------- 1 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 2 | [![NPM](https://img.shields.io/npm/v/pown.svg)](https://www.npmjs.com/package/pown) 3 | [![Fury](https://img.shields.io/badge/version-3x%20Rage-red.svg)](https://github.com/pownjs/lobby) 4 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 5 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 6 | 7 | # Pown Modules 8 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/remote/remove.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'remove ', 3 | describe: 'Remove remote', 4 | aliases: ['a'], 5 | 6 | handler: async (argv) => { 7 | const { uris } = argv 8 | 9 | const { getPreferences, setPreferences } = require('@pown/preferences') 10 | 11 | const preferences = await getPreferences('recon') 12 | 13 | uris.forEach((uri) => { 14 | delete preferences.remotes[uri] 15 | }) 16 | 17 | setPreferences('recon', preferences) 18 | }, 19 | } 20 | -------------------------------------------------------------------------------- /packages/preferences/README.md: -------------------------------------------------------------------------------- 1 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 2 | [![NPM](https://img.shields.io/npm/v/pown.svg)](https://www.npmjs.com/package/pown) 3 | [![Fury](https://img.shields.io/badge/version-3x%20Rage-red.svg)](https://github.com/pownjs/lobby) 4 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 5 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 6 | 7 | # Pown Preferences 8 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/options/sub/clear.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'clear', 3 | describe: 'Clear options', 4 | aliases: ['c'], 5 | 6 | builder: (yargs) => { 7 | yargs.option('category', { 8 | alias: ['c'], 9 | describe: 'Select category', 10 | default: 'global', 11 | }) 12 | }, 13 | 14 | handler: (argv) => { 15 | const { options } = require('../../../lib/globals/options') 16 | 17 | const { category } = argv 18 | 19 | options.clearOptions(category) 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /packages/request/commands/request/options/url/handler.js: -------------------------------------------------------------------------------- 1 | const init = (options, scheduler) => { 2 | const { urlSuffix, urlPrefix } = options 3 | 4 | scheduler.on('request-scheduled', (request) => { 5 | if (urlPrefix) { 6 | request.uri = urlPrefix + request.uri 7 | } 8 | 9 | if (urlSuffix) { 10 | request.uri = request.uri + urlSuffix 11 | } 12 | 13 | if (!/https?:\/\//i.test(request.uri)) { 14 | request.uri = 'https://' + request.uri 15 | } 16 | }) 17 | } 18 | 19 | module.exports = { init } 20 | -------------------------------------------------------------------------------- /packages/recon/test/normalize.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { normalizeDomain } = require('../lib/normalize') 4 | 5 | describe('normalize', () => { 6 | it('#normalizeDomain', () => { 7 | assert.equal(normalizeDomain('acme.com'), 'acme.com') 8 | assert.equal(normalizeDomain('acme.com.'), 'acme.com') 9 | assert.equal(normalizeDomain('Acme.com.'), 'acme.com') 10 | assert.equal(normalizeDomain('*.Acme.com.'), 'acme.com') 11 | assert.equal(normalizeDomain('*.*.Acme.com.'), 'acme.com') 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/options/sub/delete.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'delete ', 3 | describe: 'Delete option', 4 | aliases: ['d'], 5 | 6 | builder: (yargs) => { 7 | yargs.option('category', { 8 | alias: ['c'], 9 | describe: 'Select category', 10 | default: 'global', 11 | }) 12 | }, 13 | 14 | handler: (argv) => { 15 | const { options } = require('../../../lib/globals/options') 16 | 17 | const { category, name } = argv 18 | 19 | options.deleteOption(category, name) 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /packages/script/commands/script/sub/mem.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'mem', 3 | describe: 'Print current memory usage', 4 | 5 | builder: {}, 6 | 7 | handler: () => { 8 | const os = require('os') 9 | const process = require('process') 10 | 11 | console.info( 12 | `freemem=${Math.round((os.freemem() / 1024 / 1024) * 100) / 100}MB`, 13 | ...Object.entries(process.memoryUsage()).map( 14 | ([name, value]) => 15 | `${name}=${Math.round((value / 1024 / 1024) * 100) / 100}MB` 16 | ) 17 | ) 18 | }, 19 | } 20 | -------------------------------------------------------------------------------- /packages/engine/examples/cascade.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const jsYaml = require('js-yaml') 4 | 5 | const { Template } = require('../lib/template.js') 6 | const { ConsoleTracer } = require('../lib/trace.js') 7 | 8 | const main = async () => { 9 | const document = jsYaml.load( 10 | fs.readFileSync(path.join(__dirname, 'cascade.yaml')).toString() 11 | ) 12 | const template = new Template(document, { tracer: new ConsoleTracer() }) 13 | 14 | await template.run({ ip0: 'test' }) 15 | } 16 | 17 | main().catch(console.error) 18 | -------------------------------------------------------------------------------- /packages/leaks/database/crypto.yaml: -------------------------------------------------------------------------------- 1 | title: Crypto Secrets 2 | checks: 3 | - title: RKCS8 4 | severity: 9 5 | regex: '-----BEGIN PRIVATE KEY-----' 6 | # TODO: match location 7 | 8 | - title: RSA 9 | severity: 9 10 | regex: '-----BEGIN RSA PRIVATE KEY-----' 11 | # TODO: match location 12 | 13 | - title: SSH 14 | severity: 9 15 | regex: '-----BEGIN OPENSSH PRIVATE KEY-----' 16 | # TODO: match location 17 | 18 | - title: PGP 19 | severity: 9 20 | regex: '-----BEGIN PGP PRIVATE KEY BLOCK-----' 21 | # TODO: match location 22 | -------------------------------------------------------------------------------- /packages/request/commands/request/options/proxy/handler.js: -------------------------------------------------------------------------------- 1 | const init = (options, scheduler) => { 2 | const { proxyUrl } = options 3 | 4 | if (proxyUrl || process.env.HTTP_PROXY || process.env.HTTPS_PROXY) { 5 | let ProxyAgent 6 | 7 | try { 8 | ProxyAgent = require('proxy-agent') 9 | 10 | scheduler.on('request-scheduled', (request) => { 11 | request.agent = new ProxyAgent(proxyUrl) 12 | }) 13 | } catch (e) { 14 | console.error(`install proxy-agent for http/s proxy support`) 15 | } 16 | } 17 | } 18 | 19 | module.exports = { init } 20 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/options/sub/get.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'get ', 3 | describe: 'Get option', 4 | aliases: ['g'], 5 | 6 | builder: (yargs) => { 7 | yargs.option('category', { 8 | alias: ['c'], 9 | describe: 'Select category', 10 | default: 'global', 11 | }) 12 | }, 13 | 14 | handler: (argv) => { 15 | const { options } = require('../../../lib/globals/options') 16 | 17 | const { category, name } = argv 18 | 19 | const value = options.getOption(category, name) 20 | 21 | console.log(value) 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /packages/async/lib/iterateOfParallel.js: -------------------------------------------------------------------------------- 1 | const { EventEmitter } = require('events') 2 | const { eachOfParallel } = require('./eachOfParallel') 3 | const { iterateOverEmitter } = require('./iterateOverEmitter') 4 | 5 | const iterateOfParallel = async function* (iterable, handler) { 6 | const em = new EventEmitter() 7 | 8 | eachOfParallel(iterable, async (item) => em.emit('item', await handler(item))) 9 | .then(() => em.emit('end')) 10 | .catch((error) => em.emit('error', error)) 11 | 12 | yield* iterateOverEmitter(em, 'item') 13 | } 14 | 15 | module.exports = { iterateOfParallel } 16 | -------------------------------------------------------------------------------- /packages/engine/examples/workflow.yaml: -------------------------------------------------------------------------------- 1 | id: workflow 2 | 3 | ops: 4 | - requests: 5 | - id: request1 6 | uri: https://httpbin.org/status/200 7 | 8 | - id: request2 9 | uri: https://httpbin.org/status/300 10 | 11 | - screenshots: 12 | - id: screenshot1 13 | uri: https://httpbin.org/status/200 14 | - id: screenshot2 15 | uri: https://httpbin.org/status/300 16 | 17 | requests: 18 | - id: request3 19 | uri: https://httpbin.org/status/400 20 | 21 | screenshots: 22 | - id: screenshot3 23 | uri: https://httpbin.org/status/400 24 | -------------------------------------------------------------------------------- /packages/preferences/commands/preferences/sub/set.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'set ', 3 | describe: 'set preferences', 4 | 5 | handler: async (argv) => { 6 | const { tool, name, value } = argv 7 | 8 | const { 9 | getPreferences, 10 | setPreferences, 11 | } = require('../../../lib/preferences') 12 | 13 | const preferences = await getPreferences(tool) 14 | 15 | preferences[name] = JSON.parse(value) 16 | 17 | await setPreferences(tool, preferences) 18 | 19 | console.log(JSON.stringify(preferences[name], '', ' ')) 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /packages/script/commands/script/sub/sh.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'sh [cmd...]', 3 | describe: 'Run shell command', 4 | 5 | builder: { 6 | command: { 7 | describe: 'The shell command', 8 | type: 'string', 9 | alias: ['c'], 10 | }, 11 | }, 12 | 13 | handler: async (argv) => { 14 | const { command, cmd } = argv 15 | 16 | const { execSync } = require('child_process') 17 | 18 | if (command) { 19 | execSync(command, { stdio: 'inherit' }) 20 | } else if (cmd) { 21 | execSync(cmd.join(' '), { stdio: 'inherit' }) 22 | } 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /packages/regexp/README.md: -------------------------------------------------------------------------------- 1 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 2 | [![NPM](https://img.shields.io/npm/v/pown.svg)](https://www.npmjs.com/package/pown) 3 | [![Fury](https://img.shields.io/badge/version-3x%20Rage-red.svg)](https://github.com/pownjs/lobby) 4 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 5 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 6 | 7 | # Pown RegExp 8 | 9 | This is a simple, high-level library to work with regular expressions. 10 | -------------------------------------------------------------------------------- /packages/connect/commands/connect/options/output/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'content-sniff-size': { 3 | alias: ['content-sniff', 'sniff-size'], 4 | type: 'number', 5 | describe: 'Specify the size of the content sniff', 6 | default: 5, 7 | }, 8 | 9 | 'print-response-data': { 10 | alias: ['print-data'], 11 | type: 'boolean', 12 | describe: 'Print response data', 13 | default: false, 14 | }, 15 | 16 | 'download-response-data': { 17 | alias: ['download-data'], 18 | type: 'boolean', 19 | describe: 'Download response data', 20 | default: false, 21 | }, 22 | } 23 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/remote/list.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'list', 3 | describe: 'List remotes', 4 | aliases: ['l'], 5 | 6 | handler: async () => { 7 | const { getPreferences } = require('@pown/preferences') 8 | 9 | const { remotes = {} } = await getPreferences('recon') 10 | 11 | Object.entries(remotes).forEach(([uri, defs]) => { 12 | console.group(uri) 13 | 14 | Object.entries(defs).forEach(([name, def]) => { 15 | console.table([{ ...def, name }], ['name', 'title', 'description']) 16 | }) 17 | 18 | console.groupEnd() 19 | }) 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /packages/cli/bin/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const process = require('process') 4 | const { extract } = require('@pown/modules') 5 | 6 | const { execute } = require('../lib/cli') 7 | const { init: initConsole } = require('../lib/console') 8 | 9 | const boot = async () => { 10 | const { loadableModules, loadableCommands } = await extract() 11 | 12 | initConsole() 13 | 14 | await execute(process.argv.slice(2), { loadableModules, loadableCommands }) 15 | } 16 | 17 | boot() 18 | .then(() => process.exit(0)) 19 | .catch((error) => { 20 | console.error(error) 21 | 22 | process.exit(error.code || 1) 23 | }) 24 | -------------------------------------------------------------------------------- /packages/recon/examples/named-traversals.pown: -------------------------------------------------------------------------------- 1 | set -xe 2 | 3 | recon add --node-type letter a b c d c 4 | recon add --node-type number 1 2 3 4 5 5 | 6 | recon v set letters 'filter node[type="letter"]' 7 | recon v set numbers 'filter node[type="number"]' 8 | 9 | recon v 'traverseByName letters' 10 | recon v 'traverseByName numbers' 11 | 12 | recon v 'traverseByName letters & traverseByName numbers' 13 | 14 | recon v 'traverseByName numbers | traverseByScript node.data("label") % 2 === 0' 15 | 16 | recon v set script 'traverseByScript node.data("label") % 2 === 0' 17 | 18 | recon v 'traverseByName numbers | traverseByName script' 19 | -------------------------------------------------------------------------------- /packages/credits/README.md: -------------------------------------------------------------------------------- 1 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 2 | [![NPM](https://img.shields.io/npm/v/pown.svg)](https://www.npmjs.com/package/pown) 3 | [![Fury](https://img.shields.io/badge/version-3x%20Rage-red.svg)](https://github.com/pownjs/lobby) 4 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 5 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 6 | 7 | # Pown Credits 8 | 9 | Celebrate all Pown.js contributors. This command is part of every pown standart distribution. 10 | -------------------------------------------------------------------------------- /packages/engine/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["esnext"], 5 | "allowJs": true, 6 | "checkJs": true, 7 | "skipLibCheck": false, 8 | "strict": false, 9 | "forceConsistentCasingInFileNames": true, 10 | "declaration": true, 11 | "emitDeclarationOnly": true, 12 | "incremental": true, 13 | "esModuleInterop": true, 14 | "module": "esnext", 15 | "resolveJsonModule": true, 16 | "moduleResolution": "node", 17 | "outFile": "types/index.d.ts" 18 | }, 19 | "include": ["**/*.js", "**/*.ts"], 20 | "exclude": ["types/index.d.ts", "node_modules"] 21 | } 22 | -------------------------------------------------------------------------------- /packages/engine/examples/secrets.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const jsYaml = require('js-yaml') 4 | 5 | const { Template } = require('../lib/template.js') 6 | const { ConsoleTracer } = require('../lib/trace.js') 7 | 8 | const main = async () => { 9 | const document = jsYaml.load( 10 | fs.readFileSync(path.join(__dirname, 'secrets.yaml')).toString() 11 | ) 12 | const template = new Template(document, { tracer: new ConsoleTracer() }) 13 | 14 | await template.run({ data: '' }) 15 | console.log('---') 16 | await template.run({ data: 'AKIAJE56YT5SVRUGH5OA' }) 17 | } 18 | 19 | main().catch(console.error) 20 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/options/sub/list.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'list', 3 | describe: 'List option', 4 | aliases: ['l'], 5 | 6 | builder: (yargs) => { 7 | yargs.option('category', { 8 | alias: ['c'], 9 | describe: 'Select category', 10 | default: 'global', 11 | }) 12 | }, 13 | 14 | handler: (argv) => { 15 | const { options } = require('../../../lib/globals/options') 16 | 17 | const { category } = argv 18 | 19 | const table = [] 20 | 21 | for (let option of options.listOptions(category)) { 22 | table.push(option) 23 | } 24 | 25 | console.table(table) 26 | }, 27 | } 28 | -------------------------------------------------------------------------------- /packages/async/examples/eachOfLimit.js: -------------------------------------------------------------------------------- 1 | const { sleep } = require('../lib/sleep') 2 | const { eachOfLimit } = require('../lib/eachOfLimit') 3 | 4 | const main = async () => { 5 | const concurency = 5 6 | 7 | const generator = async function* () { 8 | let i = 1 9 | 10 | for (;;) { 11 | yield i++ 12 | } 13 | } 14 | 15 | eachOfLimit( 16 | generator(), 17 | async (item) => { 18 | console.log(`processing item`, item) 19 | 20 | if (item % concurency == 0) { 21 | console.log('---') 22 | } 23 | 24 | await sleep(1000) 25 | }, 26 | concurency 27 | ) 28 | } 29 | 30 | main().catch(console.error) 31 | -------------------------------------------------------------------------------- /packages/cli/lib/line.js: -------------------------------------------------------------------------------- 1 | const process = require('process') 2 | const readline = require('readline') 3 | 4 | const makeLineIterator = (input) => { 5 | if ([true, false, '-'].includes(input) || !input) { 6 | const rl = readline.createInterface({ 7 | input: process.stdin, 8 | }) 9 | 10 | return async function* () { 11 | for await (let line of rl) { 12 | yield line 13 | } 14 | } 15 | } else { 16 | return function* () { 17 | if (Array.isArray(input)) { 18 | yield* input 19 | } else { 20 | yield input 21 | } 22 | } 23 | } 24 | } 25 | 26 | module.exports = { makeLineIterator } 27 | -------------------------------------------------------------------------------- /packages/lau/README.md: -------------------------------------------------------------------------------- 1 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 2 | [![NPM](https://img.shields.io/npm/v/pown.svg)](https://www.npmjs.com/package/pown) 3 | [![Fury](https://img.shields.io/badge/version-3x%20Rage-red.svg)](https://github.com/pownjs/lobby) 4 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 5 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 6 | 7 | # Pown LAU 8 | 9 | Pown LAU (List All URLs) is a library and Pownjs tool for enlisting target web application URLs using several public databases. 10 | -------------------------------------------------------------------------------- /packages/request/README.md: -------------------------------------------------------------------------------- 1 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 2 | [![NPM](https://img.shields.io/npm/v/pown.svg)](https://www.npmjs.com/package/pown) 3 | [![Fury](https://img.shields.io/badge/version-3x%20Rage-red.svg)](https://github.com/pownjs/lobby) 4 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 5 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 6 | 7 | # Pown Request 8 | 9 | This is a simple, high-level library and pownjs command for performing requests. This module comes with its own Scheduler. 10 | -------------------------------------------------------------------------------- /packages/async/test/utils.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { isIterable } = require('../lib/utils') 4 | 5 | describe('utils', () => { 6 | describe('isIterable', () => { 7 | it('validates', () => { 8 | assert.ok(!isIterable(0), 'numbers are not iterables') 9 | assert.ok(!isIterable(1), 'numbers are not iterables') 10 | 11 | assert.ok(!isIterable(false), 'booleans are not iterables') 12 | assert.ok(!isIterable(true), 'booleans are not iterables') 13 | 14 | assert.ok(!isIterable(''), 'empty strings are not iterables') 15 | assert.ok(isIterable('abc'), 'non empty strings are iterables') 16 | }) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /packages/connect/commands/connect/options/connect/handler.js: -------------------------------------------------------------------------------- 1 | const init = (options, scheduler) => { 2 | const { connectTimeout, dataTimeout, acceptUnauthorized, tls } = options 3 | 4 | if (connectTimeout) { 5 | scheduler.on('connect-scheduled', (connect) => { 6 | connect.connectTimeout = connectTimeout 7 | }) 8 | } 9 | 10 | if (dataTimeout) { 11 | scheduler.on('connect-scheduled', (connect) => { 12 | connect.dataTimeout = dataTimeout 13 | }) 14 | } 15 | 16 | scheduler.on('connect-scheduled', (connect) => { 17 | connect.rejectUnauthorized = !acceptUnauthorized 18 | connect.tls = tls 19 | }) 20 | } 21 | 22 | module.exports = { init } 23 | -------------------------------------------------------------------------------- /packages/engine/lib/util.js: -------------------------------------------------------------------------------- 1 | const ensureArray = (input) => { 2 | return Array.isArray(input) ? input : input ? [input] : [] 3 | } 4 | 5 | const ensureObject = (input) => { 6 | return typeof input === 'object' ? input : { value: input } 7 | } 8 | 9 | const btoa = (input) => 10 | (!Buffer.isBuffer(input) ? Buffer.from(input) : input).toString('base64') 11 | const atob = (input) => Buffer.from(input, 'base64') 12 | 13 | const dict = (input) => input 14 | const list = (input) => input 15 | 16 | const ret = (input) => input 17 | 18 | module.exports = { 19 | ensureArray, 20 | ensureObject, 21 | 22 | btoa, 23 | atob, 24 | 25 | dict, 26 | list, 27 | 28 | ret, 29 | } 30 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/load/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'load ', 3 | describe: 'Load a file', 4 | aliases: ['l'], 5 | 6 | builder: (yargs) => { 7 | const { installWriteOptions } = require('../../lib/handlers/file') 8 | 9 | installWriteOptions(yargs) 10 | }, 11 | 12 | handler: async (argv) => { 13 | const { file } = argv 14 | 15 | const { recon } = require('../../lib/globals/recon') 16 | 17 | const { 18 | handleWriteOptions, 19 | handleReadOptions, 20 | } = require('../../lib/handlers/file') 21 | 22 | await handleReadOptions({ read: file }, recon) 23 | 24 | await handleWriteOptions(argv, recon) 25 | }, 26 | } 27 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/save/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'save ', 3 | describe: 'Save to file', 4 | aliases: ['o'], 5 | 6 | builder: (yargs) => { 7 | const { installReadOptions } = require('../../lib/handlers/file') 8 | 9 | installReadOptions(yargs) 10 | }, 11 | 12 | handler: async (argv) => { 13 | const { file } = argv 14 | 15 | const { recon } = require('../../lib/globals/recon') 16 | 17 | const { 18 | handleReadOptions, 19 | handleWriteOptions, 20 | } = require('../../lib/handlers/file') 21 | 22 | await handleReadOptions(argv, recon) 23 | 24 | await handleWriteOptions({ write: file }, recon) 25 | }, 26 | } 27 | -------------------------------------------------------------------------------- /packages/leaks/README.md: -------------------------------------------------------------------------------- 1 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 2 | [![NPM](https://img.shields.io/npm/v/pown.svg)](https://www.npmjs.com/package/pown) 3 | [![Fury](https://img.shields.io/badge/version-3x%20Rage-red.svg)](https://github.com/pownjs/lobby) 4 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 5 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 6 | 7 | # Pown Leaks 8 | 9 | Pown Leaks is a comprehensive database of regular expressions that help you search for leaks, such as passwords, keys, tokens and other sensitive strings in files. 10 | -------------------------------------------------------------------------------- /packages/script/commands/script/sub/set.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'set [options]', 3 | describe: 'Set scripting options', 4 | 5 | builder: { 6 | exit: { 7 | describe: 'Exit immediately', 8 | type: 'boolean', 9 | alias: ['e'], 10 | }, 11 | 12 | expand: { 13 | describe: 'Expand command', 14 | type: 'boolean', 15 | alias: ['x'], 16 | }, 17 | }, 18 | 19 | handler: (argv) => { 20 | const { exit, expand } = argv 21 | 22 | const { options } = require('../globals/options') 23 | 24 | if (exit !== undefined) { 25 | options.exit = exit 26 | } 27 | 28 | if (expand !== undefined) { 29 | options.expand = expand 30 | } 31 | }, 32 | } 33 | -------------------------------------------------------------------------------- /packages/lau/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | const { unrollOfParallel } = require('@pown/async/lib/unrollOfParallel') 2 | 3 | const { listAlienVaultURIs } = require('./alienvault') 4 | const { listWebArchiveURIs } = require('./webarchive') 5 | const { listCommonCrawlURIs } = require('./commoncrawl') 6 | 7 | const sg = async function* (generator) { 8 | try { 9 | yield* generator 10 | } catch (e) {} 11 | } 12 | 13 | const listURIs = async function* ( 14 | domain, 15 | { safeGenerator = sg, ...options } = {} 16 | ) { 17 | yield* unrollOfParallel( 18 | [listAlienVaultURIs, listWebArchiveURIs, listCommonCrawlURIs].map((f) => 19 | safeGenerator(f(domain, options)) 20 | ) 21 | ) 22 | } 23 | 24 | module.exports = { listURIs } 25 | -------------------------------------------------------------------------------- /packages/connect/commands/connect/options/connect/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'connect-timeout': { 3 | alias: ['t', 'timeout'], 4 | type: 'number', 5 | describe: 'Maximum time allowed for connection', 6 | default: 30000, 7 | }, 8 | 9 | 'data-timeout': { 10 | alias: ['T'], 11 | type: 'number', 12 | describe: 'Maximum time allowed for connection', 13 | default: 30000, 14 | }, 15 | 16 | 'accept-unauthorized': { 17 | alias: ['k', 'insecure'], 18 | type: 'boolean', 19 | describe: 'Accept unauthorized TLS errors', 20 | default: false, 21 | }, 22 | 23 | tls: { 24 | alias: [], 25 | type: 'boolean', 26 | describe: 'Connect with TLS', 27 | default: false, 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /packages/engine/examples/analyzer.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const jsYaml = require('js-yaml') 4 | 5 | const { Template } = require('../lib/template.js') 6 | const { ConsoleTracer } = require('../lib/trace.js') 7 | 8 | const main = async () => { 9 | const document = jsYaml.load( 10 | fs.readFileSync(path.join(__dirname, 'analyzer.yaml')).toString() 11 | ) 12 | const template = new Template(document, { tracer: new ConsoleTracer() }) 13 | 14 | await template.run({}) 15 | console.log('---') 16 | await template.run({ 17 | responseHeaders: { 18 | 'access-control-allow-origin': '*', 19 | 'access-control-allow-credentials': 'true', 20 | }, 21 | }) 22 | } 23 | 24 | main().catch(console.error) 25 | -------------------------------------------------------------------------------- /packages/cli/README.md: -------------------------------------------------------------------------------- 1 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 2 | [![NPM](https://img.shields.io/npm/v/pown.svg)](https://www.npmjs.com/package/pown) 3 | [![Fury](https://img.shields.io/badge/version-3x%20Rage-red.svg)](https://github.com/pownjs/lobby) 4 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 5 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 6 | 7 | # Pown CLI 8 | 9 | CLI is the main command line interface to PownJS. It contains some basic functionalities, such as colors, tables, logging and more. Just like all other PownJS features, this module is 100% swapable. Your can replace this module with your own. 10 | -------------------------------------------------------------------------------- /packages/pown/scripts/postinstall.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const child_process = require('child_process') 4 | 5 | const run = (command) => { 6 | console.log(`$ ${command}`) 7 | 8 | return child_process.execSync(command, { stdio: 'ignore' }) 9 | } 10 | 11 | const main = () => { 12 | require('../lib/splash') 13 | 14 | const modules = [] 15 | 16 | if (modules.length) { 17 | console.log('* installing default modules', modules.join(', ')) 18 | 19 | modules.forEach((module) => { 20 | run(`pown modules install @pown/${module}`) 21 | }) 22 | } 23 | 24 | console.log('') 25 | console.log('Additional modules available!') 26 | console.log('') 27 | console.log('Try `pown modules search @pown`.') 28 | console.log('\n') 29 | } 30 | 31 | main() 32 | -------------------------------------------------------------------------------- /packages/recon/lib/utils.js: -------------------------------------------------------------------------------- 1 | const makeId = (type, name, ...extra) => { 2 | return `${type ? type + ':' : ''}${[ 3 | name || Math.random().toString(32).substring(2), 4 | ] 5 | .concat(extra) 6 | .join(':')}` 7 | } 8 | 9 | const makeNode = (node) => { 10 | const { 11 | id: _id, 12 | type = '', 13 | label = '', 14 | props = {}, 15 | edges = [], 16 | ...rest 17 | } = node 18 | 19 | const id = _id || makeId(type, label) 20 | 21 | return { ...rest, id, type, label, props, edges } 22 | } 23 | 24 | const flatten = (array, times) => { 25 | let result = array 26 | 27 | for (let i = 0; i < times; i++) { 28 | result = [].concat(...result) 29 | } 30 | 31 | return result 32 | } 33 | 34 | module.exports = { makeId, makeNode, flatten } 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | # NPM configuration files 40 | .npmrc 41 | -------------------------------------------------------------------------------- /packages/leaks/lib/entropy.js: -------------------------------------------------------------------------------- 1 | // see https://gist.github.com/ppseprus/afab8500dec6394c401734cb6922d220 2 | 3 | const getCharacterFrequency = (chr, str) => { 4 | let c = 0 5 | let i = -1 6 | 7 | while ((i = str.indexOf(chr, i + 1)) >= 0) { 8 | c += 1 9 | } 10 | 11 | return c 12 | } 13 | 14 | const calculateEntropyHP = (str) => { 15 | return ( 16 | [...new Set(str)] 17 | .map((chr) => getCharacterFrequency(chr, str)) 18 | .reduce((sum, frequency) => { 19 | const p = frequency / str.length 20 | 21 | return sum + p * Math.log2(1 / p) 22 | }, 0) * str.length 23 | ) 24 | } 25 | 26 | const calculateEntropy = (str) => { 27 | return Math.round(calculateEntropyHP(str)) 28 | } 29 | 30 | module.exports = { calculateEntropy, calculateEntropyHP } 31 | -------------------------------------------------------------------------------- /packages/leaks/lib/scanners/npm/index.js: -------------------------------------------------------------------------------- 1 | const { eachMatch } = require('@pown/regexp/lib/eachMatch') 2 | 3 | const modules = { 4 | title: 'NPM Module', 5 | 6 | severity: 1, 7 | 8 | scan: function* (input) { 9 | for (let match of eachMatch( 10 | /"(?:dependencies|devDependencies)":\s*(\{.+?\})/g, 11 | input 12 | )) { 13 | const { index, 1: find } = match 14 | 15 | let deps 16 | 17 | try { 18 | deps = JSON.parse(find) 19 | } catch (e) {} 20 | 21 | if (deps) { 22 | for (let [name, version] of Object.entries(deps)) { 23 | yield { index, find: `${name}@${version}` } 24 | } 25 | } 26 | } 27 | }, 28 | } 29 | 30 | module.exports = { 31 | title: 'NPM Module Enumeration', 32 | checks: [modules], 33 | } 34 | -------------------------------------------------------------------------------- /packages/request/commands/request/options/output/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'filter-response-code': { 3 | alias: ['response-code', 'filter-status'], 4 | type: 'string', 5 | describe: 'Filter responses with code', 6 | default: '', 7 | }, 8 | 9 | 'content-sniff-size': { 10 | alias: ['content-sniff', 'sniff-size'], 11 | type: 'number', 12 | describe: 'Specify the size of the content sniff', 13 | default: 5, 14 | }, 15 | 16 | 'print-response-body': { 17 | alias: ['print-body'], 18 | type: 'boolean', 19 | describe: 'Print response body', 20 | default: false, 21 | }, 22 | 23 | 'download-response-body': { 24 | alias: ['download-body'], 25 | type: 'boolean', 26 | describe: 'Download response body', 27 | default: false, 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /scripts/on-version.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const { spawnSync } = require('child_process') 4 | 5 | const main = async () => { 6 | if (!process.env.npm_new_version) { 7 | return 8 | } 9 | 10 | const packagesDir = path.join(__dirname, '..', 'packages') 11 | 12 | for (const dir of fs.readdirSync(packagesDir)) { 13 | const packageFile = path.join(packagesDir, dir, 'package.json') 14 | 15 | const packageJSON = fs.readFileSync(packageFile) 16 | 17 | const package = JSON.parse(packageJSON.toString()) 18 | 19 | package.version = process.env.npm_new_version 20 | 21 | fs.writeFileSync(packageFile, JSON.stringify(package, '', 2) + '\n') 22 | 23 | spawnSync('git', ['add', packageFile]) 24 | } 25 | } 26 | 27 | main().catch(console.error) 28 | -------------------------------------------------------------------------------- /packages/lau/lib/scheduler.js: -------------------------------------------------------------------------------- 1 | const requestJSON = async (scheduler, request, options) => { 2 | const { retry = 5 } = request 3 | const { parser: parse = JSON.parse } = options || {} 4 | 5 | const times = Math.max(0, retry) + 1 6 | 7 | for (let i = 0; i < times; i++) { 8 | if (i > 0) { 9 | console.info(`retrying ${i}/${retry}`) 10 | } 11 | 12 | const { responseBody } = await scheduler.request(request) 13 | 14 | try { 15 | return parse(responseBody) 16 | } catch (e) { 17 | if (process.env.NODE_ENV !== 'production') { 18 | console.error(new Error(`Parsing JSON data from ${request.uri} failed`)) 19 | console.error(e) 20 | } 21 | } 22 | } 23 | 24 | throw new Error(`Unable to parse JSON data`) 25 | } 26 | 27 | module.exports = { requestJSON } 28 | -------------------------------------------------------------------------------- /packages/modules/commands/modules/sub/search.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'search ', 3 | describe: 'Search modules', 4 | aliases: ['s'], 5 | 6 | handler: async (yargs) => { 7 | const { terms = [] } = yargs 8 | 9 | const util = require('util') 10 | const { spawn } = require('child_process') 11 | const { 12 | ensurePreferencesFilename, 13 | getPreferencesDirectory, 14 | } = require('@pown/preferences') 15 | 16 | const spawnAsync = util.promisify(spawn) 17 | 18 | await ensurePreferencesFilename('modules', 'package.json') 19 | 20 | const dirname = getPreferencesDirectory('modules') 21 | 22 | await spawnAsync('npm', ['search', ...terms], { 23 | shell: true, 24 | stdio: 'inherit', 25 | cwd: dirname, 26 | }) 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /packages/modules/commands/modules/sub/uninstall.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'uninstall ', 3 | describe: 'Uninstall modules', 4 | aliases: ['u'], 5 | 6 | handler: async (yargs) => { 7 | const { modules = [] } = yargs 8 | 9 | const util = require('util') 10 | const { spawn } = require('child_process') 11 | const { 12 | ensurePreferencesFilename, 13 | getPreferencesDirectory, 14 | } = require('@pown/preferences') 15 | 16 | const spawnAsync = util.promisify(spawn) 17 | 18 | await ensurePreferencesFilename('modules', 'package.json') 19 | 20 | const dirname = getPreferencesDirectory('modules') 21 | 22 | await spawnAsync('npm', ['uninstall', ...modules], { 23 | shell: true, 24 | stdio: 'inherit', 25 | cwd: dirname, 26 | }) 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /packages/async/examples/semaphore.js: -------------------------------------------------------------------------------- 1 | const { sleep } = require('../lib/sleep') 2 | const { Semaphore } = require('../lib/semaphore') 3 | 4 | const main = async () => { 5 | const concurency = 5 6 | 7 | const semaphore = new Semaphore(concurency) 8 | 9 | let item = 0 10 | 11 | await Promise.all( 12 | Array(concurency) 13 | .fill(0) 14 | .map(async () => { 15 | for (;;) { 16 | const localItem = (item += 1) 17 | 18 | const release = await semaphore.acquire() 19 | 20 | console.log(`processing item`, localItem) 21 | 22 | if (localItem % concurency == 0) { 23 | console.log('---') 24 | } 25 | 26 | release(sleep(1000)) 27 | } 28 | }) 29 | ) 30 | 31 | await semaphore.join() 32 | } 33 | 34 | main().catch(console.error) 35 | -------------------------------------------------------------------------------- /packages/request/lib/error.js: -------------------------------------------------------------------------------- 1 | const RETRY_ERROR_CODE = 'RETRY' 2 | 3 | /** 4 | * This error is only raised when we maxed the number of retries. 5 | */ 6 | class RetryError extends Error { 7 | /** 8 | * @param {string} message 9 | */ 10 | constructor(message) { 11 | super(message) 12 | 13 | this.code = RETRY_ERROR_CODE 14 | } 15 | } 16 | 17 | const BARRED_ERROR_CODE = 'BARRED' 18 | 19 | /** 20 | * This error is only raised when a specific origin is barred. 21 | */ 22 | class BarredError extends Error { 23 | /** 24 | * @param {string} message 25 | */ 26 | constructor(message) { 27 | super(message) 28 | 29 | this.code = BARRED_ERROR_CODE 30 | } 31 | } 32 | 33 | module.exports = { 34 | RETRY_ERROR_CODE, 35 | 36 | RetryError, 37 | 38 | BARRED_ERROR_CODE, 39 | 40 | BarredError, 41 | } 42 | -------------------------------------------------------------------------------- /packages/async/lib/unrollOfParallel.js: -------------------------------------------------------------------------------- 1 | const { EventEmitter } = require('events') 2 | 3 | const { isIterable, isString } = require('./utils') 4 | const { eachOfParallel } = require('./eachOfParallel') 5 | const { iterateOverEmitter } = require('./iterateOverEmitter') 6 | 7 | const unrollOfParallel = async function* (iterables) { 8 | const ee = new EventEmitter() 9 | 10 | eachOfParallel(iterables, async (item) => { 11 | if (isIterable(item) && !isString(item)) { 12 | for await (let subitem of unrollOfParallel(item)) { 13 | ee.emit('item', subitem) 14 | } 15 | } else { 16 | ee.emit('item', item) 17 | } 18 | }) 19 | .then(() => ee.emit('end')) 20 | .catch((error) => ee.emit('error', error)) 21 | 22 | yield* iterateOverEmitter(ee, 'item') 23 | } 24 | 25 | module.exports = { unrollOfParallel } 26 | -------------------------------------------------------------------------------- /packages/modules/commands/modules/sub/update.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'update [modules...]', 3 | describe: 'Update modules', 4 | aliases: ['upgrade', 'up', 'u'], 5 | 6 | handler: async (yargs) => { 7 | const { modules = [] } = yargs 8 | 9 | const util = require('util') 10 | const { spawn } = require('child_process') 11 | const { 12 | ensurePreferencesFilename, 13 | getPreferencesDirectory, 14 | } = require('@pown/preferences') 15 | 16 | const spawnAsync = util.promisify(spawn) 17 | 18 | await ensurePreferencesFilename('modules', 'package.json') 19 | 20 | const dirname = getPreferencesDirectory('modules') 21 | 22 | await spawnAsync('npm', ['update', '--depth', '9999', ...modules], { 23 | shell: true, 24 | stdio: 'inherit', 25 | cwd: dirname, 26 | }) 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /packages/async/lib/iterateOfLimit.js: -------------------------------------------------------------------------------- 1 | const { EventEmitter } = require('events') 2 | const { eachOfLimit } = require('./eachOfLimit') 3 | const { iterateOverEmitter } = require('./iterateOverEmitter') 4 | 5 | const iterateOfLimit = async function* (iterable, handler, limit = 1) { 6 | if (typeof limit === 'function') { 7 | ;[handler, limit] = [limit, handler] 8 | } 9 | 10 | const em = new EventEmitter() 11 | 12 | eachOfLimit( 13 | iterable, 14 | async (item) => { 15 | item = await handler(item) 16 | 17 | if (item != null) { 18 | em.emit('item', item) // NOTE: only emit if not null 19 | } 20 | }, 21 | limit 22 | ) 23 | .then(() => em.emit('end')) 24 | .catch((error) => em.emit('error', error)) 25 | 26 | yield* iterateOverEmitter(em, 'item') 27 | } 28 | 29 | module.exports = { iterateOfLimit } 30 | -------------------------------------------------------------------------------- /packages/request/commands/request/options/request/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | method: { 3 | alias: ['X'], 4 | type: 'string', 5 | describe: 'Custom method', 6 | }, 7 | 8 | header: { 9 | alias: ['H'], 10 | type: 'string', 11 | describe: 'Custom header', 12 | }, 13 | 14 | 'connect-timeout': { 15 | alias: ['t', 'timeout'], 16 | type: 'number', 17 | describe: 'Maximum time allowed for the connection to start', 18 | default: 30000, 19 | }, 20 | 21 | 'data-timeout': { 22 | alias: ['T'], 23 | type: 'number', 24 | describe: 'Maximum time allowed for the data to arrive', 25 | default: 30000, 26 | }, 27 | 28 | 'accept-unauthorized': { 29 | alias: ['k', 'insecure'], 30 | type: 'boolean', 31 | describe: 'Accept unauthorized TLS errors', 32 | default: false, 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /packages/async/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/async", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/async#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "publishConfig": { 25 | "access": "public", 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "scripts": { 29 | "test": "NODE_ENV=test npx -y mocha@latest" 30 | }, 31 | "dependencies": {} 32 | } 33 | -------------------------------------------------------------------------------- /packages/pown/bin/pown.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const boot = async () => { 4 | const path = require('path') 5 | const { 6 | ensurePreferencesFilename, 7 | getPreferencesDirectory, 8 | } = require('@pown/preferences') 9 | 10 | // stage1: setup pown root 11 | 12 | if (!process.env.POWN_ROOT) { 13 | process.env.POWN_ROOT = path.join(__dirname, '..') 14 | } 15 | 16 | // stage2: setup pown modules 17 | 18 | await ensurePreferencesFilename('modules', 'package.json') 19 | 20 | const dirname = getPreferencesDirectory('modules') 21 | 22 | process.env.POWN_PATH = [ 23 | dirname, 24 | ...(process.env.POWN_PATH ? [process.env.POWN_PATH] : []), 25 | ].join(path.delimiter) 26 | 27 | // stage4: launch 28 | 29 | require('@pown/cli/bin/cli') 30 | } 31 | 32 | boot().catch((error) => { 33 | console.error(error) 34 | 35 | process.exit(1) 36 | }) 37 | -------------------------------------------------------------------------------- /packages/async/lib/unrollOfLimit.js: -------------------------------------------------------------------------------- 1 | const { EventEmitter } = require('events') 2 | 3 | const { isIterable, isString } = require('./utils') 4 | const { eachOfLimit } = require('./eachOfLimit') 5 | const { iterateOverEmitter } = require('./iterateOverEmitter') 6 | 7 | const unrollOfLimit = async function* (iterables, limit = 1) { 8 | const ee = new EventEmitter() 9 | 10 | eachOfLimit( 11 | iterables, 12 | async (item) => { 13 | if (isIterable(item) && !isString(item)) { 14 | for await (let subitem of unrollOfLimit(item)) { 15 | ee.emit('item', subitem) 16 | } 17 | } else { 18 | ee.emit('item', item) 19 | } 20 | }, 21 | limit 22 | ) 23 | .then(() => ee.emit('end')) 24 | .catch((error) => ee.emit('error', error)) 25 | 26 | yield* iterateOverEmitter(ee, 'item') 27 | } 28 | 29 | module.exports = { unrollOfLimit } 30 | -------------------------------------------------------------------------------- /packages/pown/commands/update/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'update', 3 | describe: 'Update global installation of pown', 4 | aliases: ['upgrade', 'up', 'u'], 5 | 6 | builder: (yargs) => { 7 | yargs.option('development', { 8 | type: 'boolean', 9 | describe: 'Install development.', 10 | alias: ['d', 'dev'], 11 | default: false, 12 | }) 13 | }, 14 | 15 | handler: async (yargs) => { 16 | const { development } = yargs 17 | 18 | const util = require('util') 19 | const { spawn } = require('child_process') 20 | 21 | const spawnAsync = util.promisify(spawn) 22 | 23 | await spawnAsync( 24 | 'npm', 25 | [ 26 | 'install', 27 | '-g', 28 | 'pown@latest', 29 | ...(development ? [] : ['--production']), 30 | ], 31 | { shell: true, stdio: 'inherit' } 32 | ) 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/options/sub/set.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'set ', 3 | describe: 'Set option', 4 | aliases: ['s'], 5 | 6 | builder: (yargs) => { 7 | yargs.option('category', { 8 | alias: ['c'], 9 | type: 'string', 10 | describe: 'Select category', 11 | default: 'global', 12 | }) 13 | 14 | yargs.option('json', { 15 | alias: ['j'], 16 | type: 'boolean', 17 | describe: 'Assume the option is a json string', 18 | default: false, 19 | }) 20 | }, 21 | 22 | handler: (argv) => { 23 | const { options } = require('../../../lib/globals/options') 24 | 25 | const { category, json, name, value } = argv 26 | 27 | if (json) { 28 | options.setOption(category, name, JSON.parse(value)) 29 | } else { 30 | options.setOption(category, name, value) 31 | } 32 | }, 33 | } 34 | -------------------------------------------------------------------------------- /packages/async/README.md: -------------------------------------------------------------------------------- 1 | [![License](https://img.shields.io/badge/license-MIT-_red.svg)](https://opensource.org/licenses/MIT) 2 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 3 | ![NPM](https://img.shields.io/npm/v/@pown/async.svg) 4 | [![Fury](https://img.shields.io/badge/version-2x%20Fury-red.svg)](https://github.com/pownjs/lobby) 5 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 6 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 7 | 8 | # Pown Async 9 | 10 | Async is a collection of functions to help with asynchronous programing in PownJS and Node. See the `src/`, `test/` and `examples/` folders to learn how to use the library. Documentation is coming soon. 11 | 12 | > **WARNING**: This is a work in progress. There is no plan to keep this module backwards compatible. 13 | -------------------------------------------------------------------------------- /packages/engine/lib/entropy.js: -------------------------------------------------------------------------------- 1 | // see https://gist.github.com/ppseprus/afab8500dec6394c401734cb6922d220 2 | 3 | /** 4 | * 5 | * @param {string} chr 6 | * @param {string} str 7 | * @returns {number} 8 | */ 9 | const getCharacterFrequency = (chr, str) => { 10 | let c = 0 11 | let i = -1 12 | 13 | while ((i = str.indexOf(chr, i + 1)) >= 0) { 14 | c += 1 15 | } 16 | 17 | return c 18 | } 19 | 20 | /** 21 | * 22 | * @param {string} str 23 | * @returns {number} 24 | */ 25 | const calculateEntropy = (str) => { 26 | // TODO: make this forward compatible 27 | // @ts-ignore 28 | return ( 29 | [...new Set(str)] 30 | .map((chr) => getCharacterFrequency(chr, str)) 31 | .reduce((sum, frequency) => { 32 | const p = frequency / str.length 33 | 34 | return sum + p * Math.log2(1 / p) 35 | }, 0) * str.length 36 | ) 37 | } 38 | 39 | module.exports = { 40 | calculateEntropy, 41 | } 42 | -------------------------------------------------------------------------------- /packages/leaks/database/google.yaml: -------------------------------------------------------------------------------- 1 | title: Google Secrets 2 | checks: 3 | - title: Google Cloud Platform API key 4 | severity: 9 5 | regex: (google|gcp|youtube|drive|yt)(.{0,20})?['\"][AIza[0-9a-z\\-_]{35}]['\"] 6 | safe: false 7 | 8 | - title: Google (GCM) Service account 9 | severity: 9 10 | regex: "((\\\"|'|`)?type(\\\"|'|`)?\\\\s{0,50}(:|=>|=)\\\\s{0,50}(\\\"|'|`)?service_account(\\\"|'|`)?,?)" 11 | safe: false 12 | 13 | - title: Google API Key 14 | severity: 4 15 | regex: >- 16 | AIza[0-9a-zA-Z\-_]{35} 17 | 18 | - title: Google Oauth ID 19 | severity: 1 20 | regex: >- 21 | [0-9]+-[0-9a-z_]{32}\.apps\.googleusercontent\.com 22 | 23 | - title: Firebase Database URL 24 | severity: 1 25 | regex: >- 26 | https://[a-z0-9-_]+\.firebaseio.com 27 | text: 28 | valid: 29 | - >- 30 | databaseURL: 'https://bb-cat-bla.firebaseio.com', 31 | -------------------------------------------------------------------------------- /packages/recon/test/detect.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { isSubdomain, isSubdomainOf } = require('../lib/detect') 4 | 5 | describe('detect', () => { 6 | it('#isSubdomain', () => { 7 | assert.ok(!isSubdomain('acme.com'), 'acme.com is not subodmain') 8 | assert.ok(!!isSubdomain('sub.acme.com'), 'sub.acme.com is subodmain') 9 | }) 10 | 11 | it('#isSubdomainOf', () => { 12 | assert.ok( 13 | !isSubdomainOf( 14 | 'acme.com', 15 | 'acme.com', 16 | 'acme.com is not subdomain of acme.com' 17 | ) 18 | ) 19 | assert.ok( 20 | !!isSubdomainOf( 21 | 'sub.acme.com', 22 | 'acme.com', 23 | 'sub.acme.com is subdomain of acme.com' 24 | ) 25 | ) 26 | assert.ok( 27 | !isSubdomainOf( 28 | 'sub.test.com', 29 | 'acme.com', 30 | 'sub.test.com is not subdomain of acme.com' 31 | ) 32 | ) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /packages/script/commands/script/sub/js.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'js [script]', 3 | describe: 'Run js expression', 4 | 5 | builder: { 6 | expression: { 7 | describe: 'JavaScript expression', 8 | type: 'string', 9 | alias: ['e'], 10 | }, 11 | }, 12 | 13 | handler: async (argv) => { 14 | const { expression, script } = argv 15 | 16 | const main = async () => { 17 | if (expression) { 18 | await eval(expression) 19 | } else if (script) { 20 | const path = require('path') 21 | const { readFile } = require('fs') 22 | const { promisify } = require('util') 23 | 24 | const readFileAsync = promisify(readFile) 25 | 26 | const data = await readFileAsync( 27 | path.resolve(path.dirname(argv.context.file), script) 28 | ) 29 | 30 | await eval(data.toString()) 31 | } 32 | } 33 | 34 | await main() 35 | }, 36 | } 37 | -------------------------------------------------------------------------------- /packages/regexp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/regexp", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/regexp#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "browser": { 25 | "re2": false 26 | }, 27 | "publishConfig": { 28 | "access": "public", 29 | "registry": "https://registry.npmjs.org/" 30 | }, 31 | "scripts": { 32 | "test": "NODE_ENV=test npx -y mocha@latest" 33 | }, 34 | "dependencies": { 35 | "re2": "^1.15.9" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/engine/examples/analyzer.yaml: -------------------------------------------------------------------------------- 1 | id: permissive-cors 2 | 3 | analyzer: 4 | matchers: 5 | - type: word 6 | word: '*' 7 | part: responseHeaders['access-control-allow-origin'] 8 | 9 | - type: word 10 | word: 'true' 11 | part: responseHeaders['access-control-allow-credentials'] 12 | 13 | extractors: 14 | - type: value 15 | path: responseHeaders['access-control-allow-origin'] 16 | name: info.origin 17 | 18 | - type: value 19 | path: responseHeaders['access-control-allow-credentials'] 20 | name: info.credentials 21 | 22 | level: 1 23 | title: Permissive Cross-Origin Resource Sharing 24 | description: > 25 | Cross-origin Resource Sharing (CORS) is a specification, which allows 26 | Web applications the ability to offer its resources for public consumption 27 | from different domains. CORS is typically used in cross-origin APIs designed 28 | to be consumed by JavaScript applications. 29 | -------------------------------------------------------------------------------- /packages/engine/examples/workflow.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const jsYaml = require('js-yaml') 4 | 5 | const { Template } = require('../lib/template.js') 6 | const { ConsoleTracer } = require('../lib/trace.js') 7 | 8 | class WorkflowTemplate extends Template { 9 | async *runTaskSetIt(taskName, tasks, input = {}) { 10 | if (['op', 'ops', 'operation', 'operations'].includes(taskName)) { 11 | for (let task of tasks) { 12 | yield* this.runTaskDefinitionsIt(task, input) 13 | } 14 | } else { 15 | yield* super.runTaskSetIt(taskName, tasks, input) 16 | } 17 | } 18 | } 19 | 20 | const main = async () => { 21 | const document = jsYaml.load( 22 | fs.readFileSync(path.join(__dirname, 'workflow.yaml')).toString() 23 | ) 24 | const template = new WorkflowTemplate(document, { 25 | tracer: new ConsoleTracer(), 26 | }) 27 | 28 | await template.run() 29 | } 30 | 31 | main().catch(console.error) 32 | -------------------------------------------------------------------------------- /packages/async/lib/eachOfLimit.js: -------------------------------------------------------------------------------- 1 | const { Semaphore } = require('./semaphore') 2 | 3 | const eachOfLimit = async (iterable, handler, limit = 1) => { 4 | if (typeof limit === 'function') { 5 | ;[handler, limit] = [limit, handler] 6 | } 7 | 8 | const semaphore = new Semaphore(limit) 9 | 10 | const errors = [] 11 | 12 | try { 13 | for await (const item of iterable) { 14 | const release = await semaphore.acquire() 15 | 16 | release(handler(item)).catch((e) => errors.push(e)) 17 | 18 | if (errors.length) { 19 | break // NOTE: bailout as soon as we know there are errors 20 | } 21 | } 22 | } catch (e) { 23 | errors.push(e) 24 | } 25 | 26 | await semaphore.join() 27 | 28 | if (errors.length) { 29 | if (typeof AggregateError === 'function') { 30 | throw new AggregateError(errors) // eslint-disable-line 31 | } else { 32 | throw errors[0] 33 | } 34 | } 35 | } 36 | 37 | module.exports = { eachOfLimit } 38 | -------------------------------------------------------------------------------- /packages/async/lib/utils.js: -------------------------------------------------------------------------------- 1 | function isIterable(obj) { 2 | if (!obj) { 3 | return false 4 | } 5 | 6 | return ( 7 | typeof obj[Symbol.iterator] === 'function' || 8 | typeof obj[Symbol.asyncIterator] === 'function' 9 | ) 10 | } 11 | 12 | function isSyncIterable(obj) { 13 | if (!obj) { 14 | return false 15 | } 16 | 17 | return typeof obj[Symbol.asyncIterator] === 'function' 18 | } 19 | 20 | function isAsyncIterable(obj) { 21 | if (!obj) { 22 | return false 23 | } 24 | 25 | return typeof obj[Symbol.asyncIterator] === 'function' 26 | } 27 | 28 | function isString(obj) { 29 | return typeof obj === 'string' || obj instanceof String 30 | } 31 | 32 | async function toArray(iterable) { 33 | const items = [] 34 | 35 | for await (let item of iterable) { 36 | items.push(item) 37 | } 38 | 39 | return items 40 | } 41 | 42 | module.exports = { 43 | isIterable, 44 | isSyncIterable, 45 | isAsyncIterable, 46 | isString, 47 | toArray, 48 | } 49 | -------------------------------------------------------------------------------- /packages/modules/commands/modules/sub/list.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'list', 3 | describe: 'List install modules', 4 | aliases: ['ls', 'l'], 5 | 6 | builder: (yargs) => { 7 | yargs.option('depth', { 8 | type: 'number', 9 | describe: 'List depth.', 10 | alias: ['d'], 11 | default: 0, 12 | }) 13 | }, 14 | 15 | handler: async (yargs) => { 16 | const { depth = 0 } = yargs 17 | 18 | const util = require('util') 19 | const { spawn } = require('child_process') 20 | const { 21 | ensurePreferencesFilename, 22 | getPreferencesDirectory, 23 | } = require('@pown/preferences') 24 | 25 | const spawnAsync = util.promisify(spawn) 26 | 27 | await ensurePreferencesFilename('modules', 'package.json') 28 | 29 | const dirname = getPreferencesDirectory('modules') 30 | 31 | await spawnAsync('npm', ['list', '--depth', depth], { 32 | shell: true, 33 | stdio: 'inherit', 34 | cwd: dirname, 35 | }) 36 | }, 37 | } 38 | -------------------------------------------------------------------------------- /packages/engine/examples/request.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const jsYaml = require('js-yaml') 4 | const { request } = require('@pown/request') 5 | 6 | const { Template } = require('../lib/template.js') 7 | const { ConsoleTracer } = require('../lib/trace.js') 8 | 9 | class RequestTemplate extends Template { 10 | async executeTask(taskName, task, input = {}) { 11 | if (taskName === 'request') { 12 | const { url, uri = url, ...req } = task 13 | 14 | return request({ ...req, uri: this.interpolate(uri, input) }) 15 | } 16 | 17 | throw new Error(`Unrecognized task ${taskName}`) 18 | } 19 | } 20 | 21 | const main = async () => { 22 | const document = jsYaml.load( 23 | fs.readFileSync(path.join(__dirname, 'request.yaml')).toString() 24 | ) 25 | const template = new RequestTemplate(document, { 26 | tracer: new ConsoleTracer(), 27 | }) 28 | 29 | await template.run({ hostname: 'httpbin.org' }) 30 | } 31 | 32 | main().catch(console.error) 33 | -------------------------------------------------------------------------------- /packages/recon/transforms/omnisint/index.js: -------------------------------------------------------------------------------- 1 | const { SubdomainTransform } = require('../../lib//common') 2 | 3 | const { DOMAIN_TYPE } = require('../../lib//types') 4 | 5 | class OmnisintSubdomainReport extends SubdomainTransform { 6 | static alias = ['omnisint_subdomain_report'] 7 | 8 | static title = 'Omnisint Subdomain Report' 9 | 10 | static description = 11 | 'Obtain omnisint domain report which helps enumerating target subdomains' 12 | 13 | static types = [DOMAIN_TYPE] 14 | 15 | static group = 'Omnisint Subdomain Report' 16 | 17 | static tags = ['ce'] 18 | 19 | static options = {} 20 | 21 | static priority = 1 22 | 23 | static noise = 1 24 | 25 | async getResults(domain) { 26 | const json = await this.scheduler.tryRequest({ 27 | uri: `https://sonar.omnisint.io/subdomains/${domain}`, 28 | toJson: true, 29 | }) 30 | 31 | return { 32 | subdomains: [...new Set(json)].map((subdomain) => ({ subdomain })), 33 | } 34 | } 35 | } 36 | 37 | module.exports = { OmnisintSubdomainReport } 38 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/lib/globals/recon.js: -------------------------------------------------------------------------------- 1 | const { Bar } = require('@pown/cli/lib/bar') 2 | 3 | const { Recon } = require('../../../../lib/recon') 4 | 5 | const recon = new Recon() 6 | 7 | recon.on('info', console.info.bind(console)) 8 | recon.on('warn', console.warn.bind(console)) 9 | recon.on('error', console.error.bind(console)) 10 | recon.on('debug', console.debug.bind(console)) 11 | 12 | // TODO: show internal-error 13 | 14 | const bars = {} 15 | 16 | recon.on('barStart', (name, { total = 0 }) => { 17 | if (total < 1000) { 18 | return 19 | } 20 | 21 | const bar = new Bar() 22 | 23 | bar.start(total, 0) 24 | 25 | bars[name] = bar 26 | }) 27 | 28 | recon.on('barStep', (name, { step = 0 }) => { 29 | const bar = bars[name] 30 | 31 | if (!bar) { 32 | return 33 | } 34 | 35 | bar.update(step) 36 | }) 37 | 38 | recon.on('barEnd', (name) => { 39 | const bar = bars[name] 40 | 41 | if (!bar) { 42 | return 43 | } 44 | 45 | bar.stop() 46 | 47 | delete bars[name] 48 | }) 49 | 50 | module.exports = { recon } 51 | -------------------------------------------------------------------------------- /packages/preferences/test/preferences.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { getPreferences, setPreferences } = require('../lib') 4 | 5 | describe('getPreferences', () => { 6 | it('must not error', (done) => { 7 | getPreferences('test', (err, prefs) => { 8 | assert.ok(!err) 9 | assert.ok(prefs) 10 | 11 | done() 12 | }) 13 | }) 14 | 15 | it('must not error (async/await)', async () => { 16 | let prefs 17 | 18 | try { 19 | prefs = getPreferences('test') 20 | } catch (err) { 21 | async.ok(!err) 22 | 23 | return 24 | } 25 | 26 | assert.ok(prefs) 27 | }) 28 | }) 29 | 30 | describe('setPreferences', () => { 31 | it('must not error', (done) => { 32 | setPreferences('test', { test: 123 }, (err) => { 33 | assert.ok(!err) 34 | 35 | done() 36 | }) 37 | }) 38 | 39 | it('must not error (async/await)', async () => { 40 | try { 41 | setPreferences('test', { test: 123 }) 42 | } catch (err) { 43 | async.ok(!err) 44 | } 45 | }) 46 | }) 47 | -------------------------------------------------------------------------------- /packages/async/test/unrollOfLimit.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { sleep } = require('../lib/sleep') 4 | const { unrollOfLimit } = require('../lib/unrollOfLimit') 5 | 6 | describe('unrollOfLimit', () => { 7 | it('produces the correct numbers', async () => { 8 | const generators = [[0], [1], [2]] 9 | 10 | const items = [] 11 | 12 | for await (const item of unrollOfLimit(generators)) { 13 | items.push(item) 14 | } 15 | 16 | items.sort() 17 | 18 | assert.deepEqual(items, [0, 1, 2], 'items are 0, 1, 2') 19 | }) 20 | 21 | it('produces the correct numbers with delays', async () => { 22 | const gen = async function* (t, i) { 23 | await sleep(t) 24 | 25 | yield i 26 | } 27 | 28 | const generators = [gen(1, 0), gen(500, 1), gen(1, 2)] 29 | 30 | const items = [] 31 | 32 | for await (const item of unrollOfLimit(generators)) { 33 | items.push(item) 34 | } 35 | 36 | items.sort() 37 | 38 | assert.deepEqual(items, [0, 1, 2], 'items are 0, 1, 2') 39 | }).timeout(1000) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/leaks/scripts/generate-database.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const jsYaml = require('js-yaml') 4 | 5 | const databaseRoot = path.join(__dirname, '..', 'database') 6 | 7 | const db = {} 8 | 9 | for (let file of fs.readdirSync(databaseRoot)) { 10 | const { 11 | title, 12 | variables = {}, 13 | checks = [], 14 | } = jsYaml.load(fs.readFileSync(path.join(databaseRoot, file)).toString()) 15 | 16 | for (let check of checks) { 17 | Object.entries(variables).forEach(([name, value]) => { 18 | if (check.regex) { 19 | check.regex = check.regex.split('${' + name + '}').join(value) 20 | } 21 | 22 | if (check.filterRegex) { 23 | check.filterRegex = check.filterRegex 24 | .split('${' + name + '}') 25 | .join(value) 26 | } 27 | }) 28 | 29 | delete check.tests 30 | } 31 | 32 | db[path.basename(file, '.yaml')] = { title, checks } 33 | } 34 | 35 | fs.writeFileSync( 36 | path.join(__dirname, '..', 'lib', 'database.json'), 37 | JSON.stringify(db, '', ' ') 38 | ) 39 | -------------------------------------------------------------------------------- /packages/async/test/unrollOfParallel.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { sleep } = require('../lib/sleep') 4 | const { unrollOfParallel } = require('../lib/unrollOfParallel') 5 | 6 | describe('unrollOfParallel', () => { 7 | it('produces the correct numbers', async () => { 8 | const generators = [[0], [1], [2]] 9 | 10 | const items = [] 11 | 12 | for await (const item of unrollOfParallel(generators)) { 13 | items.push(item) 14 | } 15 | 16 | items.sort() 17 | 18 | assert.deepEqual(items, [0, 1, 2], 'items are 0, 1, 2') 19 | }) 20 | 21 | it('produces the correct numbers with delays', async () => { 22 | const gen = async function* (t, i) { 23 | await sleep(t) 24 | 25 | yield i 26 | } 27 | 28 | const generators = [gen(1, 0), gen(500, 1), gen(1, 2)] 29 | 30 | const items = [] 31 | 32 | for await (const item of unrollOfParallel(generators)) { 33 | items.push(item) 34 | } 35 | 36 | items.sort() 37 | 38 | assert.deepEqual(items, [0, 1, 2], 'items are 0, 1, 2') 39 | }).timeout(1000) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/show/sub/selected.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'selected', 3 | describe: 'Show what is selected', 4 | aliases: ['s'], 5 | 6 | builder: (yargs) => { 7 | const { 8 | installReadOptions, 9 | installWriteOptions, 10 | } = require('../../../lib/handlers/file') 11 | 12 | installReadOptions(yargs) 13 | installWriteOptions(yargs) 14 | 15 | const { installOutputOptions } = require('../../../lib/handlers/output') 16 | 17 | installOutputOptions(yargs) 18 | }, 19 | 20 | handler: async (argv) => { 21 | const { recon } = require('../../../lib/globals/recon') 22 | 23 | const { 24 | handleReadOptions, 25 | handleWriteOptions, 26 | } = require('../../../lib/handlers/file') 27 | 28 | await handleReadOptions(argv, recon) 29 | 30 | const resultNodes = recon.selection.map((node) => node.data()) 31 | 32 | await handleWriteOptions(argv, recon) 33 | 34 | const { handleOutputOptions } = require('../../../lib/handlers/output') 35 | 36 | await handleOutputOptions(argv, resultNodes) 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /packages/async/test/semaphore.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { sleep } = require('../lib/sleep') 4 | const { Semaphore } = require('../lib/semaphore') 5 | 6 | describe('semaphore', () => { 7 | describe('#acquire', () => { 8 | it('acquires at 1 room', async () => { 9 | const semaphore = new Semaphore(1) 10 | 11 | const r1 = await semaphore.acquire() 12 | 13 | r1() 14 | 15 | const r2 = await semaphore.acquire() 16 | 17 | r2() 18 | 19 | const r3 = await semaphore.acquire() 20 | 21 | r3() 22 | 23 | assert.ok(true, 'done') 24 | }) 25 | }) 26 | 27 | describe('#acquire', () => { 28 | it('acquires at 1 room with release promises', async () => { 29 | const semaphore = new Semaphore(1) 30 | 31 | const r1 = await semaphore.acquire() 32 | 33 | r1(sleep(300)) 34 | 35 | const r2 = await semaphore.acquire() 36 | 37 | r2(sleep(300)) 38 | 39 | const r3 = await semaphore.acquire() 40 | 41 | r3(sleep(300)) 42 | 43 | assert.ok(true, 'done') 44 | }).timeout(1000) 45 | }) 46 | }) 47 | -------------------------------------------------------------------------------- /packages/credits/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/credits", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/credits#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "publishConfig": { 25 | "access": "public", 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "scripts": { 29 | "start": "POWN_ROOT=. pown-cli", 30 | "test": "NODE_ENV=test npx -y mocha@latest" 31 | }, 32 | "pown": { 33 | "commands": [ 34 | "commands/credits/index.js" 35 | ] 36 | }, 37 | "peerDependencies": { 38 | "@pown/cli": "*" 39 | }, 40 | "devDependencies": { 41 | "@pown/cli": "*" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/recon/examples/permissive-cors-1.yaml: -------------------------------------------------------------------------------- 1 | id: permissive-cors 2 | 3 | add: 4 | select: node[type="uri"] 5 | 6 | matchers: 7 | - type: word 8 | word: '*' 9 | part: props.responseHeaders['access-control-allow-origin'] 10 | 11 | - type: word 12 | word: 'true' 13 | part: props.responseHeaders['access-control-allow-credentials'] 14 | 15 | extractors: 16 | - type: value 17 | path: props.responseHeaders['access-control-allow-origin'] 18 | name: props.origin 19 | 20 | - type: value 21 | path: props.responseHeaders['access-control-allow-credentials'] 22 | name: props.credentials 23 | 24 | type: issue 25 | label: Permissive Cross-Origin Resource Sharing 26 | props: 27 | level: 1 28 | title: Permissive Cross-Origin Resource Sharing 29 | description: > 30 | Cross-origin Resource Sharing (CORS) is a specification, which allows 31 | Web applications the ability to offer its resources for public consumption 32 | from different domains. CORS is typically used in cross-origin APIs designed 33 | to be consumed by JavaScript applications. 34 | -------------------------------------------------------------------------------- /packages/script/README.md: -------------------------------------------------------------------------------- 1 | [![Follow on Twitter](https://img.shields.io/twitter/follow/pownjs.svg?logo=twitter)](https://twitter.com/pownjs) 2 | [![NPM](https://img.shields.io/npm/v/pown.svg)](https://www.npmjs.com/package/pown) 3 | [![Fury](https://img.shields.io/badge/version-3x%20Rage-red.svg)](https://github.com/pownjs/lobby) 4 | ![default workflow](https://github.com/pownjs/git/actions/workflows/default.yaml/badge.svg) 5 | [![SecApps](https://img.shields.io/badge/credits-SecApps-black.svg)](https://secapps.com) 6 | 7 | # Pown Script 8 | 9 | Pown Script is a simple scripting environment. The key advantage of using Pown Script instead of Bash, Python, Perl, etc, is because all commands are executed within the same VM context (same process). Commands such as [Pown Recon](https://github.com/pownjs/pown-script) take advantage of this by keeping a global model of its graph, thus, removing the need to save into intermediate files upon each command execution. 10 | 11 | Pown Script implements some some standard commands such as `echo`, `sleep` and even `set`. This is done for interoperability. Every pown script is also a valid bash script. 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/async/lib/semaphore.js: -------------------------------------------------------------------------------- 1 | const { Mutex } = require('./mutex') 2 | 3 | class Semaphore { 4 | constructor(rooms = 1) { 5 | this.rooms = rooms 6 | this.tasks = {} 7 | 8 | this.internalId = 0 9 | } 10 | 11 | async acquire() { 12 | while (Object.keys(this.tasks).length >= this.rooms) { 13 | await Promise.race(Object.values(this.tasks)) 14 | } 15 | 16 | const taskId = (this.internalId += 1) 17 | 18 | const task = new Mutex() 19 | 20 | this.tasks[taskId] = task.lock() 21 | 22 | return async (promise) => { 23 | try { 24 | if (promise) { 25 | if (typeof promise === 'function') { 26 | await promise() 27 | } else { 28 | await promise 29 | } 30 | } 31 | } finally { 32 | delete this.tasks[taskId] 33 | 34 | task.unlock(taskId) 35 | } 36 | } 37 | } 38 | 39 | async join() { 40 | for (;;) { 41 | await Promise.all(Object.values(this.tasks)) 42 | 43 | if (!this.tasks.size) { 44 | break 45 | } 46 | } 47 | } 48 | } 49 | 50 | module.exports = { Semaphore } 51 | -------------------------------------------------------------------------------- /packages/preferences/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/preferences", 3 | "version": "3.12.1", 4 | "description": "Pownage preference", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/preferences#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "publishConfig": { 25 | "access": "public", 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "scripts": { 29 | "start": "POWN_ROOT=. pown-cli", 30 | "test": "NODE_ENV=test npx -y mocha@latest" 31 | }, 32 | "pown": { 33 | "commands": [ 34 | "commands/preferences/index.js" 35 | ] 36 | }, 37 | "peerDependencies": { 38 | "@pown/cli": "*" 39 | }, 40 | "devDependencies": { 41 | "@pown/cli": "*" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/traverse/sub/traverse.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: '$0 ', 3 | 4 | builder: (yargs) => { 5 | const { 6 | installReadOptions, 7 | installWriteOptions, 8 | } = require('../../../lib/handlers/file') 9 | 10 | installReadOptions(yargs) 11 | installWriteOptions(yargs) 12 | 13 | const { installOutputOptions } = require('../../../lib/handlers/output') 14 | 15 | installOutputOptions(yargs) 16 | }, 17 | 18 | handler: async (argv) => { 19 | const { expressions } = argv 20 | 21 | const { recon } = require('../../../lib/globals/recon') 22 | 23 | const { 24 | handleReadOptions, 25 | handleWriteOptions, 26 | } = require('../../../lib/handlers/file') 27 | 28 | await handleReadOptions(argv, recon) 29 | 30 | const resultNodes = recon 31 | .traverse(...expressions) 32 | .map((node) => node.data()) 33 | 34 | await handleWriteOptions(argv, recon) 35 | 36 | const { handleOutputOptions } = require('../../../lib/handlers/output') 37 | 38 | await handleOutputOptions(argv, resultNodes) 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/select/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'select ', 3 | describe: 'Select nodes', 4 | aliases: ['s'], 5 | 6 | builder: (yargs) => { 7 | const { 8 | installReadOptions, 9 | installWriteOptions, 10 | } = require('../../lib/handlers/file') 11 | 12 | installReadOptions(yargs) 13 | installWriteOptions(yargs) 14 | 15 | const { installOutputOptions } = require('../../lib/handlers/output') 16 | 17 | installOutputOptions(yargs) 18 | }, 19 | 20 | handler: async (argv) => { 21 | const { expressions } = argv 22 | 23 | const { recon } = require('../../lib/globals/recon') 24 | 25 | const { 26 | handleReadOptions, 27 | handleWriteOptions, 28 | } = require('../../lib/handlers/file') 29 | 30 | await handleReadOptions(argv, recon) 31 | 32 | const resultNodes = recon.select(...expressions).map((node) => node.data()) 33 | 34 | await handleWriteOptions(argv, recon) 35 | 36 | const { handleOutputOptions } = require('../../lib/handlers/output') 37 | 38 | await handleOutputOptions(argv, resultNodes) 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /packages/async/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/cli/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/connect/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/credits/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/engine/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/lau/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/leaks/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/modules/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/pown/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/recon/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/regexp/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/request/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/script/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/shell/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/preferences/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pownjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/connect/commands/connect/options/output/handler.js: -------------------------------------------------------------------------------- 1 | const { writeFile } = require('fs') 2 | const { promisify } = require('util') 3 | 4 | const writeFileAsync = promisify(writeFile) 5 | 6 | const init = (options, scheduler) => { 7 | const { contentSniffSize, printResponseData, downloadResponseData } = options 8 | 9 | scheduler.on('connect-finished', (request, response) => { 10 | const { host, port, responseData, info } = response 11 | 12 | const responseDataSniff = responseData 13 | .slice(0, contentSniffSize) 14 | .toString('base64') 15 | 16 | console.info( 17 | `${host}:${port} -> ${info.open ? 'open' : 'closed'} ${ 18 | responseData.length 19 | } ${responseDataSniff ? responseDataSniff : '-'}` 20 | ) 21 | 22 | if (printResponseData) { 23 | console.log(responseData.toString()) 24 | } 25 | 26 | if (downloadResponseData) { 27 | writeFileAsync( 28 | `${host}:${port}` 29 | .replace(/\W+/g, '_') 30 | .replace(/_+/, '_') 31 | .replace(/([a-zA-Z0-9]+)$/, '.$1'), 32 | responseData 33 | ) 34 | } 35 | }) 36 | } 37 | 38 | module.exports = { init } 39 | -------------------------------------------------------------------------------- /packages/script/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/script", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/script#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "publishConfig": { 25 | "access": "public", 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "scripts": { 29 | "start": "POWN_ROOT=. pown-cli", 30 | "test": "NODE_ENV=test npx -y mocha@latest" 31 | }, 32 | "pown": { 33 | "commands": [ 34 | "commands/script/index.js" 35 | ] 36 | }, 37 | "peerDependencies": { 38 | "@pown/cli": "*", 39 | "@pown/modules": "*" 40 | }, 41 | "devDependencies": { 42 | "@pown/cli": "*", 43 | "@pown/modules": "*" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/cli", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/cli#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "bin": { 24 | "pown-cli": "bin/cli.js" 25 | }, 26 | "main": "lib/index.js", 27 | "publishConfig": { 28 | "access": "public", 29 | "registry": "https://registry.npmjs.org/" 30 | }, 31 | "scripts": { 32 | "test": "NODE_ENV=test npx -y mocha@latest" 33 | }, 34 | "dependencies": { 35 | "@pown/modules": "*", 36 | "are-we-there-yet": "^1.1.5", 37 | "chalk": "^2.4.2", 38 | "cli-progress": "^2.1.1", 39 | "cli-table3": "^0.5.1", 40 | "inquirer": "^6.5.2", 41 | "wordwrap": "^1.0.0", 42 | "yargs": "^17.6.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/lau/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/lau", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/lau#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "publishConfig": { 25 | "access": "public", 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "scripts": { 29 | "start": "POWN_ROOT=. pown-cli", 30 | "test": "NODE_ENV=test npx -y mocha@latest" 31 | }, 32 | "pown": { 33 | "commands": [ 34 | "commands/lau" 35 | ] 36 | }, 37 | "dependencies": { 38 | "@pown/async": "*", 39 | "@pown/request": "*" 40 | }, 41 | "peerDependencies": { 42 | "@pown/cli": "*" 43 | }, 44 | "devDependencies": { 45 | "@pown/cli": "*" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/recon/lib/common.js: -------------------------------------------------------------------------------- 1 | const { isDomain } = require('./detect') 2 | const { Transform } = require('./transform') 3 | const { normalizeDomain } = require('./normalize') 4 | const { DOMAIN_TYPE, SUBDOMAIN_TYPE } = require('./types') 5 | 6 | class SubdomainTransform extends Transform { 7 | async handle({ id: source = '', label = '' }) { 8 | let { subdomains, ...rest } = await this.getResults(label) 9 | 10 | const results = subdomains 11 | .filter(({ subdomain }) => subdomain) 12 | .map(({ subdomain, ...props }) => ({ 13 | subdomain: normalizeDomain(subdomain), 14 | ...props, 15 | })) 16 | .filter( 17 | ({ subdomain }) => 18 | subdomain && isDomain(subdomain) && subdomain.endsWith(`.${label}`) 19 | ) 20 | .map(({ subdomain, ...props }) => ({ 21 | type: DOMAIN_TYPE, 22 | label: subdomain, 23 | props: { domain: subdomain, ...props }, 24 | edges: [{ source, type: SUBDOMAIN_TYPE }], 25 | })) 26 | 27 | results.push(...Object.values(rest).filter((value) => Array.isArray(value))) 28 | 29 | return results 30 | } 31 | } 32 | 33 | module.exports = { SubdomainTransform } 34 | -------------------------------------------------------------------------------- /packages/recon/examples/permissive-cors-2.yaml: -------------------------------------------------------------------------------- 1 | id: permissive-cors 2 | 3 | select: 4 | select: node[type="uri"] 5 | 6 | add: 7 | matchers: 8 | - type: word 9 | word: '*' 10 | part: props.responseHeaders['access-control-allow-origin'] 11 | 12 | - type: word 13 | word: 'true' 14 | part: props.responseHeaders['access-control-allow-credentials'] 15 | 16 | extractors: 17 | - type: value 18 | path: props.responseHeaders['access-control-allow-origin'] 19 | name: props.origin 20 | 21 | - type: value 22 | path: props.responseHeaders['access-control-allow-credentials'] 23 | name: props.credentials 24 | 25 | type: issue 26 | label: Permissive Cross-Origin Resource Sharing 27 | props: 28 | level: 1 29 | title: Permissive Cross-Origin Resource Sharing 30 | description: > 31 | Cross-origin Resource Sharing (CORS) is a specification, which allows 32 | Web applications the ability to offer its resources for public consumption 33 | from different domains. CORS is typically used in cross-origin APIs designed 34 | to be consumed by JavaScript applications. 35 | -------------------------------------------------------------------------------- /packages/engine/lib/async.js: -------------------------------------------------------------------------------- 1 | // TODO: these needs to be move into the async module for better reusability 2 | 3 | /** 4 | * @typedef {(any: any) => boolean|Promise} Handler 5 | */ 6 | 7 | /** 8 | * @param {Iterable} it 9 | * @param {Handler} handler 10 | * @returns {Promise} 11 | */ 12 | const asyncEvery = async (it, handler) => { 13 | for await (let e of it) { 14 | if (!(await handler(e))) { 15 | return false 16 | } 17 | } 18 | 19 | return true 20 | } 21 | 22 | /** 23 | * @param {Iterable} it 24 | * @param {Handler} handler 25 | * @returns {Promise} 26 | */ 27 | const asyncSome = async (it, handler) => { 28 | for await (let e of it) { 29 | if (await handler(e)) { 30 | return true 31 | } 32 | } 33 | 34 | return false 35 | } 36 | 37 | /** 38 | * @param {Iterable} it 39 | * @param {Handler} handler 40 | * @returns {Promise} 41 | */ 42 | const asyncNone = async (it, handler) => { 43 | for await (let e of it) { 44 | if (await handler(e)) { 45 | return false 46 | } 47 | } 48 | 49 | return true 50 | } 51 | 52 | module.exports = { 53 | asyncEvery, 54 | asyncSome, 55 | asyncNone, 56 | } 57 | -------------------------------------------------------------------------------- /packages/shell/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/shell", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/shell#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "publishConfig": { 25 | "access": "public", 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "scripts": { 29 | "start": "POWN_ROOT=. pown-cli", 30 | "test": "NODE_ENV=test npx -y mocha@latest" 31 | }, 32 | "pown": { 33 | "commands": [ 34 | "commands/shell" 35 | ] 36 | }, 37 | "peerDependencies": { 38 | "@pown/cli": "*", 39 | "@pown/modules": "*", 40 | "@pown/script": "*" 41 | }, 42 | "devDependencies": { 43 | "@pown/cli": "*", 44 | "@pown/modules": "*", 45 | "@pown/script": "*" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/engine/lib/trace.js: -------------------------------------------------------------------------------- 1 | const util = require('util') 2 | 3 | /** 4 | * @typedef {{ 5 | * message: string 6 | * data: Record 7 | * ts: number 8 | * }} TraceStep 9 | */ 10 | 11 | class Tracer { 12 | constructor() { 13 | this.trace = /** @type {TraceStep[]} */ ([]) 14 | } 15 | 16 | /** 17 | * 18 | * @param {string} message 19 | * @param {Record} [data] 20 | */ 21 | push(message, data = {}) { 22 | this.trace.push({ message, data, ts: Date.now() }) 23 | } 24 | 25 | /** 26 | * 27 | * returns {TraceStep[]} 28 | */ 29 | getTrace() { 30 | return this.trace 31 | } 32 | } 33 | 34 | class ConsoleTracer extends Tracer { 35 | /** 36 | * 37 | * @param {string} message 38 | * @param {Record} [data] 39 | */ 40 | push(message, data = {}) { 41 | if (process.env.DEBUG) { 42 | console.debug( 43 | `* [${Date.now()}]`, 44 | message, 45 | util.inspect(data, { colors: true, depth: Infinity }) 46 | ) 47 | } else { 48 | console.info(`* [${Date.now()}]`, message) 49 | } 50 | 51 | super.push(message, data) 52 | } 53 | } 54 | 55 | module.exports = { 56 | Tracer, 57 | ConsoleTracer, 58 | } 59 | -------------------------------------------------------------------------------- /packages/modules/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/modules", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/modules#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework", 22 | "modules" 23 | ], 24 | "main": "lib/index.js", 25 | "publishConfig": { 26 | "access": "public", 27 | "registry": "https://registry.npmjs.org/" 28 | }, 29 | "scripts": { 30 | "start": "POWN_ROOT=. pown-cli", 31 | "test": "NODE_ENV=test npx -y mocha@latest" 32 | }, 33 | "pown": { 34 | "commands": [ 35 | "commands/modules" 36 | ] 37 | }, 38 | "dependencies": { 39 | "@pown/preferences": "*", 40 | "read-package-tree": "^5.2.1" 41 | }, 42 | "peerDependencies": { 43 | "@pown/cli": "*" 44 | }, 45 | "devDependencies": { 46 | "@pown/cli": "*" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/remote/add.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'add ', 3 | describe: 'Add remote', 4 | aliases: ['a'], 5 | 6 | handler: async (argv) => { 7 | const { uris } = argv 8 | 9 | const { getPreferences, setPreferences } = require('@pown/preferences') 10 | 11 | const { fetchRemoteTransforms } = require('../../../../lib/remote') 12 | 13 | const preferences = await getPreferences('recon') 14 | 15 | preferences.remotes = { 16 | ...preferences.remotes, 17 | 18 | ...Object.assign( 19 | {}, 20 | ...(await Promise.all( 21 | uris.map(async (uri) => { 22 | const transforms = await fetchRemoteTransforms(uri) 23 | 24 | console.group(uri) 25 | 26 | Object.entries(transforms).forEach(([name, def]) => { 27 | console.table( 28 | [{ ...def, name }], 29 | ['name', 'title', 'description'] 30 | ) 31 | }) 32 | 33 | console.groupEnd() 34 | 35 | return { 36 | [uri]: transforms, 37 | } 38 | }) 39 | )) 40 | ), 41 | } 42 | 43 | await setPreferences('recon', preferences) 44 | }, 45 | } 46 | -------------------------------------------------------------------------------- /packages/async/lib/iterateOverEmitter.js: -------------------------------------------------------------------------------- 1 | const { PassThrough } = require('stream') 2 | 3 | const iterateOverEmitter = async function* ( 4 | emitter, 5 | yieldEvent, 6 | handler, 7 | options 8 | ) { 9 | if (typeof handler !== 'function') { 10 | options = handler 11 | handler = undefined 12 | } 13 | 14 | const { errorEvent = 'error', endEvent = 'end' } = options || {} 15 | 16 | if (!handler) { 17 | handler = (chunk) => chunk 18 | } 19 | 20 | const stream = new PassThrough({ objectMode: true }) 21 | 22 | const yieldEventHandler = (i) => { 23 | stream.write(i) 24 | } 25 | 26 | const errorEventHandler = (e) => { 27 | stream.emit('error', e) 28 | } 29 | 30 | const endEventHandler = () => { 31 | stream.end() 32 | } 33 | 34 | emitter.on(yieldEvent, yieldEventHandler) 35 | emitter.on(errorEvent, errorEventHandler) 36 | emitter.on(endEvent, endEventHandler) 37 | 38 | try { 39 | for await (const chunk of stream) { 40 | yield await handler(chunk) 41 | } 42 | } finally { 43 | emitter.off(yieldEvent, yieldEventHandler) 44 | emitter.off(errorEvent, errorEventHandler) 45 | emitter.off(endEvent, endEventHandler) 46 | } 47 | } 48 | 49 | module.exports = { iterateOverEmitter } 50 | -------------------------------------------------------------------------------- /packages/engine/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/engine", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/engine#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "publishConfig": { 25 | "access": "public", 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "scripts": { 29 | "check": "npx -y -p typescript tsc", 30 | "test": "NODE_ENV=test npx -y mocha@latest" 31 | }, 32 | "types": "types/index.d.ts", 33 | "dependencies": { 34 | "@pown/regexp": "*", 35 | "deepmerge": "^4.2.2", 36 | "jsonpath": "^1.1.1", 37 | "nightly-esprima": "^2021.8.30", 38 | "static-eval": "^2.1.0" 39 | }, 40 | "devDependencies": { 41 | "@pown/request": "*", 42 | "@types/mocha": "^10.0.0", 43 | "@types/node": "^18.8.5", 44 | "js-yaml": "^4.1.0" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'recon ', 3 | describe: 'Target recon', 4 | 5 | builder: (yargs) => { 6 | yargs.command(require('./sub/transform').yargs) 7 | yargs.command(require('./sub/template').yargs) 8 | yargs.command(require('./sub/select').yargs) 9 | yargs.command(require('./sub/traverse').yargs) 10 | yargs.command(require('./sub/options').yargs) 11 | yargs.command(require('./sub/cache').yargs) 12 | yargs.command(require('./sub/add').yargs) 13 | yargs.command(require('./sub/remove').yargs) 14 | yargs.command(require('./sub/edit').yargs) 15 | yargs.command(require('./sub/show').yargs) 16 | yargs.command(require('./sub/merge').yargs) 17 | yargs.command(require('./sub/diff').yargs) 18 | yargs.command(require('./sub/group').yargs) 19 | yargs.command(require('./sub/ungroup').yargs) 20 | yargs.command(require('./sub/load').yargs) 21 | yargs.command(require('./sub/save').yargs) 22 | yargs.command(require('./sub/import').yargs) 23 | yargs.command(require('./sub/export').yargs) 24 | yargs.command(require('./sub/remote').yargs) 25 | yargs.command(require('./sub/layout').yargs) 26 | yargs.command(require('./sub/summary').yargs) 27 | yargs.command(require('./sub/exec').yargs) 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /packages/connect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/connect", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/connect#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "exploit", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "publishConfig": { 25 | "access": "public", 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "scripts": { 29 | "start": "POWN_ROOT=. pown-cli", 30 | "test": "NODE_ENV=test npx -y mocha@latest" 31 | }, 32 | "pown": { 33 | "commands": [ 34 | "commands/connect" 35 | ] 36 | }, 37 | "dependencies": { 38 | "bottleneck": "^2.19.5", 39 | "is-deflate": "^1.0.0", 40 | "is-gzip": "^2.0.0", 41 | "performance-now": "^2.1.0" 42 | }, 43 | "peerDependencies": { 44 | "@pown/async": "*", 45 | "@pown/cli": "*" 46 | }, 47 | "devDependencies": { 48 | "@pown/async": "*", 49 | "@pown/cli": "*" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /packages/async/test/iterateOverStream.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | const { PassThrough } = require('stream') 3 | 4 | const { iterateOverStream } = require('../lib/iterateOverStream') 5 | 6 | describe('iterateOverStream', () => { 7 | it('produces the correct numbers', async () => { 8 | const stream = new PassThrough({ objectMode: true }) 9 | 10 | setTimeout(() => { 11 | stream.write(0) 12 | stream.write(1) 13 | stream.write(2) 14 | stream.end() 15 | }, 1) 16 | 17 | const items = [] 18 | 19 | for await (const item of iterateOverStream(stream)) { 20 | items.push(item) 21 | } 22 | 23 | items.sort() 24 | 25 | assert.deepEqual(items, [0, 1, 2], 'items are 0, 1, 2') 26 | }) 27 | 28 | it('handles errors correctly', async () => { 29 | const stream = new PassThrough({ objectMode: true }) 30 | 31 | setTimeout(() => { 32 | stream.write(0) 33 | stream.write(1) 34 | stream.emit('error', new Error('test')) 35 | stream.write(2) 36 | stream.end() 37 | }, 1) 38 | 39 | let error 40 | 41 | try { 42 | for await (const item of iterateOverStream(stream)) { 43 | item 44 | } 45 | } catch (e) { 46 | error = e 47 | } 48 | 49 | assert.equal(error.message, 'test', 'error detected') 50 | }) 51 | }) 52 | -------------------------------------------------------------------------------- /packages/modules/commands/modules/sub/install.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'install ', 3 | describe: 'Install modules', 4 | aliases: ['i'], 5 | 6 | builder: (yargs) => { 7 | yargs.option('development', { 8 | type: 'boolean', 9 | describe: 'Install development.', 10 | alias: ['d', 'dev'], 11 | default: false, 12 | }) 13 | }, 14 | 15 | handler: async (yargs) => { 16 | const { modules = [], development } = yargs 17 | 18 | const util = require('util') 19 | const { writeFile } = require('fs') 20 | const { spawn } = require('child_process') 21 | const { 22 | ensurePreferencesFilename, 23 | getPreferencesFilename, 24 | getPreferencesDirectory, 25 | } = require('@pown/preferences') 26 | 27 | const spawnAsync = util.promisify(spawn) 28 | const writeFileAsync = util.promisify(writeFile) 29 | 30 | await ensurePreferencesFilename('modules', 'package.json') 31 | 32 | await writeFileAsync( 33 | getPreferencesFilename('modules', '.npmrc'), 34 | 'package-lock=false\n' 35 | ) 36 | 37 | const dirname = getPreferencesDirectory('modules') 38 | 39 | await spawnAsync( 40 | 'npm', 41 | ['install', ...modules, ...(development ? [] : ['--production'])], 42 | { shell: true, stdio: 'inherit', cwd: dirname } 43 | ) 44 | }, 45 | } 46 | -------------------------------------------------------------------------------- /packages/request/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/request", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/request#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "exploit", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "publishConfig": { 25 | "access": "public", 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "scripts": { 29 | "start": "POWN_ROOT=. pown-cli", 30 | "test": "NODE_ENV=test npx -y mocha@latest" 31 | }, 32 | "pown": { 33 | "commands": [ 34 | "commands/request" 35 | ] 36 | }, 37 | "dependencies": { 38 | "proxy-agent": "^5.0.0", 39 | "bottleneck": "^2.19.5", 40 | "is-deflate": "^1.0.0", 41 | "is-gzip": "^2.0.0", 42 | "performance-now": "^2.1.0" 43 | }, 44 | "peerDependencies": { 45 | "@pown/async": "*", 46 | "@pown/cli": "*" 47 | }, 48 | "devDependencies": { 49 | "@pown/async": "*", 50 | "@pown/cli": "*" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /packages/lau/lib/modules/alienvault.js: -------------------------------------------------------------------------------- 1 | const querystring = require('querystring') 2 | 3 | const { requestJSON } = require('../scheduler') 4 | 5 | const listAlienVaultURIs = async function* (domain, options) { 6 | const { 7 | logger, 8 | scheduler, 9 | pageSize = 50, 10 | ...schedulerOptions 11 | } = options || {} 12 | 13 | const search = `${encodeURIComponent(domain)}` 14 | 15 | const preQuery = querystring.stringify({ 16 | limit: pageSize, 17 | }) 18 | 19 | let page = 0 20 | 21 | for (;;) { 22 | logger.info(`alienvault: fetching page ${page}`) 23 | 24 | const postQuery = querystring.stringify({ 25 | page: page, 26 | }) 27 | 28 | console.debug(`alienvault: ${search}?${preQuery}&${postQuery}`) 29 | 30 | const data = await requestJSON(scheduler, { 31 | ...schedulerOptions, 32 | uri: `https://otx.alienvault.com/otxapi/indicator/hostname/url_list/${search}?${preQuery}&${postQuery}`, 33 | }) 34 | 35 | const { has_next, url_list } = data 36 | 37 | for (let item of url_list) { 38 | let { url = '' } = item 39 | 40 | url = url.trim() 41 | 42 | if (/^https?:\/\//i.test(url)) { 43 | yield url 44 | } 45 | } 46 | 47 | if (has_next) { 48 | page += 1 49 | } else { 50 | break 51 | } 52 | } 53 | } 54 | 55 | module.exports = { listAlienVaultURIs } 56 | -------------------------------------------------------------------------------- /packages/leaks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pown/leaks", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/leaks#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "main": "lib/index.js", 24 | "publishConfig": { 25 | "access": "public", 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "scripts": { 29 | "build": "node ./scripts/generate-database.js", 30 | "start": "POWN_ROOT=. pown-cli", 31 | "test": "NODE_ENV=test npx -y mocha@latest" 32 | }, 33 | "pown": { 34 | "commands": [ 35 | "commands/leaks" 36 | ] 37 | }, 38 | "dependencies": { 39 | "@pown/regexp": "*" 40 | }, 41 | "peerDependencies": { 42 | "@pown/async": "*", 43 | "@pown/cli": "*", 44 | "@pown/request": "*" 45 | }, 46 | "devDependencies": { 47 | "@pown/async": "*", 48 | "@pown/cli": "*", 49 | "@pown/request": "*", 50 | "js-yaml": "^4.1.0", 51 | "safe-regex": "^2.1.1" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /packages/pown/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pown", 3 | "version": "3.12.1", 4 | "description": "Pownage guaranteed", 5 | "license": "MIT", 6 | "engines": { 7 | "node": ">=14" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/pownjs/pown.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/pownjs/pown/issues" 15 | }, 16 | "homepage": "https://github.com/pownjs/pown/tree/master/packages/pown#readme", 17 | "author": "pdp ", 18 | "contributors": [], 19 | "keywords": [ 20 | "security", 21 | "framework" 22 | ], 23 | "bin": { 24 | "pown": "bin/pown.js" 25 | }, 26 | "main": "lib/index.js", 27 | "publishConfig": { 28 | "access": "public", 29 | "registry": "https://registry.npmjs.org/" 30 | }, 31 | "scripts": { 32 | "postinstall": "node scripts/postinstall.js", 33 | "start": "POWN_ROOT=. pown-cli", 34 | "test": "NODE_ENV=test npx -y mocha@latest" 35 | }, 36 | "pown": { 37 | "commands": [ 38 | "commands/update" 39 | ] 40 | }, 41 | "dependencies": { 42 | "@pown/cli": "*", 43 | "@pown/credits": "*", 44 | "@pown/modules": "*", 45 | "@pown/preferences": "*", 46 | "@pown/script": "*", 47 | "@pown/shell": "*" 48 | }, 49 | "peerDependencies": { 50 | "@pown/cli": "*" 51 | }, 52 | "devDependencies": { 53 | "@pown/cli": "*" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/recon/transforms/gravatar/index.js: -------------------------------------------------------------------------------- 1 | const crypto = require('crypto') 2 | const querystring = require('querystring') 3 | 4 | const { Transform } = require('../../lib//transform') 5 | 6 | const GRAVATAR_TYPE = 'gravatar' 7 | 8 | const gravatar = class extends Transform { 9 | static get alias() { 10 | return [] 11 | } 12 | 13 | static get title() { 14 | return 'Gravatar' 15 | } 16 | 17 | static get description() { 18 | return 'Get gravatar' 19 | } 20 | 21 | static get group() { 22 | return this.title 23 | } 24 | 25 | static get tags() { 26 | return ['ce'] 27 | } 28 | 29 | static get types() { 30 | return ['email'] 31 | } 32 | 33 | static get options() { 34 | return {} 35 | } 36 | 37 | static get priority() { 38 | return 1 39 | } 40 | 41 | static get noise() { 42 | return 1 43 | } 44 | 45 | async handle({ id: source = '', label = '' }) { 46 | const gravatar = crypto.createHash('md5').update(label).digest('hex') 47 | 48 | const query = querystring.stringify({ 49 | s: 256, 50 | d: 'identicon', 51 | }) 52 | 53 | const uri = `https://gravatar.com/avatar/${gravatar}?${query}` 54 | 55 | return [ 56 | { 57 | type: GRAVATAR_TYPE, 58 | label, 59 | image: uri, 60 | props: { gravatar, uri }, 61 | edges: [source], 62 | }, 63 | ] 64 | } 65 | } 66 | 67 | module.exports = { gravatar } 68 | -------------------------------------------------------------------------------- /packages/recon/lib/cache/memcached.js: -------------------------------------------------------------------------------- 1 | const Memcached = require('memcached') 2 | const querystring = require('querystring') 3 | 4 | class Cache { 5 | constructor(options) { 6 | const { ttl, keyPrefix, keySuffix, hosts, ...memcachedOptions } = 7 | options || {} 8 | 9 | this.ttl = ttl || 60 10 | 11 | this.keyPrefix = keyPrefix || '' 12 | this.keySuffix = keySuffix || '' 13 | 14 | this.client = new Memcached(hosts, memcachedOptions) 15 | } 16 | 17 | invoke(op, ...args) { 18 | return new Promise((resolve, reject) => { 19 | this.client[op](...args, (err, result) => { 20 | if (err) { 21 | reject(err) 22 | } else { 23 | resolve(result) 24 | } 25 | }) 26 | }) 27 | } 28 | 29 | key(transform, node, options) { 30 | return ( 31 | [this.keyPrefix, transform, node.id, this.keySuffix] 32 | .filter((i) => i) 33 | .map(encodeURIComponent) 34 | .join('/') + 35 | '?' + 36 | querystring.stringify(options || {}) 37 | ) 38 | } 39 | 40 | async get(transform, node, options) { 41 | return this.invoke('get', this.key(transform, node, options)) 42 | } 43 | 44 | async set(transform, node, options, value, ttl = this.ttl) { 45 | return this.invoke('set', this.key(transform, node, options), value, ttl) 46 | } 47 | 48 | async end() { 49 | return this.invoke('end') 50 | } 51 | } 52 | 53 | module.exports = { Cache } 54 | -------------------------------------------------------------------------------- /packages/recon/lib/worker/utils.js: -------------------------------------------------------------------------------- 1 | const serialize = (obj) => { 2 | // NOTE: this method is only available for consistency reasons because we rely on the structured 3 | // cloning algorithm to do the heavy lifting, but keep in mind that there is a chance that the 4 | // serialised and deseiralised object will be different, which should not be a problem for most 5 | // intents and purposes 6 | 7 | return obj 8 | } 9 | 10 | const deserialize = (obj) => { 11 | // NOTE: there is no need to handle String, Number, Boolean and other native objects because 12 | // we assume this method is only used in the context of deserializing object created by the 13 | // structured clone algorithm - i.e. due to message passing 14 | 15 | switch (true) { 16 | case obj === null: 17 | return obj 18 | 19 | case Array.isArray(obj): 20 | return obj.map(deserialize) 21 | 22 | case ArrayBuffer.isView(obj): 23 | return Buffer.from(obj, obj.byteOffset, obj.byteLength) 24 | 25 | case typeof obj === 'object': 26 | if (obj.type === 'Buffer' && Array.isArray(obj.data)) { 27 | return Buffer.from(obj.data) 28 | } else { 29 | return Object.assign( 30 | {}, 31 | ...Object.entries(obj).map(([key, value]) => ({ 32 | [key]: deserialize(value), 33 | })) 34 | ) 35 | } 36 | 37 | default: 38 | return obj 39 | } 40 | } 41 | 42 | module.exports = { serialize, deserialize } 43 | -------------------------------------------------------------------------------- /packages/request/commands/request/options/output/handler.js: -------------------------------------------------------------------------------- 1 | const { writeFile } = require('fs') 2 | const { promisify } = require('util') 3 | 4 | const writeFileAsync = promisify(writeFile) 5 | 6 | const init = (options, scheduler) => { 7 | const { 8 | filterResponseCode, 9 | contentSniffSize, 10 | printResponseBody, 11 | downloadResponseBody, 12 | } = options 13 | 14 | scheduler.on('request-finished', (request, response) => { 15 | const { method, uri, responseCode, responseHeaders, responseBody } = 16 | response 17 | 18 | if (filterResponseCode) { 19 | if (filterResponseCode != responseCode) { 20 | return 21 | } 22 | } 23 | 24 | const responseBodySniff = responseBody 25 | .slice(0, contentSniffSize) 26 | .toString('hex') 27 | 28 | console.info( 29 | `${method} ${uri} -> ${responseCode} ${responseBody.length} ${ 30 | responseBodySniff ? responseBodySniff : '-' 31 | }${ 32 | responseHeaders['location'] ? ' -> ' + responseHeaders['location'] : '' 33 | }` 34 | ) 35 | 36 | if (printResponseBody) { 37 | console.log(responseBody.toString()) 38 | } 39 | 40 | if (downloadResponseBody) { 41 | writeFileAsync( 42 | uri 43 | .replace(/\W+/g, '_') 44 | .replace(/_+/, '_') 45 | .replace(/([a-zA-Z0-9]+)$/, '.$1'), 46 | responseBody 47 | ) 48 | } 49 | }) 50 | } 51 | 52 | module.exports = { init } 53 | -------------------------------------------------------------------------------- /packages/leaks/test/dataset.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | const jsYaml = require('js-yaml') 3 | const path = require('path') 4 | const fs = require('fs') 5 | 6 | const { Pilot } = require('../lib/pilot') 7 | const database = require('../lib/database') 8 | const { compileDatabase } = require('../lib/compile') 9 | 10 | describe('dataset', () => { 11 | it('viv-1615539741', async () => { 12 | const dataset = jsYaml.load( 13 | fs.readFileSync( 14 | path.join(__dirname, '..', 'dataset', 'viv-1615539741.yaml') 15 | ) 16 | ) 17 | 18 | const lp = new Pilot({ database: compileDatabase(database) }) 19 | 20 | for (let { valid, invalid } of dataset) { 21 | if (valid) { 22 | let lastMatch 23 | 24 | for await (const match of lp.iterateOverSearch(valid || invalid)) { 25 | lastMatch = match 26 | } 27 | 28 | assert.ok( 29 | lastMatch, 30 | `Valid secret ${JSON.stringify(valid)} should match` 31 | ) 32 | } else { 33 | let lastMatch 34 | 35 | for await (const match of lp.iterateOverSearch(valid || invalid)) { 36 | lastMatch = match 37 | 38 | if (match) { 39 | break 40 | } 41 | } 42 | 43 | assert.ok( 44 | !lastMatch, 45 | `Invalid secret ${JSON.stringify( 46 | invalid 47 | )} should not match ${JSON.stringify(lastMatch, '', ' ')}` 48 | ) 49 | } 50 | } 51 | }) 52 | }) 53 | -------------------------------------------------------------------------------- /packages/recon/lib/options.js: -------------------------------------------------------------------------------- 1 | class Store { 2 | constructor() { 3 | this.store = {} 4 | } 5 | 6 | getOption(name) { 7 | return this.store[name] 8 | } 9 | 10 | setOption(name, value) { 11 | this.store[name] = value 12 | } 13 | 14 | deleteOption(name) { 15 | delete this.store[name] 16 | } 17 | 18 | clearOptions() { 19 | this.store = {} 20 | } 21 | 22 | listOptions() { 23 | return Object.entries(this.store).map(([name, value]) => ({ name, value })) 24 | } 25 | 26 | getOptions() { 27 | return { 28 | ...this.store, 29 | } 30 | } 31 | } 32 | 33 | class Options { 34 | constructor() { 35 | this.stores = {} 36 | } 37 | 38 | getStore(category) { 39 | if (!this.stores[category]) { 40 | this.stores[category] = new Store() 41 | } 42 | 43 | return this.stores[category] 44 | } 45 | 46 | getOption(category, name) { 47 | return this.getStore(category).getOption(name) 48 | } 49 | 50 | setOption(category, name, value) { 51 | this.getStore(category).setOption(name, value) 52 | } 53 | 54 | deleteOption(category, name) { 55 | this.getStore(category).deleteOption(name) 56 | } 57 | 58 | clearOptions(category) { 59 | this.getStore(category).clearOptions() 60 | } 61 | 62 | listOptions(category) { 63 | return this.getStore(category).listOptions() 64 | } 65 | 66 | getOptions(category) { 67 | return this.getStore(category).getOptions() 68 | } 69 | } 70 | 71 | module.exports = { Options, Store } 72 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/ungroup/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'ungroup ', 3 | describe: 'Ungroup nodes', 4 | aliases: ['u'], 5 | 6 | builder: (yargs) => { 7 | const { 8 | installReadOptions, 9 | installWriteOptions, 10 | } = require('../../lib/handlers/file') 11 | 12 | installReadOptions(yargs) 13 | installWriteOptions(yargs) 14 | 15 | const { installOutputOptions } = require('../../lib/handlers/output') 16 | 17 | installOutputOptions(yargs) 18 | 19 | yargs.options('traverse', { 20 | alias: 'v', 21 | type: 'boolean', 22 | describe: 'Traverse graph', 23 | default: false, 24 | }) 25 | }, 26 | 27 | handler: async (argv) => { 28 | const { traverse, expressions } = argv 29 | 30 | const { recon } = require('../../lib/globals/recon') 31 | 32 | const { 33 | handleReadOptions, 34 | handleWriteOptions, 35 | } = require('../../lib/handlers/file') 36 | 37 | await handleReadOptions(argv, recon) 38 | 39 | let resultNodes 40 | 41 | if (traverse) { 42 | resultNodes = recon.traverse(...expressions).map((node) => node.data()) 43 | } else { 44 | resultNodes = recon.select(...expressions).map((node) => node.data()) 45 | } 46 | 47 | await recon.ungroup() 48 | 49 | await handleWriteOptions(argv, recon) 50 | 51 | const { handleOutputOptions } = require('../../lib/handlers/output') 52 | 53 | await handleOutputOptions(argv, resultNodes) 54 | }, 55 | } 56 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/remove/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'remove ', 3 | describe: 'Remove nodes', 4 | aliases: ['r'], 5 | 6 | builder: (yargs) => { 7 | const { 8 | installReadOptions, 9 | installWriteOptions, 10 | } = require('../../lib/handlers/file') 11 | 12 | installReadOptions(yargs) 13 | installWriteOptions(yargs) 14 | 15 | const { installOutputOptions } = require('../../lib/handlers/output') 16 | 17 | installOutputOptions(yargs) 18 | 19 | yargs.options('traverse', { 20 | alias: 'v', 21 | type: 'boolean', 22 | describe: 'Traverse graph', 23 | default: false, 24 | }) 25 | }, 26 | 27 | handler: async (argv) => { 28 | const { traverse, expressions } = argv 29 | 30 | const { recon } = require('../../lib/globals/recon') 31 | 32 | const { 33 | handleReadOptions, 34 | handleWriteOptions, 35 | } = require('../../lib/handlers/file') 36 | 37 | await handleReadOptions(argv, recon) 38 | 39 | let resultNodes 40 | 41 | if (traverse) { 42 | resultNodes = recon.traverse(...expressions).map((node) => node.data()) 43 | } else { 44 | resultNodes = recon.select(...expressions).map((node) => node.data()) 45 | } 46 | 47 | recon.removeNodes(resultNodes) 48 | 49 | await handleWriteOptions(argv, recon) 50 | 51 | const { handleOutputOptions } = require('../../lib/handlers/output') 52 | 53 | await handleOutputOptions(argv, resultNodes) 54 | }, 55 | } 56 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/group/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'group ', 3 | describe: 'Group nodes', 4 | aliases: ['g'], 5 | 6 | builder: (yargs) => { 7 | const { 8 | installReadOptions, 9 | installWriteOptions, 10 | } = require('../../lib/handlers/file') 11 | 12 | installReadOptions(yargs) 13 | installWriteOptions(yargs) 14 | 15 | const { installOutputOptions } = require('../../lib/handlers/output') 16 | 17 | installOutputOptions(yargs) 18 | 19 | yargs.options('traverse', { 20 | alias: 'v', 21 | type: 'boolean', 22 | describe: 'Traverse graph', 23 | default: false, 24 | }) 25 | }, 26 | 27 | handler: async (argv) => { 28 | const { traverse, name, expressions } = argv 29 | 30 | const { recon } = require('../../lib/globals/recon') 31 | 32 | const { 33 | handleReadOptions, 34 | handleWriteOptions, 35 | } = require('../../lib/handlers/file') 36 | 37 | await handleReadOptions(argv, recon) 38 | 39 | let resultNodes 40 | 41 | if (traverse) { 42 | resultNodes = recon.traverse(...expressions).map((node) => node.data()) 43 | } else { 44 | resultNodes = recon.select(...expressions).map((node) => node.data()) 45 | } 46 | 47 | await recon.group(name) 48 | 49 | await handleWriteOptions(argv, recon) 50 | 51 | const { handleOutputOptions } = require('../../lib/handlers/output') 52 | 53 | await handleOutputOptions(argv, resultNodes) 54 | }, 55 | } 56 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/layout/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'layout ', 3 | describe: 'Layout the graph', 4 | aliases: ['k'], 5 | 6 | builder: (yargs) => { 7 | const { 8 | installReadOptions, 9 | installWriteOptions, 10 | } = require('../../lib/handlers/file') 11 | 12 | installReadOptions(yargs) 13 | installWriteOptions(yargs) 14 | }, 15 | 16 | handler: async (argv) => { 17 | const { name } = argv 18 | 19 | const { cytoscape } = require('../../../../lib/cytoscape') 20 | 21 | const klay = require('cytoscape-klay') 22 | const dagre = require('cytoscape-dagre') 23 | const euler = require('cytoscape-euler') 24 | 25 | cytoscape.use(klay) 26 | cytoscape.use(dagre) 27 | cytoscape.use(euler) 28 | 29 | const { recon } = require('../../lib/globals/recon') 30 | 31 | recon.resetGraph({ 32 | headless: true, 33 | 34 | styleEnabled: true, 35 | }) 36 | 37 | const { 38 | handleReadOptions, 39 | handleWriteOptions, 40 | } = require('../../lib/handlers/file') 41 | 42 | await handleReadOptions(argv, recon) 43 | 44 | const layout = recon.elements().layout({ 45 | boundingBox: { x1: 0, y1: 0, w: 4096, h: 3072 }, 46 | 47 | name: name, 48 | 49 | animate: false, 50 | 51 | nodeDimensionsIncludeLabels: true, 52 | }) 53 | 54 | const promise = layout.pon('layoutstop') 55 | 56 | await layout.run() 57 | 58 | await promise 59 | 60 | await handleWriteOptions(argv, recon) 61 | }, 62 | } 63 | -------------------------------------------------------------------------------- /packages/recon/commands/recon/sub/transform/transforms.js: -------------------------------------------------------------------------------- 1 | const { extractSync, atain } = require('@pown/modules') 2 | const { getPreferencesSync } = require('@pown/preferences') 3 | 4 | const { buildRemoteTransforms } = require('../../../../lib/remote') 5 | 6 | const getCompoundTransforms = async () => { 7 | const { remotes = {} } = getPreferencesSync('recon') 8 | 9 | const remoteTransforms = buildRemoteTransforms(remotes) 10 | 11 | const { loadableTransforms } = extractSync() 12 | 13 | return { 14 | ...remoteTransforms, 15 | 16 | ...Object.assign( 17 | {}, 18 | ...(await Promise.all( 19 | loadableTransforms.map(async (module) => { 20 | let transforms 21 | 22 | try { 23 | transforms = await atain(module) 24 | } catch (e) { 25 | if (process.env.POWN_DEBUG) { 26 | console.error(e) 27 | } 28 | 29 | return {} 30 | } 31 | 32 | return Object.assign( 33 | {}, 34 | ...Object.entries(transforms) 35 | .filter(([name]) => name !== 'default') 36 | .map(([name, Transform]) => { 37 | return { 38 | [name]: class extends Transform { 39 | static loadableTransformModule = module 40 | static loadableTransformName = name 41 | }, 42 | } 43 | }) 44 | ) 45 | }) 46 | )) 47 | ), 48 | } 49 | } 50 | 51 | module.exports = { getCompoundTransforms } 52 | -------------------------------------------------------------------------------- /packages/recon/lib/types.js: -------------------------------------------------------------------------------- 1 | const ALL_TYPE = '*' 2 | const STRING_TYPE = 'string' 3 | const DOMAIN_TYPE = 'domain' 4 | const SUBDOMAIN_TYPE = 'subdomain' 5 | const IPV4_TYPE = 'ipv4' 6 | const IPV6_TYPE = 'ipv6' 7 | const PORT_TYPE = 'port' 8 | const URI_TYPE = 'uri' 9 | const BRAND_TYPE = 'brand' 10 | const PERSON_TYPE = 'person' 11 | const EMAIL_TYPE = 'email' 12 | const NICK_TYPE = 'nick' 13 | const ORG_TYPE = 'org' 14 | const CODE_TYPE = 'code' 15 | const TITLE_TYPE = 'title' 16 | const SOFTWARE_TYPE = 'software' 17 | const MIME_TYPE = 'mime' 18 | const IMAGE_TYPE = 'image' 19 | const SCREENSHOT_TYPE = 'screenshot' 20 | const SHA1_TYPE = 'sha1' 21 | const FINGERPRINT_TYPE = 'fingerprint' 22 | const SIGNATURE_TYPE = 'signature' 23 | const WHOIS_TYPE = 'whois' 24 | const ISSUE_TYPE = 'issue' 25 | const EXPLOIT_TYPE = 'exploit' 26 | const HASH_TYPE = 'hash' 27 | const SANDOMAIN_TYPE = 'sandomain' 28 | const BANNER_TYPE = 'banner' 29 | const CERTIFICATE_TYPE = 'certificate' 30 | const TLS_TYPE = 'tls' 31 | 32 | module.exports = { 33 | ALL_TYPE, 34 | STRING_TYPE, 35 | DOMAIN_TYPE, 36 | SUBDOMAIN_TYPE, 37 | IPV4_TYPE, 38 | IPV6_TYPE, 39 | PORT_TYPE, 40 | URI_TYPE, 41 | BRAND_TYPE, 42 | PERSON_TYPE, 43 | EMAIL_TYPE, 44 | NICK_TYPE, 45 | ORG_TYPE, 46 | CODE_TYPE, 47 | TITLE_TYPE, 48 | SOFTWARE_TYPE, 49 | MIME_TYPE, 50 | IMAGE_TYPE, 51 | SCREENSHOT_TYPE, 52 | SHA1_TYPE, 53 | FINGERPRINT_TYPE, 54 | SIGNATURE_TYPE, 55 | WHOIS_TYPE, 56 | ISSUE_TYPE, 57 | EXPLOIT_TYPE, 58 | HASH_TYPE, 59 | SANDOMAIN_TYPE, 60 | BANNER_TYPE, 61 | CERTIFICATE_TYPE, 62 | TLS_TYPE, 63 | } 64 | -------------------------------------------------------------------------------- /packages/request/commands/request/options/request/handler.js: -------------------------------------------------------------------------------- 1 | const init = (options, scheduler) => { 2 | const { method, header, connectTimeout, dataTimeout, acceptUnauthorized } = 3 | options 4 | 5 | if (method) { 6 | scheduler.on('request-scheduled', (request) => { 7 | request.method = method 8 | }) 9 | } 10 | 11 | if (connectTimeout) { 12 | scheduler.on('request-scheduled', (request) => { 13 | request.connectTimeout = connectTimeout 14 | }) 15 | } 16 | 17 | if (dataTimeout) { 18 | scheduler.on('request-scheduled', (request) => { 19 | request.dataTimeout = dataTimeout 20 | }) 21 | } 22 | 23 | scheduler.on('request-scheduled', (request) => { 24 | request.rejectUnauthorized = !acceptUnauthorized 25 | }) 26 | 27 | if (header) { 28 | const headers = {} 29 | 30 | for (let entry of Array.isArray(header) ? header : [header]) { 31 | let [name = '', value = ''] = entry.split(':', 1) 32 | 33 | name = name.trim() || entry 34 | value = value.trim() || '' 35 | 36 | if (headers[name]) { 37 | if (!Array.isArray(headers[name])) { 38 | headers[name] = [headers[name]] 39 | } 40 | 41 | headers[name].push(value) 42 | } else { 43 | headers[name] = value 44 | } 45 | } 46 | 47 | scheduler.on('request-scheduled', (request) => { 48 | if (!request.headers) { 49 | request.headers = {} 50 | } 51 | 52 | request.headers = { 53 | ...request.headers, 54 | 55 | ...headers, 56 | } 57 | }) 58 | } 59 | } 60 | 61 | module.exports = { init } 62 | -------------------------------------------------------------------------------- /scripts/fix-package-json.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | const main = async () => { 5 | const packagesDir = path.join(__dirname, '..', 'packages') 6 | 7 | for (const dir of fs.readdirSync(packagesDir)) { 8 | const packageFile = path.join(packagesDir, dir, 'package.json') 9 | 10 | const packageJSON = fs.readFileSync(packageFile) 11 | 12 | const pkg = JSON.parse(packageJSON.toString()) 13 | 14 | pkg.main = 'lib/index.js' 15 | 16 | pkg.scripts.test = 'NODE_ENV=test npx -y mocha@latest' 17 | 18 | pkg.homepage = `https://github.com/pownjs/pown/tree/master/packages/${dir}#readme` 19 | 20 | pkg.license = 'MIT' 21 | 22 | pkg.repository = { 23 | type: 'git', 24 | url: `git+https://github.com/pownjs/pown.git`, 25 | } 26 | 27 | pkg.bugs = { 28 | url: 'https://github.com/pownjs/pown/issues', 29 | } 30 | 31 | pkg.engines = { 32 | node: '>=14', 33 | } 34 | 35 | pkg.publishConfig = { 36 | access: 'public', 37 | registry: 'https://registry.npmjs.org/', 38 | } 39 | 40 | if (pkg?.pown?.commands?.length > 0) { 41 | pkg.scripts.start = 'POWN_ROOT=. pown-cli' 42 | 43 | if (!pkg.peerDependencies) { 44 | pkg.peerDependencies = {} 45 | } 46 | 47 | pkg.peerDependencies['@pown/cli'] = '*' 48 | 49 | if (!pkg.devDependencies) { 50 | pkg.devDependencies = {} 51 | } 52 | 53 | pkg.devDependencies['@pown/cli'] = '*' 54 | } 55 | 56 | fs.writeFileSync(packageFile, JSON.stringify(pkg, '', 2) + '\n') 57 | } 58 | } 59 | 60 | main().catch(console.error) 61 | -------------------------------------------------------------------------------- /packages/request/commands/request/index.js: -------------------------------------------------------------------------------- 1 | exports.yargs = { 2 | command: 'request [url]', 3 | describe: 'Send requests', 4 | 5 | builder: { 6 | ...require('./options/url'), 7 | ...require('./options/proxy'), 8 | ...require('./options/output'), 9 | ...require('./options/request'), 10 | ...require('./options/scheduler'), 11 | 12 | 'task-concurrency': { 13 | alias: ['C'], 14 | type: 'number', 15 | describe: 'The number of request tasks to run at the same time', 16 | default: Infinity, 17 | }, 18 | }, 19 | 20 | handler: async (argv) => { 21 | const { taskConcurrency, url } = argv 22 | 23 | const { Scheduler } = require('../../lib/scheduler') 24 | 25 | const scheduler = new Scheduler() 26 | 27 | require('./options/url/handler').init(argv, scheduler) 28 | require('./options/proxy/handler').init(argv, scheduler) 29 | require('./options/output/handler').init(argv, scheduler) 30 | require('./options/request/handler').init(argv, scheduler) 31 | require('./options/scheduler/handler').init(argv, scheduler) 32 | 33 | const { makeLineIterator } = require('@pown/cli/lib/line') 34 | const { eachOfLimit } = require('@pown/async/lib/eachOfLimit') 35 | 36 | const it = makeLineIterator(url) 37 | 38 | await eachOfLimit(it(), taskConcurrency, async (uri) => { 39 | if (!uri) { 40 | return 41 | } 42 | 43 | uri = uri.trim() 44 | 45 | if (!uri) { 46 | return 47 | } 48 | 49 | try { 50 | await scheduler.request({ uri }) 51 | } catch (e) { 52 | console.error(e) 53 | } 54 | }) 55 | }, 56 | } 57 | -------------------------------------------------------------------------------- /packages/recon/transforms/ipinfoio/index.js: -------------------------------------------------------------------------------- 1 | const querystring = require('querystring') 2 | 3 | const { Transform } = require('../../lib//transform') 4 | const { WHOIS_TYPE, IPV4_TYPE } = require('../../lib//types') 5 | 6 | const ipinfoioWidgetSearch = class extends Transform { 7 | static get alias() { 8 | return ['ipinfoio_widget_search', 'iiiows'] 9 | } 10 | 11 | static get title() { 12 | return 'ipinfo.io widget search' 13 | } 14 | 15 | static get description() { 16 | return 'Obtain ipinfo.io whois report via the web widget' 17 | } 18 | 19 | static get group() { 20 | return this.title 21 | } 22 | 23 | static get tags() { 24 | return ['ce'] 25 | } 26 | 27 | static get types() { 28 | return [IPV4_TYPE] 29 | } 30 | 31 | static get options() { 32 | return {} 33 | } 34 | 35 | static get priority() { 36 | return 1 37 | } 38 | 39 | static get noise() { 40 | return 1 41 | } 42 | 43 | async handle({ id: source = '', label = '' }, options) { 44 | const search = querystring.escape(label) 45 | 46 | const headers = { 47 | 'User-Agent': 48 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:88.0) Gecko/20100101 Firefox/88.0', 49 | Referer: 'https://ipinfo.io/', 50 | } 51 | 52 | const { org, ...rest } = await this.scheduler.tryRequest({ 53 | uri: `https://ipinfo.io/widget/${search}`, 54 | headers, 55 | toJson: true, 56 | }) 57 | 58 | return [ 59 | { 60 | type: WHOIS_TYPE, 61 | label: org, 62 | props: { org, ...rest }, 63 | }, 64 | ] 65 | } 66 | } 67 | 68 | module.exports = { ipinfoioWidgetSearch } 69 | -------------------------------------------------------------------------------- /packages/connect/examples/request-smuggling.js: -------------------------------------------------------------------------------- 1 | const { Scheduler } = require('@pown/connect/lib/scheduler') 2 | 3 | const scheduler = new Scheduler() 4 | 5 | const firstRequest = `POST / HTTP/1.1\r 6 | Transfer_Encoding: chunked\r 7 | Host: target.com\r 8 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36\r 9 | Content-type: application/x-www-form-urlencoded; charset=UTF-8\r 10 | Content-Length: 52\r 11 | \r 12 | 0\r 13 | GET /robots.txt HTTP/1.1\r 14 | Host: target.com\r 15 | X-Ignore: X` 16 | 17 | const subsequentRequest = `POST / HTTP/1.1\r 18 | Transfer_Encoding: chunked\r 19 | Host: target.com\r 20 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36\r 21 | Content-type: application/x-www-form-urlencoded; charset=UTF-8\r 22 | Content-Length: 3\r 23 | \r 24 | 0\r 25 | ` 26 | 27 | scheduler 28 | .connect({ 29 | timeout: 1000, 30 | host: 'target.com', 31 | data: firstRequest, 32 | port: 443, 33 | tls: true, 34 | }) 35 | .then(async (response) => { 36 | console.log('---') 37 | console.log(response.responseData.toString()) 38 | 39 | await Promise.all( 40 | Array(15) 41 | .fill(0) 42 | .map(async () => { 43 | const response = await scheduler.connect({ 44 | timeout: 1000, 45 | host: 'target.com', 46 | data: subsequentRequest, 47 | port: 443, 48 | tls: true, 49 | }) 50 | 51 | console.log('---') 52 | console.log(response.responseData.toString()) 53 | }) 54 | ) 55 | }) 56 | -------------------------------------------------------------------------------- /packages/recon/transforms/securitytrails/index.js: -------------------------------------------------------------------------------- 1 | const querystring = require('querystring') 2 | 3 | const { Transform } = require('../../lib//transform') 4 | const { normalizeDomain } = require('../../lib//normalize') 5 | const { BRAND_TYPE, DOMAIN_TYPE } = require('../../lib//types') 6 | 7 | const securitytrailsSuggestions = class extends Transform { 8 | static get alias() { 9 | return ['securitytrails_domain_suggestions', 'stds'] 10 | } 11 | 12 | static get title() { 13 | return 'Security Trails Domain Suggestions' 14 | } 15 | 16 | static get description() { 17 | return 'Get a list of domain suggestions from securitytrails.com' 18 | } 19 | 20 | static get group() { 21 | return this.title 22 | } 23 | 24 | static get tags() { 25 | return ['ce'] 26 | } 27 | 28 | static get types() { 29 | return [BRAND_TYPE] 30 | } 31 | 32 | static get options() { 33 | return {} 34 | } 35 | 36 | static get priority() { 37 | return 1 38 | } 39 | 40 | static get noise() { 41 | return 9 42 | } 43 | 44 | async handle({ id: source = '', label = '' }) { 45 | const search = querystring.escape(label) 46 | 47 | const { suggestions = [] } = await this.scheduler.tryRequest({ 48 | uri: `https://securitytrails.com/app/api/autocomplete/domain/${search}`, 49 | toJson: true, 50 | }) 51 | 52 | return suggestions.map((domain) => { 53 | domain = normalizeDomain(domain) 54 | 55 | return { 56 | type: DOMAIN_TYPE, 57 | label: domain, 58 | props: { domain }, 59 | edges: [source], 60 | } 61 | }) 62 | } 63 | } 64 | 65 | module.exports = { securitytrailsSuggestions } 66 | -------------------------------------------------------------------------------- /packages/connect/lib/scheduler.js: -------------------------------------------------------------------------------- 1 | const EventEmitter = require('events') 2 | const Bottleneck = require('bottleneck') 3 | 4 | const { connect } = require('./connect') 5 | 6 | const systemLimiter = new Bottleneck() 7 | 8 | class SystemScheduler extends EventEmitter { 9 | constructor() { 10 | super() 11 | 12 | this.limiter = systemLimiter 13 | } 14 | 15 | update(options) { 16 | this.limiter.updateSettings(options) 17 | } 18 | 19 | stop() { 20 | this.limiter.stop() 21 | } 22 | 23 | pause() { 24 | this.update({ reservoir: 0 }) 25 | } 26 | 27 | resume() { 28 | this.update({ reservoir: null }) 29 | } 30 | 31 | async connect(options) { 32 | this.emit('connect-scheduled', options) 33 | 34 | const result = await this.limiter.schedule(async (options) => { 35 | this.emit('connect-executed', options) 36 | 37 | const result = await connect(options) 38 | 39 | this.emit('connect-finished', options, result) 40 | 41 | return result 42 | }, options) 43 | 44 | this.emit('connect-completed', options, result) 45 | 46 | return result 47 | } 48 | } 49 | 50 | class Scheduler extends SystemScheduler { 51 | constructor(options) { 52 | super() 53 | 54 | const limiter = new Bottleneck(options) 55 | 56 | limiter.chain(this.limiter) 57 | 58 | this.limiter = limiter 59 | } 60 | 61 | update(options) { 62 | this.limiter.updateSettings(options) 63 | } 64 | 65 | stop() { 66 | this.limiter.stop() 67 | } 68 | 69 | pause() { 70 | this.update({ reservoir: 0 }) 71 | } 72 | 73 | resume() { 74 | this.update({ reservoir: null }) 75 | } 76 | } 77 | 78 | module.exports = { Scheduler, SystemScheduler, systemLimiter } 79 | --------------------------------------------------------------------------------