Need help with padding-oracle-attacker?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

146 Stars 32 Forks MIT License 54 Commits 1 Opened issues


🔓 CLI tool and library to execute padding oracle attacks easily, with support for concurrent network requests and an elegant UI.

Services available


Need anything else?

Contributors list

# 32,902
46 commits


CLI tool and library to execute padding oracle attacks easily, with support for concurrent network requests and an elegant UI.

poattack decrypt demo

Build Status


Make sure Node.js is installed, then run

$ npm install --global padding-oracle-attacker


$ yarn global add padding-oracle-attacker

CLI Usage

  $ padding-oracle-attacker decrypt  hex:   [options]
  $ padding-oracle-attacker decrypt  b64:   [options]

$ padding-oracle-attacker encrypt

<block_size> <error> [options] $ padding-oracle-attacker encrypt <url> hex:<plaintext_hex> <block_size> <error> [options]</p> <p> $ padding-oracle-attacker analyze <url> [<block_size>] [options]</p> <p>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)</p> <p>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)</p> <p>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 &#39;Cookie: cookie1&#39; -H &#39;User-Agent: Googlebot/2.1&#39; -d, --data Request body JSON string: {&quot;id&quot;: 101, &quot;foo&quot;: &quot;bar&quot;} URL encoded: id=101&amp;foo=bar Make sure to specify the Content-Type header.</p> <p> -e, --payload-encoding Ciphertext payload encoding for {POPAYLOAD} [default: hex] base64 FooBar+/= base64-urlsafe FooBar-_ hex deadbeef hex-uppercase DEADBEEF base64(xyz) Custom base64 (&#39;xyz&#39; represent characters for &#39;+/=&#39;)</p> <p> --dont-urlencode-payload Don&#39;t URL encode {POPAYLOAD} [default: false]</p> <p> --start-from-1st-block Start processing from the first block instead [default: false] of the last (only works with decrypt mode)</p> <p>Examples $ poattack decrypt <a href="http://localhost:2020/decrypt?ciphertext=">http://localhost:2020/decrypt?ciphertext=</a> hex:e3e70d8599206647dbc96952aaa209d75b4e3c494842aa1aa8931f51505df2a8a184e99501914312e2c50320835404e9 16 400 $ poattack encrypt <a href="http://localhost:2020/decrypt?ciphertext=">http://localhost:2020/decrypt?ciphertext=</a> &quot;foo bar 🦄&quot; 16 400 $ poattack encrypt <a href="http://localhost:2020/decrypt?ciphertext=">http://localhost:2020/decrypt?ciphertext=</a> hex:666f6f2062617220f09fa684 16 400 $ poattack analyze <a href="http://localhost:2020/decrypt?ciphertext=">http://localhost:2020/decrypt?ciphertext=</a></p> <p>Aliases poattack padding-oracle-attack </error></block_size></url></error></block_size></url></error></block_size></plaintext_hex></url></error></block_size></plaintext></url></error></block_size></ciphertext_b64></url></error></block_size></ciphertext_hex></url></pre></p> <h2>Library API</h2> <pre class="language-js">const { decrypt, encrypt } = require('padding-oracle-attacker') // or import { decrypt, encrypt } from 'padding-oracle-attacker' <p>const { blockCount, totalSize, foundBytes, interBytes } = await decrypt(options)</p> <p>const { blockCount, totalSize, foundBytes, interBytes, finalRequest } = await encrypt(options) </pre></p> <h4><pre>decrypt(options: Object): Promise</pre></h4> <h4><pre>encrypt(options: Object): Promise</pre></h4> <h5>Required options</h5> <h6><pre>url: string</pre></h6> <p>URL to attack. Payload will be appended at the end by default. To specify a custom injection point, include </p><pre>{POPAYLOAD}</pre> in the URL, a header (<pre>requestOptions.headers</pre>) or the request body (<pre></pre>) <h6><pre>blockSize: number</pre></h6> <p>Block size used by the encryption algorithm on the server.</p> <h6><pre>isDecryptionSuccess: ({ statusCode, headers, body }) =&gt; boolean</pre></h6> <p>Function that returns true if the server response indicates decryption was successful.</p> <h6> <pre>ciphertext: Buffer</pre> (<pre>decrypt</pre> only)</h6> <p>Ciphertext to decrypt.</p> <h6> <pre>plaintext: Buffer</pre> (<pre>encrypt</pre> only)</h6> <p>Plaintext to encrypt. Padding will be added automatically. Example: </p><pre>Buffer.from('foo bar', 'utf8')</pre> <hr> <h5>Optional options</h5> <h6><pre>concurrency: number = 128</pre></h6> <p>Network requests to be sent concurrently.</p> <h6><pre>isCacheEnabled: boolean = true</pre></h6> <p>Responses are cached by default and saved to </p><pre>poattack-cache.json.gz.txt</pre>. Set to <pre>false</pre> to disable caching. <h6><pre>requestOptions: { method, headers, data }</pre></h6> <h6><pre>requestOptions.method: string</pre></h6> <p>HTTP method to use while making the request. </p><pre>GET</pre> by default. <pre>POST</pre>, <pre>PUT</pre>, <pre>DELETE</pre> are some valid options. <h6><pre>requestOptions.headers: { string: string }</pre></h6> <p>Headers to be sent with request. Example: </p><pre>{ 'Content-Type': 'application/x-www-form-urlencoded' }</pre> <h6><pre>requestOptions.body: string</pre></h6> <p>Request body. Can be a JSON string, URL encoded params etc. </p><pre>Content-Type</pre> header has to be set manually. <h6><pre>logMode: 'full'|'minimal'|'none' = 'full'</pre></h6> <p></p><pre>full</pre>: Log everything to console (default)<br> <pre>minimal</pre>: Log only after start and completion to console<br> <pre>none</pre>: Log nothing to console <h6><pre>transformPayload: (ciphertext: Buffer) =&gt; string</pre></h6> <p>Function to convert the </p><pre>ciphertext</pre> into a string when making a request. By default, <pre>ciphertext</pre> is encoded in hex and inserted at the injection point (URL end unless <pre>{POPAYLOAD}</pre> is present). <hr> <h5>Optional options (<pre>decrypt</pre> only)</h5> <h6><pre>alreadyFound: Buffer</pre></h6> <p>Plaintext bytes already known/found that can be skipped (from the end). If you provide a </p><pre>Buffer</pre> of ten bytes, the last ten bytes will be skipped. <h6><pre>initFirstPayloadBlockWithOrigBytes: boolean = false</pre></h6> <p>Initialize first payload block with original </p><pre>ciphertext</pre> bytes instead of zeroes.<br> Example: <pre>abcdef12345678ff 1111111111111111</pre> instead of <pre>00000000000000ff 1111111111111111</pre> <h6><pre>startFromFirstBlock: boolean = false</pre></h6> <p>Start processing from the first block instead of the last.</p> <h6><pre>makeInitialRequest: boolean = true</pre></h6> <p>Make an initial request with the original </p><pre>ciphertext</pre> provided and log server response to console to allow the user to make sure network requests are being sent correctly. <hr> <h5>Optional options (<pre>encrypt</pre> only)</h5> <h6><pre>makeFinalRequest: boolean = true</pre></h6> <p>After finding the </p><pre>ciphertext</pre> bytes for the new <pre>plaintext</pre>, make a final request with the found bytes and log the server response to console. <h6><pre>lastCiphertextBlock: Buffer</pre></h6> <p>Custom ciphertext for the last block. Last block is just zeroes by default (</p><pre>000000000000000</pre>). <h2>Developing</h2> <p></p><pre>padding-oracle-attacker</pre> 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 <a href="">ts-node</a>.<br> Example: <pre>yarn build</pre> then <pre>node dist/cli ...</pre> or simply <pre>ts-node src/cli ...</pre> <h5> <pre>yarn build</pre> or <pre>npm run build</pre> </h5> <p>Builds the TypeScript files inside the </p><pre>src</pre> directory to JS files and outputs them to the <pre>dist</pre> directory. <h5> <pre>yarn clean</pre> or <pre>npm run clean</pre> </h5> <p>Deletes the </p><pre>dist</pre> directory. <h5> <pre>yarn lint</pre> or <pre>npm run lint</pre> </h5> <p>Lints the files using eslint.</p> <h5> <pre>yarn test</pre> or <pre>npm run test</pre> </h5> <p>Lints and runs the tests using ava.</p> <h5><pre>node test/helpers/vulnerable-server.js</pre></h5> <p>Runs the test server which is vulnerable to padding oracle attacks at <a href="http://localhost:2020">http://localhost:2020</a></p> <h2>Related</h2> <ul> <li> <a href="">PadBuster</a> (Perl)</li> <li> <a href="">Padding Oracle Attack</a> (Python)</li> <li> <a href="">python-paddingoracle</a> (Python)</li> <li> <a href="">Poracle</a> (Ruby)</li> <li> <a href="">GoPaddy</a> (Go)</li> <li> <a href="">pax</a> (Go)</li> <li> <a href="">padre</a> (Go)</li> <li> <a href="">Padantic</a> (Rust)</li> <li> <a href="">Padoracle</a> (JavaScript)</li> </ul> <h2>License</h2> <p>MIT © <a href="">Kishan Bagaria</a></p></plaintext></error></block_size></ciphertext_b64></url></error></block_size></ciphertext_hex></url></pre>

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.