From a8d1eb8f8d82e5adc285c8b0139701d130163c67 Mon Sep 17 00:00:00 2001 From: Cameron Lonsdale Date: Wed, 5 Jun 2019 18:15:11 +1000 Subject: [PATCH] Add image shift example program --- examples/shift/example.png | Bin 0 -> 32206 bytes examples/shift/image_shift.py | 23 +++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 examples/shift/example.png create mode 100755 examples/shift/image_shift.py diff --git a/examples/shift/example.png b/examples/shift/example.png new file mode 100644 index 0000000000000000000000000000000000000000..25ab0b8e6dd9e072f5a6e2ad42dacdf917ba78cf GIT binary patch literal 32206 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 E56|V~-~a#s literal 0 HcmV?d00001 diff --git a/examples/shift/image_shift.py b/examples/shift/image_shift.py new file mode 100755 index 0000000..c9d06ad --- /dev/null +++ b/examples/shift/image_shift.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +from lantern.modules import shift + + +shift_encrypt = lambda key, byte: (byte + key) % 255 +shift_decrypt = lambda key, byte: (byte - key) % 255 + + +with open("example.png", "rb") as image: + image_bytes = bytearray(image.read()) + +KEY = 144 +encrypted_bytes = shift.encrypt(KEY, image_bytes, shift_encrypt) + +print(f"Encrypted header: {encrypted_bytes[:8]}") + +header_matcher = lambda value: 0 if value[:8] == [137, 80, 78, 71, 13, 10, 26, 10] else -1 + +# Decrypt the image by finding a matching PNG header +decryptions = shift.crack(encrypted_bytes, header_matcher, min_key=0, max_key=255, shift_function=shift_decrypt) + +print(f"Decrypted Header: {decryptions[0].plaintext[:8]}")