Post模块的开发挑战你的编程技能。它与编写基于内存溢出的漏洞利用模块不同,后者技术上通常涉及构造恶意输入——一个字符串。Post模块更多的是关于正确的模块设计、Ruby编程和Metasploit库的实践知识。这也是一个非常宝贵的技能,因为如果你不知道在成功获得Shell之后该做什么,那么渗透测试有什么意义呢?此外,如果一个模块不能正常工作,你是否愿意等待几天、几周,甚至几个月让别人为你修复它?可能不会吧。如果你知道怎么做,你就能更快地修复它,继续渗透测试并做更多的事情。所以,学习Post模块开发吧!这对你和你的职业生涯都有好处。
一、规划模块
就像编写软件一样,在开始编码之前,你应该对你的Post模块的目标有一个清晰明确的计划。把多个功能放到一个模块里并不是一个好主意。例如:让模块偷取网络配置文件、偷取密码、哈希值、Shell历史记录等。相反,你应该将这些功能分解成多个模块。
你还需要考虑支持哪些会话类型:Meterpreter,还是Shell。理想情况下,支持这两种。但如果你必须在这两者之间做出选择,在Windows上,你应该优先考虑Windows Meterpreter。在Linux上,Shell会话类型通常比Linux Meterpreter更强,但希望不久的将来这种情况会发生变化。对于没有Meterpreter的系统,显然你唯一的选择是Shell。
另一个重要的事情是考虑你的模块如何在不同的操作系统/发行版上运行。例如,假设你想在Linux上运行ifconfig命令。在Ubuntu上,这是一个显而易见的事情,只需运行ifconfig命令。然而,另一个Linux发行版可能根本不知道你在问什么,所以你需要更具体地使用/sbin/ifconfig。Windows也是一样。是C:\WINDOWS\还是C:\WinNT?都有可能。是C:\Documents and Settings[用户名],还是C:\Users[用户名]?这也取决于Windows版本。更好的解决方法是使用环境变量。
始终做足功课,涵盖你能想到的所有场景。最重要的是,拿出你的虚拟机,进行测试!
1、Post模块的分类
Post模块根据其行为进行分类。例如,如果模块涉及收集数据,显然应该属于“gather”类别;如果它添加、更新或删除用户,则属于“manage”类别。以下是作为参考的分类列表:
分类 | 描述 |
---|---|
gather | 涉及数据收集/收集/枚举的模块。 |
gather/credentials | 偷取凭证的模块。 |
gather/forensics | 涉及取证数据收集的模块。 |
manage | 修改/操作/操控系统中某些内容的模块。与会话管理相关的任务,如迁移、注入也属于此类。 |
recon | 帮助你了解目标系统的信息,但不涉及数据偷窃的模块。理解这与“gather”类模块不同。 |
wlan | 与WLAN相关任务的模块。 |
escalate | 这个类别已被废弃,但由于流行度仍然保留。以前这是特权提升模块的位置。所有特权提升模块现在不再视为Post模块,而是漏洞利用模块。 |
capture | 涉及监控数据收集的模块。例如:键盘记录。 |
2、会话对象
你知道《指环王》里人们对“至尊魔戒”有多痴迷吗?会话对象就是这样的重要。它是你无法缺少的唯一对象,它是你的珍宝。所有的Post模块和其他相关的Mixin基本上都是建立在会话对象之上的,因为它知道有关被攻破主机的所有信息,并允许你控制它。
你可以使用session
方法来访问会话对象,或者使用其别名client
。与会话对象交互的最佳方式是通过irb
,以下是一个示例:
msf exploit(handler) > run
[*] Started reverse handler on 192.168.1.64:4444
[*] Starting the payload handler...
[*] Sending stage (769536 bytes) to 192.168.1.106
[*] Meterpreter session 1 opened (192.168.1.64:4444 -> 192.168.1.106:55157) at 2014-07-31 17:59:36 -0500
meterpreter > irb
[*] Starting IRB shell
[*] The 'client' variable holds the meterpreter client
>> session.class
=> Msf::Sessions::Meterpreter_x86_Win
在这一点上,你拥有了统治一切的力量。但请注意,上面的示例是一个 Msf::Sessions::Meterpreter_x86_Win
对象。实际上,还有许多不同类型的会话对象:command_shell.rb
、meterpreter_php.rb
、meterpreter_java.rb
、meterpreter_x86_linux.rb
等等。每种对象的行为有所不同,所以解释它们的工作方式实际上有些困难,但你可以在 lib/msf/base/sessions/
目录中查看它们是如何定义的。或者,既然你已经进入了 irb
提示符,你可以直接与其中的一个会话对象进行交互。
在 Ruby 中,有两个对象方法对调试非常有帮助。第一个是 methods
,它会列出该对象的所有公共和保护方法:
session.methods
另一个方法是 inspect
,它会返回一个人类可读的字符串,表示该对象的状态:
session.inspect
会话对象中一个常用的方法是 platform
。例如,如果你正在为一个 Windows 漏洞编写 Post 模块,在 check
方法中你可能会想使用 session.platform
来确保目标会话是 Windows 系统:
unless session.platform == 'windows'
# 非 Windows 系统肯定不受影响。
return Exploit::CheckCode::Safe
end
你也可以查看其他现有的 Post 模块,了解它们是如何使用会话对象的。
3、Msf::Post Mixin
正如我们所解释的,大多数 Post 模块的 mixin 都是建立在会话对象之上的,而且有很多这样的 mixin。不过,有一个你显然不能没有的主要 mixin:Msf::Post
mixin。当你创建一个包含这个 mixin 的 Post 模块时,它会自动包含许多其他 mixin,以应对各种不同的场景,具体包括:
- msf/core/post/common - Post 模块常用的通用方法,例如:
cmd_exec
。 - msf/core/post_mixin - 跟踪会话状态的方法。
- msf/core/post/file - 与文件系统相关的方法。
- msf/core/post/webrtc - 使用 WebRTC 与目标机器的摄像头进行交互。
- msf/core/post/linux - 其实没有太多内容,主要是
get_sysinfo
和is_root?
,专门用于 Linux。 - msf/core/post/osx -
get_sysinfo
、get_users
、get_system_accounts
、get_groups
和用于操作目标机器摄像头的方法。 - msf/core/post/solaris - 基本上和 Linux mixin 一样。相同的方法,但用于 Solaris。
- msf/core/post/unix -
get_users
、get_groups
、enum_user_directories
。 - msf/core/post/windows - 大部分开发时间都花在这里。从 Windows 账户管理、事件日志、文件信息、Railgun、LDAP、netapi、powershell、注册表、wmic、服务等都有涉及。
4、Template
下面是一个 Post 模块的模板。你可以看到,有些字段是必须填写的。我们将逐一解释每个字段:
class PostModuleName < Msf::Post
include Msf::Post::Common
include Msf::Post::File
include Msf::Post::Windows # 如果是 Windows 环境
# 如果是其他平台,可以根据需要包含对应的 mixin
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Example Post Module',
'Description' => 'This module does something useful.',
'License' => MSF_LICENSE,
'Author' => ['Author Name'],
'Platform' => ['windows', 'linux'], # 目标平台
'SessionTypes' => ['meterpreter', 'shell'], # 支持的会话类型
'References' =>
[
['CVE', '2020-1234'],
['URL', 'https://example.com']
]
)
)
end
def run
# 执行模块的主要逻辑
print_status("Running post-exploitation module...")
# 示例:列出当前目录中的文件
files = cmd_exec("ls")
print_good("Files: #{files}")
end
end
在上面的代码中,我们定义了一个新的 Post 模块,并说明了每个重要字段的作用:
- Name: 模块的名称。
- Description: 模块的描述,简要说明它的功能。
- License: 模块的授权信息。Metasploit 的许可证是
MSF_LICENSE
。 - Author: 模块的作者。
- Platform: 模块支持的操作系统平台。可以是一个字符串数组,表示该模块支持的操作系统(如
windows
、linux
)。 - SessionTypes: 模块支持的会话类型。可以是
meterpreter
、shell
或其他会话类型。 - References: 该模块的参考信息,如 CVE 编号或 URL。
run 方法是模块的核心方法,模块的实际逻辑将在这里实现。在 run
方法中,通常会调用 cmd_exec
来执行命令、收集信息、或者执行其他操作。
这个模板展示了如何利用 Msf::Post
mixin 来构建一个功能完备的 Post 模块,你可以根据实际需要修改和扩展这个模板。
5、基本 Git 命令
Metasploit 不再使用 SVN 进行源代码管理,而是转向了 Git,因此了解一些 Git 命令对于你来说非常有帮助。我们不是来教你 Git 有多么强大,大家都知道它有一定的学习曲线,尤其是对于新用户来说,很容易犯错。偶尔,Git 的“愤怒”情绪会爆发出来,我们能理解。不过,利用分支来管理代码是非常重要的。
每次创建一个新模块或者修改现有代码时,都不应该在默认的 master
分支上操作。为什么呢?因为当你执行 msfupdate
(Metasploit 用于更新仓库的工具)时,它会在合并更改之前执行 git reset
,这样所有的代码就会消失。
另外一个常见的错误是,在提交拉取请求之前,所有的更改都做到了 master
分支上。这是一个坏主意,因为你很可能提交了你不打算修改的其他代码,或者你可能会将不必要的提交历史一起合并,而实际上你只需要一个提交。感谢你为社区贡献模块,但我们并不想要你那一堆疯狂的提交历史。
所以作为一个好习惯,每次当你想要进行新的开发或者修改时,都应该从 master
分支创建一个新的分支。首先,确保你在 master
分支上。如果你运行 git status
命令,它会告诉你当前所在的分支:
$ git status
# 在分支 upstream-master 上
nothing to commit, working directory clean
接下来,执行 git pull
从 Metasploit 获取最新的代码更新:
$ git pull
Already up-to-date.
此时,你准备开始新分支的开发了。假设我们给新分支命名为 my_awesome_branch
:
$ git checkout -b my_awesome_module
Switched to a new branch 'my_awesome_module'
然后,你可以开始添加你的模块。确保它放在合适的路径下:
$ git add [module path]
当你决定保存更改时,提交(如果只是一个模块,你也可以使用 git commit -a
来提交所有修改,无需手动输入模块路径,-a
表示所有更改):
$ git commit [module path]
最后,推送更改,这会把你的代码上传到远程分支 my_awesome_branch
。你必须推送你的更改,才能提交拉取请求或与他人共享你的代码:
$ git push origin my_awesome_branch
这样,你就成功地在 Git 上创建了一个新的分支,并将更改推送到远程仓库。通过这种方式,你可以确保在更新 Metasploit 时,不会丢失你的开发工作。