101 lines
2.7 KiB
Python
101 lines
2.7 KiB
Python
|
#!/usr/bin/python3
|
||
|
# dEncexdel by six
|
||
|
# version: 1.1
|
||
|
|
||
|
import getpass
|
||
|
import argparse
|
||
|
import base64
|
||
|
from cryptography.fernet import Fernet
|
||
|
from cryptography.hazmat.backends import default_backend
|
||
|
from cryptography.hazmat.primitives import hashes
|
||
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
||
|
|
||
|
# Taking arguments from the user
|
||
|
parser = argparse.ArgumentParser()
|
||
|
parser.add_argument("-e", help="Encrypt the executable")
|
||
|
parser.add_argument("-x", help="Decrypt, execute and delete")
|
||
|
parser.add_argument("-r", help="Read and print the decrypted data to stdout")
|
||
|
args = parser.parse_args()
|
||
|
passkey = getpass.getpass("Passkey: ")
|
||
|
|
||
|
# Building the key for Fernet
|
||
|
passkey = passkey.encode()
|
||
|
salt = b'\x05bWB\xc5i\x8b\x8dy\xd5\xe3[~\\Z\x10' # You want to change this and possibly store salts in a database
|
||
|
kdf = PBKDF2HMAC(
|
||
|
algorithm=hashes.SHA256(),
|
||
|
length=32,
|
||
|
salt=salt,
|
||
|
iterations=100000,
|
||
|
backend=default_backend()
|
||
|
)
|
||
|
key = base64.urlsafe_b64encode(kdf.derive(passkey)) # Fernet(key) requires to be a base64 urlsafe string
|
||
|
f = Fernet(key)
|
||
|
|
||
|
|
||
|
# Encryption, overwrites the original file
|
||
|
def encrypt(filename, key):
|
||
|
f = Fernet(key)
|
||
|
with open(filename, "rb") as file:
|
||
|
file_data = file.read()
|
||
|
encrypted_data = f.encrypt(file_data)
|
||
|
with open(filename, "wb") as file:
|
||
|
file.write(encrypted_data)
|
||
|
|
||
|
|
||
|
# Decryption to /dev/shm/dEncexdel/<filename>
|
||
|
def decrypt(filename, key):
|
||
|
|
||
|
# decryption
|
||
|
f = Fernet(key)
|
||
|
with open(filename, "rb") as file:
|
||
|
encrypted_data = file.read()
|
||
|
try:
|
||
|
decrypted_data = f.decrypt(encrypted_data)
|
||
|
except:
|
||
|
print("Wrong passkey")
|
||
|
return
|
||
|
|
||
|
# Print to stdout if -r is used and do not execute
|
||
|
if args.r:
|
||
|
try:
|
||
|
print(decrypted_data.decode('utf-8'))
|
||
|
except:
|
||
|
import sys
|
||
|
sys.stdout.buffer.write(decrypted_data)
|
||
|
return
|
||
|
|
||
|
# Prepare a directory with read permissions to the user only
|
||
|
import os
|
||
|
temp_dir = "/dev/shm/dEncexdel/"
|
||
|
os.mkdir(temp_dir)
|
||
|
os.chmod(temp_dir, 0o700)
|
||
|
|
||
|
# Write out the decrypted executable
|
||
|
filename = temp_dir + filename
|
||
|
with open(filename, "wb") as file:
|
||
|
file.write(decrypted_data)
|
||
|
|
||
|
# Make the temporary file executable
|
||
|
os.chmod(filename, 0o700)
|
||
|
from subprocess import Popen
|
||
|
Popen([filename])
|
||
|
|
||
|
# Wait until binary is loaded but execution not finished
|
||
|
# Let me know if you have a better idea
|
||
|
import time
|
||
|
time.sleep(3)
|
||
|
|
||
|
# Remove the file and the directory
|
||
|
Popen(['rm','-rf',temp_dir])
|
||
|
|
||
|
|
||
|
# Deciding if we encrypt or decrypt and run or just read to stdout
|
||
|
if args.e:
|
||
|
encrypt(args.e, key)
|
||
|
|
||
|
if args.x:
|
||
|
decrypt(args.x, key)
|
||
|
|
||
|
if args.r:
|
||
|
decrypt(args.r, key)
|