Skip to content

Commit

Permalink
🗓 Apr 25, 2024 10:12:27 PM
Browse files Browse the repository at this point in the history
✨ railfence encode/decode
🤖 types added/updated
  • Loading branch information
securisec committed Apr 26, 2024
1 parent b49356e commit 5782adf
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 47 deletions.
87 changes: 78 additions & 9 deletions chepy/modules/encryptionencoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,6 @@ def xor(
x.append(char ^ key_val)

else:

if key_type == "utf":
key = str(key)
key = binascii.hexlify(key.encode())
Expand Down Expand Up @@ -828,8 +827,8 @@ def triple_des_decrypt(
cipher = DES3.new(key, mode=DES3.MODE_OFB, iv=iv)
self.state = cipher.decrypt(self._convert_to_bytes())
return self
else: # pragma: no cover
raise ValueError('Invalid mode')
else: # pragma: no cover
raise ValueError("Invalid mode")

@ChepyDecorators.call_stack
def aes_encrypt(
Expand Down Expand Up @@ -963,8 +962,8 @@ def aes_decrypt(
cipher = AES.new(key, mode=AES.MODE_OFB, iv=iv)
self.state = cipher.decrypt(self._convert_to_bytes())
return self
else: # pragma: no cover
raise ValueError('Invalid AES mode')
else: # pragma: no cover
raise ValueError("Invalid AES mode")

@ChepyDecorators.call_stack
def blowfish_encrypt(
Expand Down Expand Up @@ -1522,7 +1521,7 @@ def to_letter_number_code(

@ChepyDecorators.call_stack
def from_letter_number_code(
self, delimiter: Union[str, bytes] = ' ', join_by: Union[str, bytes] = ""
self, delimiter: Union[str, bytes] = " ", join_by: Union[str, bytes] = ""
) -> EncryptionEncodingT:
"""Decode A1Z26
Expand Down Expand Up @@ -1593,8 +1592,8 @@ def bifid_encode(self, key: Union[bytes, str] = "") -> EncryptionEncodingT:
key = self._bytes_to_str(key)
key = "".join(re.findall(r"[A-Z]+", key))
keyword_str = key.upper().replace("J", "I")
keyword_set = set(keyword_str)
keyword_list = []
# keyword_set = set(keyword_str)
# keyword_list = []
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
x_co = []
y_co = []
Expand Down Expand Up @@ -1655,7 +1654,7 @@ def bifid_decode(self, key: Union[str, bytes] = ""):
key = self._bytes_to_str(key)
key = "".join(re.findall(r"[A-Z]+", key))
keyword_str = key.upper().replace("J", "I")
keyword_set = set(keyword_str)
# keyword_set = set(keyword_str)
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
structure = []

Expand Down Expand Up @@ -1836,3 +1835,73 @@ def fernet_decrypt(
out = Fernet(key).decrypt(self._convert_to_bytes())
self.state = out
return self

@ChepyDecorators.call_stack
def railfence_encode(self, key=2, offset=0) -> EncryptionEncodingT:
"""Encode to railfence
Args:
key (int, optional): Key. Should be equal or larger than data. Defaults to 2.
offset (int, optional): Offset. Defaults to 0.
Returns:
Chepy: The Chepy object.
"""
key, offset = int(key), int(offset)
data = self._convert_to_str()
if key < 2:
raise ValueError("Key has to be bigger than 2") # pragma: no cover
elif key > len(data):
raise ValueError(
"Key should be smaller than the plain text's length"
) # pragma: no cover

if offset < 0:
raise ValueError("Offset has to be a positive integer") # pragma: no cover

cycle = (key - 1) * 2
rows = [""] * key

for pos in range(len(data)):
row_idx = key - 1 - abs(cycle // 2 - (pos + offset) % cycle)
rows[row_idx] += data[pos]

self.state = "".join(rows).strip()
return self

@ChepyDecorators.call_stack
def railfence_decode(self, key=2, offset=0) -> EncryptionEncodingT:
"""Decode railfence
Args:
key (int, optional): Key. Should be equal or larger than data. Defaults to 2.
offset (int, optional): Offset. Defaults to 0.
Returns:
Chepy: The Chepy object.
"""
key, offset = int(key), int(offset)
cipher = self._convert_to_str()

if key < 2:
raise ValueError("Key has to be bigger than 2") # pragma: no cover
elif key > len(cipher):
raise ValueError(
"Key should be smaller than the cipher's length"
) # pragma: no cover

if offset < 0:
raise ValueError("Offset has to be a positive integer") # pragma: no cover

cycle = (key - 1) * 2
plaintext = [""] * len(cipher)

j = 0
for y in range(key):
for x in range(len(cipher)):
if (y + x + offset) % cycle == 0 or (y - x - offset) % cycle == 0:
plaintext[x] = cipher[j]
j += 1

self.state = "".join(plaintext).strip()
return self
8 changes: 5 additions & 3 deletions chepy/modules/encryptionencoding.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class EncryptionEncoding(ChepyCore):
def jwt_verify(self: EncryptionEncodingT, secret: str, algorithm: list=...) -> EncryptionEncodingT: ...
def jwt_sign(self: EncryptionEncodingT, secret: str, algorithms: str=...) -> EncryptionEncodingT: ...
def jwt_token_generate_none_alg(self: EncryptionEncodingT, headers: Dict[str, Any]=...) -> EncryptionEncodingT: ...
def jwt_token_generate_embedded_jwk(self: EncryptionEncodingT, private_key_pem: str, private_key_passphrase: str = ..., headers: dict = ..., alg: str = Union["RS256", "RS512"]) -> EncryptionEncodingT: ...
def jwt_token_generate_embedded_jwk(self: EncryptionEncodingT, private_key_pem: str, private_key_passphrase: str = ..., headers: dict = ..., alg: str = Literal["RS256", "RS512"]) -> EncryptionEncodingT: ...
def rc4_encrypt(self: EncryptionEncodingT, key: str, key_format: RC4_FORMAT=...) -> EncryptionEncodingT: ...
def rc4_decrypt(self: EncryptionEncodingT, key: str, key_format: RC4_FORMAT=...) -> EncryptionEncodingT: ...
def des_encrypt(self: EncryptionEncodingT, key: str, iv: str=..., mode: Literal["CBC", "OFB", "CTR", "ECB"]="CBC", key_format: FORMAT="hex", iv_format: FORMAT="hex") -> EncryptionEncodingT: ...
Expand All @@ -35,8 +35,8 @@ class EncryptionEncoding(ChepyCore):
def chacha_decrypt(self: EncryptionEncodingT, key: str, nonce: str=..., key_format: FORMAT=..., nonce_format: FORMAT=...) -> EncryptionEncodingT: ...
def triple_des_encrypt(self: EncryptionEncodingT, key: str, iv: str=..., mode: Literal["CBC", "OFB", "CTR", "ECB"]="CBC", key_format: FORMAT="hex", iv_format: FORMAT="hex") -> EncryptionEncodingT: ...
def triple_des_decrypt(self: EncryptionEncodingT, key: str, iv: str=..., mode: Literal["CBC", "OFB", "CTR", "ECB", "ECB/NoPadding", "CBC/NoPadding"]="CBC", key_format: FORMAT="hex", iv_format: FORMAT="hex") -> EncryptionEncodingT: ...
def aes_encrypt(self: EncryptionEncodingT, key: Union[bytes, str], iv: str=..., mode: Literal["CBC", "CFB", "OFB", "CTR", "ECB", "GCM"]="CBC", key_format: FORMAT="hex", iv_format: FORMAT="hex") -> EncryptionEncodingT: ...
def aes_decrypt(self: EncryptionEncodingT, key: Union[bytes, str], iv: str=..., mode: Literal["CBC", "CFB", "OFB", "CTR", "ECB", "GCM", "ECB/NoPadding", "CBC/NoPadding"]="CBC", key_format: FORMAT="hex", iv_format: FORMAT="hex") -> EncryptionEncodingT: ...
def aes_encrypt(self: EncryptionEncodingT, key: Union[bytes, str], iv: Union[bytes, str]=..., mode: Literal["CBC", "CFB", "OFB", "CTR", "ECB", "GCM"]="CBC", key_format: FORMAT="hex", iv_format: FORMAT="hex") -> EncryptionEncodingT: ...
def aes_decrypt(self: EncryptionEncodingT, key: Union[bytes, str], iv: Union[bytes, str]=..., mode: Literal["CBC", "CFB", "OFB", "CTR", "ECB", "GCM", "ECB/NoPadding", "CBC/NoPadding"]="CBC", key_format: FORMAT="hex", iv_format: FORMAT="hex") -> EncryptionEncodingT: ...
def blowfish_encrypt(self: EncryptionEncodingT, key: str, iv: str=..., mode: Literal["CBC", "OFB", "CTR", "ECB"]=..., key_format: FORMAT=..., iv_format: FORMAT=...) -> EncryptionEncodingT: ...
def blowfish_decrypt(self: EncryptionEncodingT, key: str, iv: str=..., mode: Literal["CBC", "OFB", "CTR", "ECB"]=..., key_format: FORMAT=..., iv_format: FORMAT=...) -> EncryptionEncodingT: ...
def vigenere_encode(self: EncryptionEncodingT, key: str) -> EncryptionEncodingT: ...
Expand Down Expand Up @@ -67,3 +67,5 @@ class EncryptionEncoding(ChepyCore):
def rabbit(self: EncryptionEncodingT, key: str, iv: Union[None, str]=...) -> EncryptionEncodingT: ...
def fernet_encrypt(self: EncryptionEncodingT, key:Union[bytes, str], encode_key: bool=False) -> EncryptionEncodingT: ...
def fernet_decrypt(self: EncryptionEncodingT, key:Union[bytes, str], encode_key: bool=False) -> EncryptionEncodingT: ...
def railfence_encode(self: EncryptionEncodingT, key: Union[int, str]=2, offset: Union[int, str]=0) -> EncryptionEncodingT: ...
def railfence_decode(self: EncryptionEncodingT, key: Union[int, str]=2, offset: Union[int, str]=0) -> EncryptionEncodingT: ...
108 changes: 73 additions & 35 deletions tests/test_encryptionencoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ def test_rot_47_bruteforce():


def test_rot_8000():
assert Chepy("籯籵籪籰粄类簹籽籽簼籷籽簹籽籱簼籬簹类簼粆").rot_8000().o == b"flag{r0tt3nt0th3c0r3}"
assert (
Chepy("籯籵籪籰粄类簹籽籽簼籷籽簹籽籱簼籬簹类簼粆").rot_8000().o
== b"flag{r0tt3nt0th3c0r3}"
)


def test_rotate():
Expand Down Expand Up @@ -155,24 +158,19 @@ def test_xor_bruteforce():


def test_jwt_decode():
assert (
Chepy(
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmF\
assert Chepy(
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmF\
tZSI6IkFtYXppbmcgSGF4eDByIiwiZXhwIjoiMTQ2NjI3MDcyMiIsImFkbWluIjp0\
cnVlfQ.UL9Pz5HbaMdZCV9cS9OcpccjrlkcmLovL2A2aiKiAOY"
)
.jwt_decode()
.o
== {
"payload": {
"sub": "1234567890",
"name": "Amazing Haxx0r",
"exp": "1466270722",
"admin": True,
},
"header": {"alg": "HS256", "typ": "JWT"},
}
)
).jwt_decode().o == {
"payload": {
"sub": "1234567890",
"name": "Amazing Haxx0r",
"exp": "1466270722",
"admin": True,
},
"header": {"alg": "HS256", "typ": "JWT"},
}


def test_jwt_sign():
Expand All @@ -187,15 +185,10 @@ def test_jwt_sign():


def test_jwt_verify():
assert (
Chepy(
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5N\
assert Chepy(
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5N\
iznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg"
)
.jwt_verify("secret")
.o
== {"some": "payload"}
)
).jwt_verify("secret").o == {"some": "payload"}


def test_jwt_non_alg():
Expand Down Expand Up @@ -402,9 +395,9 @@ def test_aes_encrypt():
.o
== b"4ab2b4f72e9d92960b"
)
raw_key = (
raw_iv
) = b'\xe1p\x07\x01R\xee\xde)\xa0gx\xb6\xc2\xcb\x18\x9e\x80\xe5\x9eu\xf2"0PVvE\xdb\x08\x93\xa0\x93'
raw_key = raw_iv = (
b'\xe1p\x07\x01R\xee\xde)\xa0gx\xb6\xc2\xcb\x18\x9e\x80\xe5\x9eu\xf2"0PVvE\xdb\x08\x93\xa0\x93'
)
assert (
Chepy("hello")
.aes_encrypt(key=raw_key, iv=raw_iv[:16], key_format="raw", iv_format="raw")
Expand All @@ -413,9 +406,17 @@ def test_aes_encrypt():
== b"hello"
)
assert (
Chepy('hello')
.aes_encrypt(key='supersecret!!!!!', key_format='utf8', iv='abcdefghijklmnop', iv_format='utf-8')
.to_hex().o == b'd18c2cba21d2eef40c9ed4771a9b320e')
Chepy("hello")
.aes_encrypt(
key="supersecret!!!!!",
key_format="utf8",
iv="abcdefghijklmnop",
iv_format="utf-8",
)
.to_hex()
.o
== b"d18c2cba21d2eef40c9ed4771a9b320e"
)


def test_aes_decrypt():
Expand Down Expand Up @@ -471,15 +472,23 @@ def test_aes_decrypt():
assert (
Chepy("6bcd22d5c24a59a818f39ba64b7f2d21")
.from_hex()
.aes_decrypt("b88e5c5597eb6e5e9d1ce47ab2eb57d0fcbd44a3c3a648116cbf6b09073f836b", iv='404cce974703e46da08c3fb65c469109', mode='ECB/NoPadding')
.aes_decrypt(
"b88e5c5597eb6e5e9d1ce47ab2eb57d0fcbd44a3c3a648116cbf6b09073f836b",
iv="404cce974703e46da08c3fb65c469109",
mode="ECB/NoPadding",
)
.to_hex()
.o
== b"68656c6c6f0b0b0b0b0b0b0b0b0b0b0b"
)
assert (
Chepy("dda597db9a1b3627f64fb3397502c6f4")
.from_hex()
.aes_decrypt("b88e5c5597eb6e5e9d1ce47ab2eb57d0fcbd44a3c3a648116cbf6b09073f836b", iv='404cce974703e46da08c3fb65c469109', mode='CBC/NoPadding')
.aes_decrypt(
"b88e5c5597eb6e5e9d1ce47ab2eb57d0fcbd44a3c3a648116cbf6b09073f836b",
iv="404cce974703e46da08c3fb65c469109",
mode="CBC/NoPadding",
)
.to_hex()
.o
== b"68656c6c6f0b0b0b0b0b0b0b0b0b0b0b"
Expand Down Expand Up @@ -560,8 +569,30 @@ def test_triple_des_decrypt():
.o
== b"some data"
)
assert Chepy('23bba626dce4683a').from_hex().triple_des_decrypt('df5770dec9f7d1843d72f195656b374c894b435da94a830d', '8219e29f40416b93', mode='ECB/NoPadding').to_hex().o == b'68656c6c6f030303'
assert Chepy('804b7fd84fa2d823').from_hex().triple_des_decrypt('df5770dec9f7d1843d72f195656b374c894b435da94a830d', '8219e29f40416b93', mode='CBC/NoPadding').to_hex().o == b'68656c6c6f030303'
assert (
Chepy("23bba626dce4683a")
.from_hex()
.triple_des_decrypt(
"df5770dec9f7d1843d72f195656b374c894b435da94a830d",
"8219e29f40416b93",
mode="ECB/NoPadding",
)
.to_hex()
.o
== b"68656c6c6f030303"
)
assert (
Chepy("804b7fd84fa2d823")
.from_hex()
.triple_des_decrypt(
"df5770dec9f7d1843d72f195656b374c894b435da94a830d",
"8219e29f40416b93",
mode="CBC/NoPadding",
)
.to_hex()
.o
== b"68656c6c6f030303"
)


def test_blowfish_encrypt():
Expand Down Expand Up @@ -868,3 +899,10 @@ def test_fernet():
c = Chepy(flag).fernet_encrypt(key, True)
assert c.o.startswith(b"gAAA")
assert c.fernet_decrypt(key, True).o == flag.encode()


def test_railfence():
assert Chepy("hello").railfence_encode().o == b"hloel"
assert Chepy("hello world").railfence_encode(key=4, offset=4).o == b"lrelolhowd"
assert Chepy("hloel").railfence_decode().o == b"hello"
assert Chepy(b"lelho").railfence_decode(key=4, offset="4").o == b"hello"

0 comments on commit 5782adf

Please sign in to comment.