Skip to content

Commit

Permalink
🗓 Nov 4, 2023 2:10:45 PM
Browse files Browse the repository at this point in the history
✨ to/from_uuencode
✨ split_chunks
🧪 tests added/updated
✨ new helpers
  • Loading branch information
securisec committed Nov 4, 2023
1 parent e5e2638 commit 45d5886
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 5 deletions.
2 changes: 1 addition & 1 deletion chepy/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = "6.4.0" # pragma: no cover
__version__ = "6.5.0" # pragma: no cover
__author__ = "@securisec" # pragma: no cover
2 changes: 1 addition & 1 deletion chepy/chepy_plugins
28 changes: 27 additions & 1 deletion chepy/modules/dataformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import itertools
from random import randint
from .internal.constants import Encoding
from .internal.helpers import detect_delimiter, Rotate, Uint1Array
from .internal.helpers import detect_delimiter, Rotate, Uint1Array, UUEncoderDecoder

yaml = lazy_import.lazy_module("yaml")
import regex as re
Expand Down Expand Up @@ -2026,3 +2026,29 @@ def from_utf21(self) -> DataFormatT:

self.state = bytes(codepoints)
return self

@ChepyDecorators.call_stack
def to_uuencode(self, header: str = "-") -> DataFormatT:
"""To UUEncode
Args:
header (str): header
Returns:
Chepy: The Chepy object.
"""
self.state = UUEncoderDecoder(self._convert_to_bytes(), header).uuencode()
return self

@ChepyDecorators.call_stack
def from_uuencode(self, header: str = "-") -> DataFormatT:
"""From UUEncode
Args:
header (str): header
Returns:
Chepy: The Chepy object.
"""
self.state = UUEncoderDecoder(self._convert_to_bytes(), header).uudecode()
return self
2 changes: 2 additions & 0 deletions chepy/modules/dataformat.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,5 @@ class DataFormat(ChepyCore):
def flatten(self: DataFormatT) -> DataFormatT: ...
def to_utf21(self: DataFormatT) -> DataFormatT: ...
def from_utf21(self: DataFormatT) -> DataFormatT: ...
def to_uuencode(self: DataFormatT, header: str='-') -> DataFormatT: ...
def from_uuencode(self: DataFormatT, header: str='-') -> DataFormatT: ...
37 changes: 37 additions & 0 deletions chepy/modules/internal/helpers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,41 @@
from typing import List, Union
import binascii


class UUEncoderDecoder:
def __init__(self, data: bytes, header: str = "-"):
self.data = data
self.header = header

def split_data(self, data, chunk_size=45):
for i in range(0, len(data), chunk_size):
yield self.data[i : i + chunk_size]

def uuencode(self):
encoded_chunks = []
for chunk in self.split_data(self.data):
encoded_data = binascii.b2a_uu(chunk)
encoded_chunks.append(encoded_data.decode("utf-8"))

# UUencode header and footer
header = f"begin 644 {self.header}\n"
footer = " \nend\n"

return header + "\n".join(encoded_chunks) + footer

def uudecode(self):
lines = self.data.strip().split(b"\n")
if len(lines) < 3 or b"begin 644" not in lines[0].lower(): # pragma: no cover
raise ValueError("Invalid UUencode format. Missing header")

data_lines = lines[1:-1] # Remove header and footer

decoded_data = []
for line in data_lines:
decoded_chunk = binascii.a2b_uu(line)
decoded_data.append(decoded_chunk)

return b"".join(decoded_data)


class Uint1Array:
Expand Down
21 changes: 19 additions & 2 deletions chepy/modules/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,23 @@ def select_every_n(self, n: int, start: int = 0) -> UtilsT:
self.state = self.state[start::n]
return self

@ChepyDecorators.call_stack
def split_chunks(self, chunk_size) -> UtilsT:
"""Split data in chunks
Args:
chunk_size (int): Chunk size
Returns:
Chepy: The Chepy object.
"""
data = self._convert_to_bytes()
data_chunks = []
for i in range(0, len(data), chunk_size):
data_chunks.append(data[i : i + chunk_size])
self.state = data_chunks
return self

@ChepyDecorators.call_stack
def unique(self) -> UtilsT:
"""Get an array of unique list items
Expand Down Expand Up @@ -533,7 +550,7 @@ def diff(
buffer: int = None,
colors: bool = False,
swap: bool = False,
only_changes: bool = False
only_changes: bool = False,
):
"""Diff state with another state or buffer
Expand Down Expand Up @@ -586,7 +603,7 @@ def process_tag(tag, i1, i2, j1, j2) -> UtilsT: # pragma: no cover
return "{-" + matcher.a[i1:i2] + "}"
if tag == "equal":
if only_changes:
return ''
return ""
return matcher.a[i1:i2]
if tag == "insert":
if colors:
Expand Down
1 change: 1 addition & 0 deletions chepy/modules/utils.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Utils(ChepyCore):
def split_by_regex(self: UtilsT, pattern: str=..., trim: Any=...) -> UtilsT: ...
def split_by_n(self: UtilsT, n: int) -> UtilsT: ...
def split_lines(self: UtilsT) -> UtilsT: ...
def split_chunks(self: UtilsT, chunk_size: int) -> UtilsT: ...
def select_every_n(self: UtilsT, n: int, start: int=...) -> UtilsT: ...
def unique(self: UtilsT) -> UtilsT: ...
def sort_list(self: UtilsT, reverse: bool=...) -> UtilsT: ...
Expand Down
10 changes: 10 additions & 0 deletions tests/test_dataformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -724,3 +724,13 @@ def test_utf21():
]
assert Chepy(bytes(flag)).from_utf21().o == b"UDCTF{7w3nty_0n3?_Y0u_57up1d!}"
assert Chepy("UDCTF{7w3nty_0n3?_Y0u_57up1d!}").to_utf21().o == bytes(flag)


def test_uuencode():
data = """HI ZERO IM TRYING A NEW ENCRYPTION
EKO{UUENC0DED_ENCRYPTED?}"""
assert (
b"EKO{UUENC0DED_ENCRYPTED?}"
in Chepy(data).to_uuencode().from_uuencode().remove_nullbytes().o
)
7 changes: 7 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ def test_split_lines():
)


def test_split_chunks():
data = "hello world"
c1 = Chepy(data).split_chunks(2)
assert len(c1.o) == 6
assert c1.o == [b"he", b"ll", b"o ", b"wo", b"rl", b"d"]


def test_select_n():
assert Chepy(["a", 1, "lol", "", True]).select_every_n(3).o == ["a", ""]

Expand Down

0 comments on commit 45d5886

Please sign in to comment.