Skip to content

Commit

Permalink
🗓 Sep 4, 2023 11:43:47 AM
Browse files Browse the repository at this point in the history
🐙 plugins updated
✨ huffman encode/decode
🐙 helper functions
🧪 tests added/updated
  • Loading branch information
securisec committed Sep 4, 2023
1 parent 8234ce7 commit b5d7b20
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 35 deletions.
28 changes: 2 additions & 26 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ New ideas:
☐ ✨ aes cmac
☐ ✨ cetacean encode/decode
☐ ✨ whitespace encoding https://www.dcode.fr/whitespace-language
☐ ✨ huffman encode/decode
☐ ✨ new plugin that can help detect encoding type trained on random data

Bug:

Expand Down Expand Up @@ -62,28 +60,6 @@ Misc:
☐ cyberchef recipe to chepy recipe converter

Archive:
✔ ✨ huffman encode/decode
✔ ✨ new plugin that can help detect encoding type trained on random data
✔ ✨ bifd
✔ ✨ to/from messagepack
✔ ✨ upside down writing
✔ ✨ bacon encode/decode
✔ rsa enc/dec with key or from pem directly
✔ ✨ to/from pickle
✔ ✨ ls47 enc/dec
✔ ✨ shuffle
✔ 🚀 add crib for xor bruteforce
✔ ✨ twin hex encoder/decoder
✔ ✨ base36 encoder decoder
✔ ✨ decorator that will show warning message if unexpected results in stdout
✔ ✨ concat method
✔ ✨ nt hash
✔ ✨ lm hash
✔ ✨ lz4 compression/decompression
✔ 🚀 improve aes ctr enc/dec to handle iv
✔ stringify method using json.dumps
✔ jwt none algo
✔ ✨ extractor partially done
✔ vigenere make aware of all cases/numbers/specials. i.e. npcdhzaon{a4Rmp!_K1N5q0p_4vQfKkT1uA3R} key victory shaktictf{y4Yyy!_M1S5i0n_4cCoMpL1sH3D}
✔ us-ascii 7bit 20127 https://gchq.github.io/CyberChef/#recipe=Encode_text('US-ASCII%20(7-bit)%20(20127)') 걳걵걮걻걢갴걳갳걟갱갲갸걟갱갵걟걢갱건걟걲갳걭갴거거갱걮걧걽
✔ rot8000
✔ base decode all bases
✔ rename base64 function to from_basexx
2 changes: 1 addition & 1 deletion chepy/chepy_plugins
40 changes: 40 additions & 0 deletions chepy/modules/encryptionencoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -1672,3 +1672,43 @@ def bifid_decode(self, key: Union[str, bytes] = ""):

self.state = output
return self

@ChepyDecorators.call_stack
def huffman_encode(self) -> EncryptionEncodingT:
"""Huffman encode
Returns:
Chepy: The Chepy object.
"""
data = self._convert_to_str()
root = Ciphers.build_huffman_tree(data)
huffman_codes = {}
Ciphers.build_huffman_codes(root, "", huffman_codes)
encoded_data = "".join(huffman_codes[char] for char in data)
self.state = {"encoded": encoded_data, "codes": huffman_codes}
return self

@ChepyDecorators.call_stack
def huffman_decode(self, huffman_codes: Dict[str, str]) -> EncryptionEncodingT:
"""Huffman decode
Args:
huffman_codes (Dict[str, str]): Huffman codes as a dict
Returns:
Chepy: The Chepy object.
"""
decoded_data = ""
current_code = ""

encoded_data = self._convert_to_str()
for bit in encoded_data:
current_code += bit
for char, code in huffman_codes.items():
if code == current_code:
decoded_data += char
current_code = ""
break

self.state = decoded_data
return self
2 changes: 2 additions & 0 deletions chepy/modules/encryptionencoding.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ class EncryptionEncoding(ChepyCore):
def ls47_decrypt(self: EncryptionEncodingT, password: str, padding: int=...) -> EncryptionEncodingT: ...
def bifid_encode(self: EncryptionEncodingT, key: Union[bytes, str]='') -> EncryptionEncodingT: ...
def bifid_decode(self: EncryptionEncodingT, key: Union[bytes, str]='') -> EncryptionEncodingT: ...
def huffman_encode(self: EncryptionEncodingT) -> EncryptionEncodingT: ...
def huffman_decode(self: EncryptionEncodingT, huffman_codes: Dict[str, str]) -> EncryptionEncodingT: ...
46 changes: 44 additions & 2 deletions chepy/modules/internal/constants.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,58 @@
from collections import Counter


