Didier Stevens

Monday 22 August 2016

Update: xor-kpa.py Version 0.0.3 With Man Page

Filed under: Encryption,My Software — Didier Stevens @ 0:00

This new version has a man page now (option -m):

Usage: xor-kpa.py [options] filename-plaintext [filename-ciphertext]
XOR known-plaintext attack

Predefined plaintext:
 dos: This program cannot be run in DOS mode

Source code put in the public domain by Didier Stevens, no Copyright
Use at your own risk
https://DidierStevens.com

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -m, --man             Print manual
  -n, --name            Use predefined plaintext
  -e EXTRA, --extra=EXTRA
                        Minimum number of extras
  -d, --decode          Decode the ciphertext

Manual:

xor-kpa performs a known-plaintext attack (KPA) on an XOR-encoded file. Take a
file with content "This is a secret message, do not share!". This file is XOR-
encoded like this: the key is ABC, the first byte of the file is XORed with A,
the second byte of the file is XORed with B, the third byte of the file is
XORed with C, the fourth byte of the file is XORed with A, the fifth byte of
the file is XORed with B, ...
If you know part of the plaintext of this file, and that plaintext is longer
than the key, then xor-kpa can recover the key.

xor-kpa tries to recover the key as follows. xor-kpa encodes the encoded file
with the provided plaintext: if you XOR-encode an XOR-encoded file
(ciphertext) again with its plaintext, then the result is the keystream (the
key repeated): ABCABCABC... xor-kpa detects such keystreams and extracts the
key.

Example:
 xor-kpa.py "#secret message" encoded.txt
Output:
 Key:       ABC
 Extra:     11
 Keystream: BCABCABCABCABC

In this example, we assume that the plaintext contains "secret message". xor-
kpa finds one keystream: BCABCABCABCABC. From this keystream, xor-kpa extracts
the key: ABC.
Extra is the number of extra charecters in the keystream: the keystream is 14
characters longh, the key is 3 characters long, so extra is 14 - 3 = 11. It is
a measure for the probability that the recovered key is the actual key. The
longer it is, the better.
In this case, because the ciphertext is a small file, xor-kpa found only one
keystream. But for larger files or small plaintext, it will identify more than
one potential keystream.

Example:
 xor-kpa.py #secret encoded.txt
Output:
 Key:       ABC
 Extra:     3
 Keystream: BCABCA

 Key:       'KUW^'
 Extra:     1
 Keystream: '^KUW^'

 Key:       'S@E'
 Extra:     1
 Keystream: 'S@ES'

In this example, xor-kpa has identified 3 potential keys. The potential keys
are sorted by descending extra-value. So the most promising keys are listed
first.
Keystreams with an extra value of 1 (1 extra character) rarely contain the
correct key.
Option -e (--extra) allows us to reduce the amount of displayed potential keys
by specifying the minimum value for extras.

Example:
 xor-kpa.py -e 2 #secret encoded.txt
Output:
 Key:       ABC
 Extra:     3
 Keystream: BCABCA

With option -e 2 we specify that the keystream must at least have 2 extras.
That's why the keystreams with 1 extra are not listed.

xor-kpa can also decode the ciphertext file with the recovered key (the key
with the highest extra value). Use option -d (--decode) to do this:

Example:
 xor-kpa.py -d #secret encoded.txt
Output:
 This is a secret message, do not share!

xor-kpa takes one or two arguments. The first argument is a file containing
the plaintext, the second argument is a file containing the ciphertext.
xor-kpa can also read the ciphertext from stdin (for example via a pipe), in
that case the second argument is omitted.
The files can also be ZIP files containing one file (optionally password-
protected with 'infected'), in that case xor-kpa will decompress the content
of the ZIP file and use it.

In stead of putting the plaintext or the ciphertext in a file, it can also be
passed in the argument. To achieve this, precede the text with character #
(this is what we have done in all the examples up till now).
If the text to pass via the argument contains control characters or non-
printable characters, hexadecimal (#h#) or base64 (#b#) can be used.

Example:
 xor-kpa.py -d #h#736563726574 encoded.txt
Output:
 This is a secret message, do not share!

Example:
 xor-kpa.py -d #b#c2VjcmV0 encoded.txt
Output:
 This is a secret message, do not share!

Finally, the plaintext can be selected from a predefined list. For the moment,
the only text in the predefined list is 'This program cannot be run in DOS
mode', identified by the keyword dos. Use option -n (--name) to use predefined
plaintext.

Example:
 xor-kpa.py -n dos malware.vir



xor-kpa_V0_0_3.zip (https)
MD5: 228B9DE1D3005F75190113369A91E1D4
SHA256: A30C20668BA0939DD936BB2706AEC636E5260EFB0B0F16F4770F9B1B59E780A9

Blog at WordPress.com.