-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added crypto class and cypher suites #1722
Changes from 17 commits
775ad35
cee1f88
6568bc3
bed84e1
66bfeb0
a371a6b
6f33f39
b49a08b
ba80385
c44a9d0
40dae62
be96050
b891849
b30c82c
3edd060
6a7cb55
47a3b0f
5b2acda
415376f
e2df120
7c2fe96
9526faf
3a91799
1f2a31b
b3c71af
c824825
17e3ca3
4be7c6f
1d3e5b5
febf259
789a710
1de0165
69d45ca
7a42efd
5b09060
f5710f9
ee5e32a
fa14ff0
eb5579b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ | |
'asm', | ||
'atexception', | ||
'atexit', | ||
'crypto', | ||
'commandline', | ||
'constants', | ||
'context', | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
from __future__ import absolute_import | ||
|
||
# load cipher suites | ||
from pwnlib.crypto.ciphers.atbash import CipherAtBash | ||
from pwnlib.crypto.ciphers.bacon import CipherBacon | ||
from pwnlib.crypto.ciphers.base64 import CipherBase64 | ||
from pwnlib.crypto.ciphers.binary import CipherBinary | ||
from pwnlib.crypto.ciphers.caesar import CipherCaesar | ||
from pwnlib.crypto.ciphers.decimal import CipherDecimal | ||
from pwnlib.crypto.ciphers.hex import CipherHex | ||
from pwnlib.crypto.ciphers.morse import CipherMorse | ||
from pwnlib.crypto.ciphers.reverse import CipherReverse | ||
from pwnlib.crypto.ciphers.rot13 import CipherRot13 | ||
from pwnlib.crypto.ciphers.transposition import CipherTransposition | ||
from pwnlib.crypto.ciphers.vigenere import CipherVigenere | ||
from pwnlib.crypto.ciphers.xor import CipherXor | ||
|
||
class Crypto(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should be able to use the module hack seen elsewhere in Pwntools to make this "automagic" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Im not sure what you mean with this, can you give me an example? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please also tell me, how to follow your suggestions about making routines top-level as you told here: Edit: It would also be nice if all of these routines were exposed as top-level routines, e.g. crypto.rot13 rather than CryptoRot13. By convention, pretty much everything in Pwntools is lower-case. I could rename the classes, but im not sure how to do this the way you want it to, that it fits. |
||
def __init__(self, algo=None, key=None): | ||
cipher = None | ||
algo = algo | ||
key = key | ||
|
||
# select cipher suite | ||
if(algo == 'atbash'): | ||
Arusekk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self.cipher = CipherAtBash() | ||
if(algo == 'bacon'): | ||
self.cipher = CipherBacon() | ||
if(algo == 'base64'): | ||
self.cipher = CipherBase64() | ||
if(algo == 'binary'): | ||
self.cipher = CipherBinary() | ||
''' check key, mode parameter | ||
if(algo == 'caesar'): | ||
self.cipher = CipherCaesar() | ||
if(algo == 'decimal'): | ||
self.cipher = CipherDecimal() | ||
''' | ||
if(algo == 'hex'): | ||
self.cipher = CipherHex() | ||
if(algo == 'morse'): | ||
self.cipher = CipherMorse() | ||
if(algo == 'reverse'): | ||
self.cipher = CipherReverse() | ||
if(algo == 'rot13'): | ||
self.cipher = CipherRot13() | ||
''' | ||
if(algo == 'transposition'): | ||
self.cipher = CipherTransposition() | ||
''' | ||
if(algo == 'vignere'): | ||
self.cipher = CipherVigenere() | ||
if(algo == 'xor'): | ||
self.cipher = CipherXor() | ||
|
||
|
||
def encrypt(self, data): | ||
return self.cipher.encrypt(data) | ||
|
||
|
||
def decrypt(self, data): | ||
return self.cipher.decrypt(data) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import string | ||
|
||
class CipherAtBash: | ||
def __init__(self): | ||
self.alphabet = list(string.ascii_uppercase) | ||
|
||
|
||
def encrypt(self, clear): | ||
return self.process(clear) | ||
|
||
|
||
def decrypt(self, cipher): | ||
return self.process(cipher) | ||
|
||
|
||
def process(self, text): | ||
reverse_alphabet = list(reversed(self.alphabet)) | ||
code_dictionary = dict(zip(self.alphabet, reverse_alphabet)) | ||
|
||
chars = list(text.upper()) | ||
result = "" | ||
|
||
for char in chars: | ||
if char in code_dictionary: | ||
result += code_dictionary.get(char) | ||
else: | ||
result += char | ||
|
||
return result |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import re | ||
|
||
class CipherBacon: | ||
def __init__(self): | ||
self.code_table = self.generate_code_table() | ||
|
||
|
||
def generate_code_table(self): | ||
bacon_dict = {} | ||
|
||
for i in range(0, 26): | ||
tmp = bin(i)[2:].zfill(5) | ||
tmp = tmp.replace('0', 'a') | ||
tmp = tmp.replace('1', 'b') | ||
bacon_dict[tmp] = chr(65 + i) | ||
|
||
return bacon_dict | ||
|
||
|
||
def encrypt(self, cleartext): | ||
cipher = '' | ||
bacon_dict = {v: k for k, v in self.code_table.items()} # hack to get key from value - reverse dict | ||
#cleartext = normalize('NFKD', cleartext).encode('ascii', 'ignore') # replace national characters to ASCII equivalents | ||
cleartext = cleartext.upper() | ||
cleartext = re.sub(r'[^A-Z]+', '', cleartext) | ||
|
||
for i in cleartext: | ||
cipher += bacon_dict.get(i).upper() | ||
return cipher | ||
|
||
|
||
def decrypt(self, ciphertext): | ||
cleartext = '' | ||
ciphertext = ciphertext.lower() | ||
ciphertext = re.sub(r'[^ab]+', '', ciphertext) | ||
|
||
for i in range(0, int(len(ciphertext) / 5)): | ||
cleartext += self.code_table.get(ciphertext[i * 5:i * 5 + 5], ' ') | ||
return cleartext |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import base64 | ||
|
||
class CipherBase64: | ||
def encrypt(self, cleartext): | ||
return base64.b64encode(cleartext.encode('utf-8')).decode() | ||
|
||
|
||
def decrypt(self, ciphertext): | ||
return base64.b64decode(ciphertext.encode('utf-8')).decode() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import binascii | ||
|
||
class CipherBinary: | ||
def encrypt(self, data): | ||
return bin(int(binascii.hexlify(data.encode('utf-8')),16)) | ||
|
||
|
||
def decrypt(self, data): | ||
n = int(data, 2) | ||
return binascii.unhexlify('%x' % n).decode() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import string | ||
|
||
class CipherCaesar: | ||
def __init__(self): | ||
self.alphabet = string.ascii_lowercase + string.ascii_uppercase | ||
|
||
|
||
def encrypt(self, data, key, mode): | ||
return self.process(data, key, mode) | ||
|
||
|
||
def decrypt(self, data, key, mode): | ||
return self.process(data, key, mode) | ||
|
||
|
||
def process(self, text, key, mode): | ||
result = '' | ||
|
||
for c in text: | ||
index = self.alphabet.find(c) | ||
if index == -1: | ||
result += c | ||
else: | ||
new_index = index + key if mode == 1 else index - key | ||
new_index %= len(self.alphabet) | ||
result += self.alphabet[new_index:new_index+1] | ||
|
||
return result |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import binascii | ||
|
||
class CipherDecimal: | ||
def encrypt(self, data): | ||
result = '' | ||
|
||
for char in data: | ||
result += ord(char) | ||
|
||
return result | ||
|
||
|
||
def decrypt(self, data): | ||
result = '' | ||
|
||
for num in data: | ||
result += chr(num) | ||
|
||
return result |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import binascii | ||
|
||
class CipherHex: | ||
def encrypt(self, data): | ||
result = '' | ||
|
||
for char in data: | ||
result += binascii.hexlify(char.encode('utf-8')).decode() | ||
|
||
return result | ||
|
||
|
||
def decrypt(self, data): | ||
return binascii.unhexlify(data).decode() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
class CipherMorse: | ||
def __init__(self): | ||
self.code_table = self.generate_code_table() | ||
|
||
|
||
def generate_code_table(self): | ||
code_table = { | ||
'A':'.-', 'B':'-...', | ||
'C':'-.-.', 'D':'-..', 'E':'.', | ||
'F':'..-.', 'G':'--.', 'H':'....', | ||
'I':'..', 'J':'.---', 'K':'-.-', | ||
'L':'.-..', 'M':'--', 'N':'-.', | ||
'O':'---', 'P':'.--.', 'Q':'--.-', | ||
'R':'.-.', 'S':'...', 'T':'-', | ||
'U':'..-', 'V':'...-', 'W':'.--', | ||
'X':'-..-', 'Y':'-.--', 'Z':'--..', | ||
'1':'.----', '2':'..---', '3':'...--', | ||
'4':'....-', '5':'.....', '6':'-....', | ||
'7':'--...', '8':'---..', '9':'----.', | ||
'0':'-----', ', ':'--..--', '.':'.-.-.-', | ||
'?':'..--..', '/':'-..-.', '-':'-....-', | ||
'(':'-.--.', ')':'-.--.-' | ||
} | ||
|
||
return code_table | ||
|
||
|
||
def encrypt(self, cleartext): | ||
ciphertext = '' | ||
for char in cleartext: | ||
if char != ' ': | ||
ciphertext += self.code_table[char.upper()] + ' ' | ||
else: | ||
ciphertext += ' ' | ||
|
||
return ciphertext | ||
|
||
|
||
def decrypt(self, ciphertext): | ||
ciphertext += ' ' | ||
cleartext = '' | ||
citext = '' | ||
for char in ciphertext: | ||
if (char != ' '): | ||
i = 0 | ||
citext += char | ||
else: | ||
i += 1 | ||
if i == 2 : | ||
cleartext += ' ' | ||
else: | ||
cleartext += list(self.code_table.keys())[list(self.code_table.values()).index(citext)] | ||
citext = '' | ||
|
||
return cleartext |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
class CipherReverse: | ||
def encrypt(self, cleartext): | ||
return self.process(cleartext) | ||
|
||
|
||
def decrypt(self, ciphertext): | ||
return self.process(ciphertext) | ||
|
||
|
||
def process(self, text): | ||
return ''.join(reversed(text)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import codecs | ||
|
||
class CipherRot13: | ||
def encrypt(self, data): | ||
return codecs.encode(data, 'rot13') | ||
|
||
def decrypt(self, data): | ||
return codecs.decode(data, 'rot13') |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from __future__ import division | ||
import math | ||
|
||
|
||
class CipherTransposition: | ||
def encrypt(self, data, key): | ||
message_size = len(data) | ||
|
||
if(key > message_size // 2): | ||
raise ValueError('Key is limited to half the length of message') | ||
else: | ||
encrypted_message = [''] * key | ||
for col in range(key): | ||
pointer = col | ||
while pointer < message_size: | ||
encrypted_message[col] += data[pointer] | ||
pointer += key | ||
|
||
encrypted_message = ''.join(encrypted_message) | ||
return encrypted_message | ||
|
||
|
||
def decrypt(self, data, key): | ||
num_of_columns = int(math.ceil(len(data) / key)) | ||
num_of_rows = key | ||
num_of_shaded_boxes = (num_of_columns * num_of_rows) - len(data) | ||
|
||
data = [''] * num_of_columns | ||
|
||
col = 0 | ||
row = 0 | ||
|
||
for symbol in data: | ||
data[col] += symbol | ||
col += 1 | ||
|
||
if (col == num_of_columns or | ||
col == num_of_columns - 1 and | ||
row >= num_of_rows - num_of_shaded_boxes): | ||
col = 0 | ||
row += 1 | ||
|
||
return ''.join(data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please try to keep these sorted. not change the blank lines formatting, and add a link as the other entries have below