使用 Metasploit JSON RPC
RPC API 允许通过基于 HTTP 的远程过程调用 (RPC) 服务以编程方式驱动 Metasploit Framework 和商业产品。RPC 服务是一组消息类型和远程方法,提供了一种结构化的方式,使外部应用程序能够与 Web 应用程序交互。可以使用 RPC 接口在本地或远程执行 Metasploit 命令,以执行基本任务,如运行模块、与数据库通信、管理会话、导出数据和生成报告。
Metasploit 产品主要用 Ruby 编写,这是使用远程 API 最简单的方式。然而,除 Ruby 外,任何支持 HTTPS 和 MessagePack 的语言(如 Python、Java 和 C)都可以利用 RPC API。
当前有两种 Metasploit RPC 实现:
- HTTP 和 MessagePack - 另有单独的指南介绍
- HTTP 和 JSON - 本指南涵盖
请注意,MessagePack 和 JSON RPC 服务提供的操作非常相似,建议查看两个文档。
一、启动 JSON API 服务器
运行 JSON API 服务器的前提是启动 Metasploit 数据库。可以使用 msfdb 初始化数据库。注意,msfdb 会询问是否希望运行 JSON RPC Web 服务,但对于本指南直接通过 thin 或 Puma 启动 JSON 服务并非必须:
首先运行 Metasploit 数据库:
msfdb init
配置数据库后,可以使用 thin Ruby Web 服务器初始化 JSON RPC 服务:
bundle exec thin --rackup msf-json-rpc.ru --address 0.0.0.0 --port 8081 --environment production --tag msf-json-rpc start
或者使用 Puma:
bundle exec puma msf-json-rpc.ru --port 8081 --environment production --tag msf-json-rpc start
二、开发
如果你想要开发或调试 JSON RPC 服务的 Ruby 实现,将 Metasploit API 同步运行在前台会很有帮助。这可以让控制台日志直接显示在终端中,还可以通过 require 'pry-byebug'; binding.pry
与断点进行交互:
也可以调试 Msfconsole 的 web 服务组件:
bundle exec ruby ./msfdb reinit
bundle exec ruby ./msfdb --component webservice stop
bundle exec ruby ./msfdb --component webservice --no-daemon start
RPC 日志记录
你可以使用 MSF_WS_DATA_SERVICE_LOGGER
环境变量配置 RPC 服务日志记录。
支持的日志记录器列表可以通过 msfconsole --help
查看。目前支持的列表如下:
Stdout
/Stderr
/StdoutWithoutTimestamps
- 将日志写入 stdout/stderrFlatfile
/TimestampColorlessFlatfile
- 将日志写入~/.msf4/logs
示例用法:
$ MSF_WS_DATA_SERVICE_LOGGER=Stdout bundle exec thin --rackup msf-json-rpc.ru --address localhost --port 8081 --environment production --tag msf-json-rpc start
[11/25/2020 17:34:53] [e(0)] core: Dependency for windows/encrypted_shell_reverse_tcp is not supported
[11/25/2020 17:34:53] [e(0)] core: Dependency for windows/x64/encrypted_shell_reverse_tcp is not supported
[11/25/2020 17:34:53] [e(0)] core: Dependency for windows/encrypted_reverse_tcp is not supported
[11/25/2020 17:34:53] [e(0)] core: Dependency for windows/x64/encrypted_reverse_tcp is not supported
[11/25/2020 17:34:54] [e(0)] core: Unable to load module /Users/adfoster/Documents/code/metasploit-framework/modules/auxiliary/gather/office365userenum.py - LoadError Try running file manually to check for errors or dependency issues.
Thin web server (v1.7.2 codename Bachmanity)
Maximum connections set to 1024
Listening on localhost:8081, CTRL+C to stop
[11/25/2020 17:35:17] [d(0)] core: Already established connection to postgresql, so reusing active connection.
[11/25/2020 17:35:17] [e(0)] core: DB.connect threw an exception - ActiveRecord::AdapterNotSpecified database configuration does not specify adapter
[11/25/2020 17:35:17] [e(0)] core: Failed to connect to the database: database configuration does not specify adapter```
三、概念
Metasploit RPC 旨在遵循 jsonrpc 规范。因此:
- 每个 JSON RPC 请求应提供一个唯一的消息 ID,客户端和服务器可以用它来关联请求和响应。
- Metasploit 可能会返回以下错误代码。
示例
首先,确保你正在运行 Metasploit 数据库,并且在运行这些示例之前已启动 JSON 服务。
1、查询
查询数据库状态
request:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "db.status",
"id": 1,
"params": []
}'
Response:
{
"jsonrpc": "2.0",
"result": {
"driver": "postgresql",
"db": "msf"
},
"id": 1
}
2、查询工作空间
Request:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "db.workspaces",
"id": 1,
"params": []
}'
Response:
{
"jsonrpc": "2.0",
"result": {
"workspaces": [
{
"id": 1,
"name": "default",
"created_at": 1673368954,
"updated_at": 1673368954
}
]
},
"id": 1
}
3、模块工作流程
搜索模块
Request:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'content-type: application/json' \
--data '{ "jsonrpc": "2.0", "method": "module.search", "id": 1, "params": ["psexec author:egypt arch:x64"] }'
Response:
{
"jsonrpc": "2.0",
"result": [
{
"type": "exploit",
"name": "PsExec via Current User Token",
"fullname": "exploit/windows/local/current_user_psexec",
"rank": "excellent",
"disclosuredate": "1999-01-01"
}
],
"id": 1
}
4、运行模块检查方法
Metasploit 模块支持运行检查方法,可以用来识别利用模块的成功与否,或者运行辅助模块进行目标检测。例如,使用辅助模块的检查请求:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "module.check",
"id": 1,
"params": [
"auxiliary",
"auxiliary/scanner/ssl/openssl_heartbleed",
{
"RHOST": "192.168.123.13"
}
]
}'
或者是利用模块的检查请求:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'content-type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "module.check",
"id": 1,
"params": [
"exploit",
"exploit/windows/smb/ms17_010_eternalblue",
{
"RHOST": "192.168.123.13"
}
]
}'
响应将包含一个标识符,可以用来查询更新:
{
"jsonrpc": "2.0",
"result": {
"job_id": 0,
"uuid": "1MIqJ5lViZHSOuaWf1Zz1lpR"
},
"id": 1
}
5、查询所有运行中的统计信息
Request:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "module.running_stats",
"id": 1,
"params": []
}'
响应将包括以下键:
- waiting - 已排队但尚未开始运行的模块
- running - 当前正在运行的模块
- results - 模块已完成或失败,可以检索并确认结果
Response:
{
"jsonrpc": "2.0",
"result": {
"waiting": [
"NkJvf4kp4JxcuFCz7rjSuHL1",
"wRnMQuJ8gzMTp5CaHu18bHdV"
],
"running": [
"b7hIX6G4ZtwvRVRDOXk5ylSx",
"gx9xTEi6KlH5LJHauyhrHTBn",
],
"results": [
"1MIqJ5lViZHSOuaWf1Zz1lpR",
"IN5PwYXrjqKfuekQt8cyCENK",
"Spd1xfgsCZXQABNh7UA3uB58",
"nRQw0bEvhFcXF0AxtVYOpQku"
]
},
"id": 1
}
6、检索模块结果
可以使用运行模块时返回的ID轮询模块结果。
Request:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "module.results",
"id": 1,
"params": ["0L37lfcIQqyRK9aBTIVJB4H3"]
}'
当模块尚未完成时的示例响应:
{
"jsonrpc": "2.0",
"result": {
"status": "running"
},
"id": 1
}
示例错误响应:
{
"jsonrpc": "2.0",
"result": {
"status": "errored",
"error": "The connection with (192.168.123.13:443) timed out."
},
"id": 1
}
示例成功响应:
{
"jsonrpc": "2.0",
"result": {
"status": "completed",
"result": {
"code": "vulnerable",
"message": "The target is vulnerable.",
"reason": null,
"details": {
"os": "Windows 7 Enterprise 7601 Service Pack 1",
"arch": "x64"
}
}
},
"id": 1
}
7、确认模块结果
此命令还允许 Metasploit 从内存中移除结果资源。如果不确认模块结果,将导致内存泄漏,但泄漏的内存限制为 35MB,因为所使用的内存数据存储是由 ActiveSupport::Cache::MemoryStore 实现的。
Request:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "module.ack",
"id": 1,
"params": ["nRQw0bEvhFcXF0AxtVYOpQku"]
}'
Response:
{
"jsonrpc": "2.0",
"result": {
"success": true
},
"id": 1
}
8、分析主机工作流
Metasploit 支持一个分析命令,该命令根据用户已经学到并存储的关于主机的信息,建议要运行的模块。首先报告一个主机:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "db.report_host",
"id": 1,
"params": [
{
"workspace": "default",
"host": "10.0.0.1",
"state": "alive",
"os_name": "Windows",
"os_flavor": "Enterprize",
"os_sp": "SP2",
"os_lang": "English",
"arch": "ARCH_X86",
"mac": "97-42-51-F2-A7-A7",
"scope": "eth2",
"virtual_host": "VMWare"
}
]
}'
# response: {"jsonrpc":"2.0","result":{"result":"success"},"id":1}
报告主机漏洞:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "db.report_vuln",
"id": 1,
"params": [
{
"workspace": "default",
"host": "10.0.0.1",
"name": "Exploit Name",
"info": "Human readable description of the vuln",
"refs": [
"CVE-2017-0143",
"CVE-2017-0144",
"CVE-2017-0145",
"CVE-2017-0146",
"CVE-2017-0147",
"CVE-2017-0148"
]
}
]
}'
# response: {"jsonrpc":"2.0","result":{"result":"success"},"id":1}
运行分析命令:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "db.analyze_host",
"id": 1,
"params": [
{
"workspace": "default",
"host": "10.0.0.1"
}
]
}'
Response:
{
"jsonrpc": "2.0",
"result": {
"host": {
"address": "10.0.0.1",
"modules": [
{
"mtype": "exploit",
"mname": "exploit/windows/smb/ms17_010_eternalblue",
"state": "READY_FOR_TEST",
"description": "ready for testing",
"options": {
"invalid": [],
"missing": []
}
}
]
}
},
"id": 1
}
在分析主机时,还可以指定有效载荷要求,以获得更精细的控制:
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "db.analyze_host",
"id": 1,
"params": [
{
"workspace": "default",
"host": "10.0.0.1",
"payload": "payload/cmd/unix/reverse_bash"
}
]
}'