🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
**注意: 这个文档可能需要审查** 一个数据存储选项是用户可以设置的变量的一个类型,允许metasploit的各种组件在使用时更具有配置性.例子,在msfconsole,你能设置ConsoleLogging选项来记录所有控制台的输入输出的所有日志 -- 在渗透过程中方便文档记录的一种方法.当你载入一个模块,这个mixin或模块会注册更多选项.一些常见的有:用于服务器exploit或辅助模块的 RHOST 和 RPORT ,客户端模块的SRVHOST等等.准确找出可以设置的数据存储选项的最佳方法是通过使用以下命令 * ```show options``` - Shows you all the basic options. * ```show advanced``` - Shows you all the advanced options. * ```show missing``` - Shows you all the required options you have not configured. * ```set``` - Shows you everything. Obviously you also use this command to set an option. ### 选项源: ModuleDataStore, active_module, session, and framework **用户如何查看数据储存选项:** 在用户方面,数据储存选项 像全局或者模块级别:全局 意味全部模块都能使用该选项.可以使用```setg```命令来设置.模块级别意味着只有你当前正在使用的模块会记住储存选项,没有其他的能记住.如果先加载模块,则需要设置模块级别选项,然后使用```set```命令,像下面这样: ``` msf > use exploit/windows/smb/ms08_067_netapi msf exploit(ms08_067_netapi) > set rhost 10.0.1.3 rhost => 10.0.1.3 ``` **metasploit开发者如何查看数据储存选项** 在开发方面,事情有点疯狂.数据存储选项实际上可以在至少四个不同的来源中找到:the ModuleDataStore object, active_module, session object, or the framework object. 如果你只是进行模块开发.你能信任的最好的源是ModuleDataStore对象.这个对象有一个特定的加载顺序,然后把所需的选项交给你.如果这个选项可以在模块的数据存储中找到,它会给你这个选项。如果没有找到,它从一个框架给你一个.以下是如何读取模块中的数据存储选项的例子 ```ruby current_host = datastore['RHOST'] ``` 如果你的开发工作在模块领域之外,那么很有可能你甚至没有ModuleDataStore对象。但是在一些情况,你仍然可以从驱动程序读取[active_module accessor](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/ui/console/driver.rb#L607) .或者如果你可以访问[ModuleCommandDispatcher](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/ui/console/module_command_dispatcher.rb#L28),有一个一个给你相同东西的```mod```方法.有时mixin会在派发模块的时候会通过 ```run_simple```方法进行传递.比如,你可以看这个[Msf::Ui::Console::CommandDispatcher::Auxiliary](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/ui/console/command_dispatcher/auxiliary.rb)类 在一些情况就像在post exploit运行脚本,你可能没有 ModuleDataStore 或者 active_module,但是你应该仍然有一个session对象.应该有一个```exploit_datastore``` 给你所有的数据储存选项 ```ruby session.exploit_datastore ``` 如果你无权访问模块或者session对象,最后的源显然是这个framework对象.并且这个framework对象总是存在.否则,像我们之前说的,如果用户设置一个 module-level 选项 没有其他的组件可以看到他,这引入框架对象 ```ruby framework.datastore ``` 所以现在你知道数据储存选项的多个来源.希望在这一点上,你清楚的认识到不是所有的源必然分享所有的东西.如果你尝试所有东西,像一个生成规则,这应该是你的载入顺序 1. Try from the ModuleDataStore 2. Try from active_module 3. Try from session 4. Try from framework ### 核心选项类型 所有核心数据储存选项类型是定义在[option_container.rb](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/option_container.rb) 文件.你应该总是挑选最合适的一个,因为每个都有自己的输入验证 那么你在数据注册阶段初始化一个选项,它应该遵循以下格式 ```ruby OptSomething.new(option_name, [boolean, description, value]) ``` * **option_name** -选项的名字 * **boolean** - 第一个属性,true的意思是这是一个必选的 false的意思是这是一个可选的 * **description** - 关于这个选项的短描述 * **value** - 一个默认值,注意如果第一个属性是false,你不需要提供这个值,它将会自动填充nil 现在让我们讨论关于什么类是可用的 * **OptString** - 通常用于字符串选项。如果输入以“file://”开头,则OptString也会自动假定这是一个文件,并从中读取。但是,在发生这种情况时没有文件路径验证,所以如果要加载文件,则应该使用OptPath,然后自己读取该文件。代码示例: ```ruby OptString.new('MYTEST', [ true, 'Set a MYTEST option', 'This is a default value' ]) ``` * **OptRaw** 实际上它的功能与OptString完全相同 * **OptBool** - bool选项它将验证输入是true或者false.例如y, yes, n, no, 0, 1, 代码示例 ```ruby OptBool.new('BLAH', [ true, 'Set a BLAH option', false ]) ``` * **OptEnum** - 基本上这将限制输入到特定的选项。例如,如果您希望输入是`apple`或者`orange`,而不是其他的.那么OptEnum就是您的选择。代码示例: ```ruby # Choices are: apple or range, defaults to apple OptEnum.new('FRUIT', [ true, 'Set a fruit', 'apple', ['apple', 'orange']]) ``` * **OptPort** -对于输入它意味着是用作端口号。这个数字应该在0 - 65535之间。代码示例: ```ruby OptPort.new('RPORT', [ true, 'Set a port', 21 ]) ``` * **OptAddress** 作为IPv4地址的输入。代码示例: ```ruby OptAddress.new('IP', [ true, 'Set an IP', '10.0.1.3' ]) ``` * **OptAddressRange** 作为IPv4地址的输入,例如:10.0.1.1-10.0.1.20或10.0.1.1/24。您也可以提供文件路径而不是范围,它会自动将该文件视为IP列表。或者,如果你使用rand:3语法,其中3意味着3次,它会为你生成3个随机IP。代码示例: ```ruby OptAddressRange.new('Range', [ true, 'Set an IP range', '10.0.1.3-10.0.1.23' ]) ``` * **OptPath** 如果你的数据储存选项要求一个本地文件路径.请使用此选项。 ```ruby OptPath.new('FILE', [ true, 'Load a local file' ]) ``` * **OptInt** 它可以是一个16进制值或者10进制 ```ruby OptInt.new('FILE', [ true, 'A hex or decimal', 1024 ]) ``` * **OptRegexp** 是一个正则表达式数据存储选项。 ```ruby OptRegexp.new('PATTERN', [true, 'Match a name', '^alien']), ``` **Other types:** 在某些情况下,可能没有适合您的数据存储选项类型。最好的例子是URL:即使没有OptUrl这样的东西,你可以做的是使用OptString类型,然后在你的模块中做一些验证,如下所示: ```ruby def valid?(input) if input =~ /^http:\/\/.+/i return true else # Here you can consider raising OptionValidateError return false end end if valid?(datastore['URL']) # We can do something with the URL else # Not the format we're looking for. Refuse to do anything. end ``` ### register_options 方法 这```register_options```方法可以注册多个基本数据存储选项。基本数据存储选项是必须配置的选项,例如服务器端漏洞中的RHOST选项。或者它是非常常用的,例如登录模块中的各种用户名/密码选项。 以下是在模块中注册多个数据存储选项的示例: ```ruby register_options( [ OptString.new('SUBJECT', [ true, 'Set a subject' ]), OptString.new('MESSAGE', [ true, 'Set a message' ]) ], self.class) ``` ### register_advanced_options 方法 这个```register_advanced_options```方法 以注册多个高级数据存储选项。高级数据存储选项是在使用模块之前不需要用户配置的选项。例如,代理选项几乎总是被视为“高级”。但是,当然,这也意味着大多数用户会觉得难以配置。 注册高级选项的示例: ```ruby register_advanced_options( [ OptInt.new('TIMEOUT', [ true, 'Set a timeout, in seconds', 60 ]) ], self.class) ``` ### 更改数据存储选项的默认值 当一个数据存储选项已经被一个mixin注册时,仍然有办法改变模块的默认值。您可以使用```register_options```方法,也可以在模块的元数据中添加一个DefaultOptions键。 #### 使用register_options更改默认值: 使用register_options其中一个优点是,如果数据存储选项是高级的,这就允许它在基本选项菜单上,这意味着当人们在msfconsole上“show options”时,该选项将会在那里。您还可以更改选项说明,以及此方法是否必须。 #### 使用DefaultOptions更改默认值: 当Metasploit初始化一个模块时,将会调用`import_defaults`方法。此方法将更新所有现有的数据存储选项(这就是为什么`register_options`可以用来更新默认值),然后它将专门检查模块元数据中的DefaultOptions键,并再次更新。 下面是一个使用DefaultOptions键的exploit模块初始化的例子: ```ruby def initialize(info={}) super(update_info(info, 'Name' => "Module name", 'Description' => %q{ This is an example of setting the default value of RPORT using the DefaultOptions key }, 'License' => MSF_LICENSE, 'Author' => [ 'Name' ], 'References' => [ [ 'URL', '' ] ], 'Platform' => 'win', 'Targets' => [ [ 'Windows', { 'Ret' => 0x41414141 } ] ], 'Payload' => { 'BadChars' => "\x00" }, 'DefaultOptions' => { 'RPORT' => 8080 }, 'Privileged' => false, 'DisclosureDate' => "", 'DefaultTarget' => 0)) end ``` ### deregister_options 方法 `deregister_options`方法可以注销基本或高级选项。用法非常简单: ```ruby deregister_options('OPTION1', 'OPTION2', 'OPTION3') ``` ### 在运行时改变数据存储选项 目前,在运行时修改数据存储选项最安全的方法是重写一个方法。例如,一些mixins像这样检索RPORT选项: ```ruby def rport datastore['RPORT'] end ``` 在这种情况下,你可以从模块中覆盖这个rport方法,并返回一个不同的值 ```ruby def rport 80 end ``` 这样,当一个mixin想要这个信息的时候,最终的值是80,而不是实际的值`datastore['RPORT']` ### 理想的数据存储命名 正常选项总是大写,高级选项是驼峰式,规避选项是前缀::驼峰式