class HuffmanNode:
def __init__(self, char, freq):
self.char = char
self.freq = freq
self.left = None
self.right = None


class Ciphers:
@staticmethod
def gen_polybius_square(keyword):
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
pol_array = list(keyword.upper() + alpha)
pol_array = sorted(list(set(pol_array)), key=lambda x: (pol_array.index(x) // 5, pol_array.index(x) % 5))
pol_array = sorted(
list(set(pol_array)),
key=lambda x: (pol_array.index(x) // 5, pol_array.index(x) % 5),
)
polybius = []

for i in range(5):
polybius.append(pol_array[i * 5:i * 5 + 5])
polybius.append(pol_array[i * 5 : i * 5 + 5])

return polybius

@staticmethod
def build_huffman_tree(data):
char_freq = dict(Counter(data))
nodes = [HuffmanNode(char, freq) for char, freq in char_freq.items()]

while len(nodes) > 1:
nodes = sorted(nodes, key=lambda x: x.freq)
left = nodes.pop(0)
right = nodes.pop(0)
parent = HuffmanNode(None, left.freq + right.freq)
parent.left = left
parent.right = right
nodes.append(parent)

return nodes[0]

@staticmethod
def build_huffman_codes(root, current_code, huffman_codes):
if root is None: # pragma: no cover
return

if root.char is not None:
huffman_codes[root.char] = current_code
return

Ciphers.build_huffman_codes(root.left, current_code + "0", huffman_codes)
Ciphers.build_huffman_codes(root.right, current_code + "1", huffman_codes)


class Encoding(object):
UPSIDE_DOWN = {
Expand Down
23 changes: 23 additions & 0 deletions tests/test_encryptionencoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -786,3 +786,26 @@ def test_ls47_enc_dec():

def test_bifid():
assert Chepy("hello").bifid_encode("!H").bifid_decode("!H").o == b"hello"


def test_huffman():
assert Chepy("hello world").huffman_encode().get_by_key("encoded").o != b""
assert (
Chepy("hello world")
.huffman_encode()
.get_by_key("encoded")
.huffman_decode(
{
" ": "000",
"w": "001",
"r": "010",
"d": "011",
"l": "10",
"o": "110",
"h": "1110",
"e": "1111",
}
)
.o
== b"hello world"
)
12 changes: 6 additions & 6 deletions tests_plugins/test_ml.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@


def test_ml_detect():
data = "04224d184070df280000806147567362473867643239796247516761534268625342684948526c633351675a47463059513d3d00000000"
assert (
Chepy("https%3A%2F%2Fwww.pennington.com%2Fcategories%2Fwp-content")
.ml_detect()
.o.get("to_url_encode")
!= None
)
assert Chepy(data).ml_detect().o.get("to_hex") != None
assert Chepy(data).from_hex().ml_detect().o.get("lz4_compress") != None
data = "5ZXN4aSn4N2ZVzGA6Q7NbqCRJa2XBt2CEKAvgDUoQj8x9vBJqcrk5fBKZh5XqdAoKnyXMeNmE21QQAqZcKZPamT8he6s8nYRU1unmSb2eAmnnBv8NWSs9f6BgsJ3DGPpdbPm8b9kDSMDTLfZ1"
assert Chepy(data).ml_detect().o.get("to_base58") != None
assert Chepy(data).from_base58().ml_detect().o.get("to_hex") != None
assert (
Chepy(data).from_hex().lz4_decompress().ml_detect().o.get("to_base64") != None
Chepy(data).from_base58().from_hex().ml_detect().o.get("lzma_compress") != None
)
assert (
Chepy(data).from_hex().lz4_decompress().from_base64().o
== b"hello world i am a test data"
Chepy(data).from_base58().from_hex().lzma_decompress().o
== b"some data with an encoded flag"
)

0 comments on commit b5d7b20

Please sign in to comment.