UNPKG

padding-oracle-attacker

Version:

CLI tool and library to execute padding oracle attacks easily

201 lines (144 loc) 8.77 kB
# padding-oracle-attacker CLI tool and library to execute [padding oracle attacks](https://en.wikipedia.org/wiki/Padding_oracle_attack) easily, with support for concurrent network requests and an elegant UI. <img alt="poattack decrypt demo" src="media/poattack-decrypt.gif" width="734" height="492" /> [![Build Status](https://travis-ci.org/KishanBagaria/padding-oracle-attacker.svg)](https://travis-ci.org/KishanBagaria/padding-oracle-attacker) ## Install ```sh $ yarn global add padding-oracle-attacker ``` or ```sh $ npm install --global padding-oracle-attacker ``` ## CLI Usage ``` Usage $ padding-oracle-attacker decrypt <url> hex:<ciphertext_hex> <block_size> <error> [options] $ padding-oracle-attacker decrypt <url> b64:<ciphertext_b64> <block_size> <error> [options] $ padding-oracle-attacker encrypt <url> <plaintext> <block_size> <error> [options] $ padding-oracle-attacker encrypt <url> hex:<plaintext_hex> <block_size> <error> [options] $ padding-oracle-attacker analyze <url> [<block_size>] [options] Commands decrypt Finds the plaintext (foobar) for given ciphertext (hex:0123abcd) encrypt Finds the ciphertext (hex:abcd1234) for given plaintext (foo=bar) analyze Helps find out if the URL is vulnerable or not, and how the response differs when a decryption error occurs (for the <error> argument) Arguments <url> URL to attack. Payload will be inserted at the end by default. To specify a custom injection point, include {POPAYLOAD} in a header (-H), request body (-d) or the URL <block_size> Block size used by the encryption algorithm on the server <error> The string present in response when decryption fails on the server. Specify a string present in the HTTP response body (like PaddingException) or status code of the HTTP response (like 400) Options -c, --concurrency Requests to be sent concurrently [default: 128] --disable-cache Disable network cache. Saved to [default: false] poattack-cache.json.gz.txt by default -X, --method HTTP method to use while making request [default: GET] -H, --header Headers to be sent with request. -H 'Cookie: cookie1' -H 'User-Agent: Googlebot/2.1' -d, --data Request body JSON string: {"id": 101, "foo": "bar"} URL encoded: id=101&foo=bar Make sure to specify the Content-Type header. -e, --payload-encoding Ciphertext payload encoding for {POPAYLOAD} [default: hex] base64 FooBar+/= base64-urlsafe FooBar-_ hex deadbeef hex-uppercase DEADBEEF base64(xyz) Custom base64 ('xyz' represent characters for '+/=') --dont-urlencode-payload Don't URL encode {POPAYLOAD} [default: false] --start-from-1st-block Start processing from the first block instead [default: false] of the last (only works with decrypt mode) Examples $ poattack decrypt http://localhost:2020/decrypt?ciphertext= hex:e3e70d8599206647dbc96952aaa209d75b4e3c494842aa1aa8931f51505df2a8a184e99501914312e2c50320835404e9 16 400 $ poattack encrypt http://localhost:2020/decrypt?ciphertext= "foo bar 🦄" 16 400 $ poattack encrypt http://localhost:2020/decrypt?ciphertext= hex:666f6f2062617220f09fa684 16 400 $ poattack analyze http://localhost:2020/decrypt?ciphertext= Aliases poattack padding-oracle-attack ``` ## Library API ```js const { decrypt, encrypt } = require('padding-oracle-attacker') // or import { decrypt, encrypt } from 'padding-oracle-attacker' const { blockCount, totalSize, foundBytes, interBytes } = await decrypt(options) const { blockCount, totalSize, foundBytes, interBytes, finalRequest } = await encrypt(options) ``` #### `decrypt(options: Object): Promise` #### `encrypt(options: Object): Promise` ##### Required options ###### `url: string` URL to attack. Payload will be appended at the end by default. To specify a custom injection point, include `{POPAYLOAD}` in the URL, a header (`requestOptions.headers`) or the request body (`requestOptions.data`) ###### `blockSize: number` Block size used by the encryption algorithm on the server. ###### `isDecryptionSuccess: ({ statusCode, headers, body }) => boolean` Function that returns true if the server response indicates decryption was successful. ###### `ciphertext: Buffer` (`decrypt` only) Ciphertext to decrypt. ###### `plaintext: Buffer` (`encrypt` only) Plaintext to encrypt. Padding will be added automatically. Example: `Buffer.from('foo bar', 'utf8')` --- ##### Optional options ###### `concurrency: number = 128` Network requests to be sent concurrently. ###### `isCacheEnabled: boolean = true` Responses are cached by default and saved to `poattack-cache.json.gz.txt`. Set to `false` to disable caching. ###### `requestOptions: { method, headers, data }` ###### `requestOptions.method: string` HTTP method to use while making the request. `GET` by default. `POST`, `PUT`, `DELETE` are some valid options. ###### `requestOptions.headers: { string: string }` Headers to be sent with request. Example: `{ 'Content-Type': 'application/x-www-form-urlencoded' }` ###### `requestOptions.body: string` Request body. Can be a JSON string, URL encoded params etc. `Content-Type` header has to be set manually. ###### `logMode: 'full'|'minimal'|'none' = 'full'` `full`: Log everything to console (default) `minimal`: Log only after start and completion to console `none`: Log nothing to console ###### `transformPayload: (ciphertext: Buffer) => string` Function to convert the `ciphertext` into a string when making a request. By default, `ciphertext` is encoded in hex and inserted at the injection point (URL end unless `{POPAYLOAD}` is present). --- ##### Optional options (`decrypt` only) ###### `alreadyFound: Buffer` Plaintext bytes already known/found that can be skipped (from the end). If you provide a `Buffer` of ten bytes, the last ten bytes will be skipped. ###### `initFirstPayloadBlockWithOrigBytes: boolean = false` Initialize first payload block with original `ciphertext` bytes instead of zeroes. Example: `abcdef12345678ff 1111111111111111` instead of `00000000000000ff 1111111111111111` ###### `startFromFirstBlock: boolean = false` Start processing from the first block instead of the last. ###### `makeInitialRequest: boolean = true` Make an initial request with the original `ciphertext` provided and log server response to console to allow the user to make sure network requests are being sent correctly. --- ##### Optional options (`encrypt` only) ###### `makeFinalRequest: boolean = true` After finding the `ciphertext` bytes for the new `plaintext`, make a final request with the found bytes and log the server response to console. ###### `lastCiphertextBlock: Buffer` Custom ciphertext for the last block. Last block is just zeroes by default (`000000000000000`). ## Developing `padding-oracle-attacker` is written in TypeScript. If you'd like to modify the source files and run them, you can either compile the files into JS first and run them using node, or use [ts-node](https://www.npmjs.com/package/ts-node). Example: `yarn build` then `node dist/cli ...` or simply `ts-node src/cli ...` ##### `yarn build` or `npm run build` Builds the TypeScript files inside the `src` directory to JS files and outputs them to the `dist` directory. ##### `yarn clean` or `npm run clean` Deletes the `dist` directory. ##### `yarn lint` or `npm run lint` Lints the files using eslint. ##### `yarn test` or `npm run test` Lints and runs the tests using ava. ##### `node test/helpers/vulnerable-server.js` Runs the test server which is vulnerable to padding oracle attacks at <http://localhost:2020> ## Related * [PadBuster](https://github.com/GDSSecurity/PadBuster) (Perl) * [Padding Oracle Attack](https://github.com/mpgn/Padding-oracle-attack) (Python) * [python-paddingoracle](https://github.com/mwielgoszewski/python-paddingoracle) (Python) * [Poracle](https://github.com/iagox86/poracle) (Ruby) * [GoPaddy](https://github.com/glebarez/GoPaddy) (Go) * [pax](https://github.com/liamg/pax) (Go) ## License MIT © [Kishan Bagaria](https://kishanbagaria.com)