Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/hellman/xortool

A tool to analyze multi-byte xor cipher
https://github.com/hellman/xortool

cryptanalysis cryptography xor-cipher xortool

Last synced: 28 days ago
JSON representation

A tool to analyze multi-byte xor cipher

Awesome Lists containing this project

README

        

xortool.py
====================

A tool to do some xor analysis:

- guess the key length (based on count of equal chars)
- guess the key (base on knowledge of most frequent char)

**Notice:** xortool is now only running on Python 3. The old Python 2 version is accessible at the `py2` branch. The **pip** package has been updated.

## Installation

```bash
$ pip3 install xortool
```

For development or building this repository, [poetry](https://python-poetry.org/) is needed.

```bash
poetry build
pip install dist/xortool*.whl
```

Usage
---------------------

```
xortool
A tool to do some xor analysis:
- guess the key length (based on count of equal chars)
- guess the key (base on knowledge of most frequent char)

Usage:
xortool [-x] [-m MAX-LEN] [-f] [-t CHARSET] [FILE]
xortool [-x] [-l LEN] [-c CHAR | -b | -o] [-f] [-t CHARSET] [-p PLAIN] [FILE]
xortool [-x] [-m MAX-LEN| -l LEN] [-c CHAR | -b | -o] [-f] [-t CHARSET] [-p PLAIN] [FILE]
xortool [-h | --help]
xortool --version

Options:
-x --hex input is hex-encoded str
-l LEN, --key-length=LEN length of the key
-m MAX-LEN, --max-keylen=MAX-LEN maximum key length to probe [default: 65]
-c CHAR, --char=CHAR most frequent char (one char or hex code)
-b --brute-chars brute force all possible most frequent chars
-o --brute-printable same as -b but will only check printable chars
-f --filter-output filter outputs based on the charset
-t CHARSET --text-charset=CHARSET target text character set [default: printable]
-p PLAIN --known-plaintext=PLAIN use known plaintext for decoding
-h --help show this help

Notes:
Text character set:
* Pre-defined sets: printable, base32, base64
* Custom sets:
- a: lowercase chars
- A: uppercase chars
- 1: digits
- !: special chars
- *: printable chars

Examples:
xortool file.bin
xortool -l 11 -c 20 file.bin
xortool -x -c ' ' file.hex
xortool -b -f -l 23 -t base64 message.enc
xortool -b -p "xctf{" message.enc
```

Example 1
---------------------

```bash
# xor is xortool/xortool-xor
tests $ xor -f /bin/ls -s "secret_key" > binary_xored

tests $ xortool binary_xored
The most probable key lengths:
2: 5.0%
5: 8.7%
8: 4.9%
10: 15.4%
12: 4.8%
15: 8.5%
18: 4.8%
20: 15.1%
25: 8.4%
30: 14.9%
Key-length can be 5*n
Most possible char is needed to guess the key!

# 00 is the most frequent byte in binaries
tests $ xortool binary_xored -l 10 -c 00
...
1 possible key(s) of length 10:
secret_key

# decrypted ciphertexts are placed in ./xortool_out/Number_
# ( have no better idea )
tests $ md5sum xortool_out/0_secret_key /bin/ls
29942e290876703169e1b614d0b4340a xortool_out/0_secret_key
29942e290876703169e1b614d0b4340a /bin/ls
```

The most common use is to pass just the encrypted file and the most frequent character (usually 00 for binaries and 20 for text files) - length will be automatically chosen:

```bash
tests $ xortool tool_xored -c 20
The most probable key lengths:
2: 5.6%
5: 7.8%
8: 6.0%
10: 11.7%
12: 5.6%
15: 7.6%
20: 19.8%
25: 7.8%
28: 5.7%
30: 11.4%
Key-length can be 5*n
1 possible key(s) of length 20:
an0ther s3cret \xdd key
```

Here, the key is longer then default 32 limit:

```bash
tests $ xortool ls_xored -c 00 -m 64
The most probable key lengths:
3: 3.3%
6: 3.3%
9: 3.3%
11: 7.0%
22: 6.9%
24: 3.3%
27: 3.2%
33: 18.4%
44: 6.8%
55: 6.7%
Key-length can be 3*n
1 possible key(s) of length 33:
really long s3cr3t k3y... PADDING
```

So, if automated decryption fails, you can calibrate:

- (`-m`) max length to try longer keys
- (`-l`) selected length to see some interesting keys
- (`-c`) the most frequent char to produce right plaintext

Example 2
---------------------

We are given a message in encoded in Base64 and XORed with an unknown key.

```bash
# xortool message.enc
The most probable key lengths:
2: 12.3%
4: 13.8%
6: 10.5%
8: 11.5%
10: 8.6%
12: 9.4%
14: 7.1%
16: 7.8%
23: 10.4%
46: 8.7%
Key-length can be 4*n
Most possible char is needed to guess the key!
```

We can now test the key lengths while filtering the outputs so that it only keeps the plaintexts holding the character set of Base64. After trying a few lengths, we come to the right one, which gives only 1 plaintext with a percentage of valid characters above the default threshold of 95%.

```bash
$ xortool message.enc -b -f -l 23 -t base64
256 possible key(s) of length 23:
\x01=\x121#"0\x17\x13\t\x7f ,&/\x12s\x114u\x170#
\x00<\x130"#1\x16\x12\x08~!-\'.\x13r\x105t\x161"
\x03?\x103! 2\x15\x11\x0b}".$-\x10q\x136w\x152!
\x02>\x112 !3\x14\x10\n|#/%,\x11p\x127v\x143
\x059\x165\'&4\x13\x17\r{$("+\x16w\x150q\x134\'
...
Found 1 plaintexts with 95.0%+ valid characters
See files filename-key.csv, filename-char_used-perc_valid.csv
```

By filtering the outputs on the character set of Base64, we directly keep the only solution.

Information
---------------------

Author: hellman

License: [MIT License](https://opensource.org/licenses/MIT)