我可以访问外部 netcat 服务器,并尝试向其发送大量输入。我目前正在尝试使用以下命令执行此操作:
python -c 'print("a" * (50000-64))' | nc www.host.net port
虽然看起来服务器确实在接收和处理输入,但连接并未保持打开状态,因为服务器上运行的 Python 程序会立即抛出 EOFError。我想知道是否有办法发送 Python 输入而不包含 EOF。
答案1
当你有一个cmd1|cmd2
命令时,shell 会创建一个管道,一旦cmd1
停止,管道的一端就会关闭。然后cmd2
在读取所有数据后,会看到 EOF。
(cmd1;cat)|cmd2
如果您想在 cmd1 结束后使管道保持打开状态,您可以键入。但该命令将继续使您能够键入其他内容。您将不会再次获得 shell 提示符。(您可以用 Ctrl D 来结束,这将关闭管道并发送 EOF,甚至可以用 CtrlZ 来cat
暂停)。
答案2
EOF 并不是发送首先,当读取器(服务器)到达流末尾时,它们会被隐式引发,并且流总是当 TCP 连接关闭时结束,这总是在客户端nc
进程退出时发生。客户端断开连接后,您无法获得无限流,并且您无法获得在没有客户端进程的情况下存在的“永久”TCP 连接。
因此,为了保持 TCP 连接打开,你需要保持实际进程运行——例如,编写一个 Python 程序,它本身通过 打开 TCP 连接socket
,发送数据,然后等待而不是立即退出(例如,time.sleep()
如果必须的话)。
$ python3
>>> import socket
>>> sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> addr = ("192.0.2.3", 1234)
>>> sk.connect(addr)
>>> sk.send(b"a" * (50000-64))
>>> [do nothing, leave it sitting at the REPL prompt]
可以让 Bash 本身作为交互式 shell 的一部分建立 TCP 连接;它将持续到您退出 shell(或直到您关闭连接)。
Open:
$ exec {fd}<>/dev/tcp/www.host.net/1234
Send data:
$ python -c 'print ...' >&$fd
Close:
$ exec {fd}>&-
(/dev/tcp 是虚拟的,由 Bash 内部处理 - 它实际上并不存在于 /dev 中。)