This project has two main parts:
- Task 2: classic CBC padding-oracle plaintext recovery (boolean oracle).
- Task 3/4: timing-oracle block recovery against MAC-then-encrypt receiver.
padding_oracle/crypto.py: AES-CBC and PKCS#7 functions.padding_oracle/services.py: vulnerable oracle/receiver services.padding_oracle/protocol.py: TCP protocol (ENCRYPT,CHECK).padding_oracle/attacks/: boolean and timing attack code.padding_oracle/cli.py: CLI commands (server,victim,boolean,timing,attacker).padding_oracle/timing_stats.py: benchmark for long path vs short path.padding_oracle/noise_experiment.py: benchmark with injected timing noise.tests/: unit tests.
This is a Python project, so there is no compile step before running.
Installation means installing required Python packages.
This README uses local virtual environment (.venv) for all commands.
Prerequisites:
- Python
>=3.10(inMakefile, default ispython3.12withSYSTEM_PYTHON). python3-pipfor package install.python3-venv(required).make(optional, but useful).
Ubuntu 24.04 package install:
sudo apt update
sudo apt install -y python3 python3-pip python3-venv makeOption A: setup with make:
make venv
make installOption B: setup without make:
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -r requirements.txtOptional editable install (adds padding-oracle command):
# with make
make install-editable
# without make
.venv/bin/python -m pip install -e .Quick sanity check:
.venv/bin/python -m padding_oracle.cli --helpRun all tests:
# with make
make test
# without make
.venv/bin/python -m unittest discover -s tests -vHow to interpret test output:
- If one test is good, it ends with
... ok. - At the end you should see
OKfor full pass. - If you see
FAILorERROR, tests did not pass. - Non-zero exit code also means there is failing/error test.
This benchmark measures timing gap between two cases:
long path: padding is valid, then MAC check runs (and fails after).short path: padding is invalid, so reject happens early.
Commands:
# with make
make timing-stats ARGS='--trials 10000 --warmup 500 --message-kb 1'
make timing-stats ARGS="--trials 10000 --warmup 500 --message 'hello world'"
# without make
.venv/bin/python -m padding_oracle.timing_stats --trials 10000 --warmup 500 --message-kb 1
.venv/bin/python -m padding_oracle.timing_stats --trials 10000 --warmup 500 --message "hello world"How to interpret output:
delta_avg_ms (long-short): if positive, long path is slower (this is expected leak direction).signal: LONG>SHORT: expected sign, usually good for attack signal.signal: LONG<SHORTor very close to zero: weak signal, use more trials or less noise.
This benchmark repeats timing recovery with added Gaussian jitter. It reports success rate and cost.
Commands:
# with make
make noise-experiment
make noise-experiment ARGS='--message-kb 1 --runs 5 --jitter-levels-us 0 10 25 50 100 250'
# without make
.venv/bin/python -m padding_oracle.noise_experiment
.venv/bin/python -m padding_oracle.noise_experiment --message-kb 1 --runs 5 --jitter-levels-us 0 10 25 50 100 250How to interpret output:
- Each run prints
success,queries, andelapsed_ms. - Final table has:
jitter_us: jitter level (microseconds).success_rate: how many runs succeeded at this jitter.avg_queries: average oracle queries.avg_time_ms: average runtime.
- Script also writes detailed rows to
noise_results.csv. - Usually with larger jitter,
success_rategoes down and query/time go up.
Run local demos:
# boolean demo
make boolean
.venv/bin/python -m padding_oracle.cli boolean
# timing demo
make timing
.venv/bin/python -m padding_oracle.cli timing
# timing demo with message size override
make timing ARGS='--message-kb 4'
.venv/bin/python -m padding_oracle.cli timing --message-kb 4- Start victim/oracle on machine B:
# with make
make victim ARGS='--addr 0.0.0.0:4000'
# without make
.venv/bin/python -m padding_oracle.cli victim --addr 0.0.0.0:4000Optional fixed keys:
# with make
make victim ARGS='--addr 0.0.0.0:4000 --enc-key <hex_aes_key> --mac-key <hex_mac_key>'
# without make
.venv/bin/python -m padding_oracle.cli victim \
--addr 0.0.0.0:4000 \
--enc-key <hex_aes_key> \
--mac-key <hex_mac_key>- Run attacker on machine A against machine B:
# with make
make attacker ARGS='--addr <victim_ip>:4000 --message-kb 16'
# without make
.venv/bin/python -m padding_oracle.cli attacker --addr <victim_ip>:4000 --message-kb 16Enable progress logging:
# with make
make attacker ARGS='--addr <victim_ip>:4000 --message-kb 16 --log-progress'
# without make
.venv/bin/python -m padding_oracle.cli attacker --addr <victim_ip>:4000 --message-kb 16 --log-progressNotes:
- Victim must bind to a reachable interface (
0.0.0.0or a specific LAN IP). - Open firewall/security rules for the selected TCP port.
timingis a self-contained localhost demo;attackeris the split deployment command.