UNPKG

padding-oracle-attacker

Version:

CLI tool and library to execute padding oracle attacks easily

82 lines (81 loc) 3.9 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const bluebird_1 = __importDefault(require("./bluebird")); // eslint-disable-line import/order const path_1 = __importDefault(require("path")); const ow_1 = __importDefault(require("ow")); const fs_extra_1 = __importDefault(require("fs-extra")); const tmp_promise_1 = __importDefault(require("tmp-promise")); const chalk_1 = __importDefault(require("chalk")); const lodash_1 = require("lodash"); const logging_1 = require("./logging"); const oracle_caller_1 = __importDefault(require("./oracle-caller")); const util_1 = require("./util"); const { logStart, logCompletion } = logging_1.analysis; const getResponseText = (res) => `<!-- Saved by https://github.com/KishanBagaria/padding-oracle-attacker From ${res.url} Payload: ${res.payload.toString('hex')} ${res.statusCode} ${util_1.stringifyHeaders(res.headers)} --> ${res.body}`; const byteRange = lodash_1.range(0, 256); async function analyseResponses(_a) { var { url, blockSize, logMode = 'full', concurrency = 128, isCacheEnabled = true, saveResponsesToTmpDir = true } = _a, args = __rest(_a, ["url", "blockSize", "logMode", "concurrency", "isCacheEnabled", "saveResponsesToTmpDir"]); ow_1.default(blockSize, ow_1.default.number); ow_1.default(concurrency, ow_1.default.number); const tmpDirPath = saveResponsesToTmpDir ? (await tmp_promise_1.default.dir({ prefix: 'poattack_' })).path : ''; if (['full', 'minimal'].includes(logMode)) await logStart({ url, blockSize, tmpDirPath }); const { callOracle, networkStats } = oracle_caller_1.default(Object.assign({ url, isCacheEnabled }, args)); const statusCodeFreq = {}; const bodyLengthFreq = {}; const responses = {}; const fsPromises = []; const rows = []; async function processByte(byte) { const twoBlocks = Buffer.alloc(blockSize * 2); twoBlocks[blockSize - 1] = byte; const req = await callOracle(twoBlocks); const res = Object.assign(Object.assign({}, req), { payload: twoBlocks }); if (saveResponsesToTmpDir) { fsPromises.push(fs_extra_1.default.writeFile(path_1.default.join(tmpDirPath, byte + '.html'), getResponseText(res))); } const { statusCode } = req; const cl = req.body.length; responses[byte] = res; statusCodeFreq[statusCode] = (statusCodeFreq[statusCode] || 0) + 1; bodyLengthFreq[cl] = (bodyLengthFreq[cl] || 0) + 1; const color = util_1.getStatusCodeColor(statusCode); rows.push([String(byte), chalk_1.default[color](String(statusCode)), String(cl)]); } if (concurrency > 1) { await bluebird_1.default.map(byteRange, processByte, { concurrency }); } else { for (const byte of byteRange) await processByte(byte); } await Promise.all(fsPromises); if (['full', 'minimal'].includes(logMode)) { const responsesTable = lodash_1.orderBy(rows, [1, 2, x => +x[0]]); logCompletion({ responsesTable, networkStats, statusCodeFreq, bodyLengthFreq, tmpDirPath, isCacheEnabled }); } return { responses, statusCodeFreq, bodyLengthFreq, tmpDirPath }; } exports.default = analyseResponses; //# sourceMappingURL=response-analysis.js.map