CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/encoders/x86/alpha_mixed.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'rex/encoder/alpha2/alpha_mixed'
7
8
class MetasploitModule < Msf::Encoder::Alphanum
9
Rank = LowRanking
10
11
def initialize
12
super(
13
'Name' => "Alpha2 Alphanumeric Mixedcase Encoder",
14
'Description' => %q{
15
Encodes payloads as alphanumeric mixedcase text. This encoder uses
16
SkyLined's Alpha2 encoding suite.
17
A pure alpha encoder is impossible without having a register that points at or near the shellcode.
18
In a default configuration the first few bytes at the beginning are an fnstenv getpc stub (the same as used in shikata_ga_nai) and thus are not alphanumeric.
19
You can set BufferRegister for full alpha (see Encoder options for details).
20
},
21
'Author' => [ 'pusscat', 'skylined' ],
22
'Arch' => ARCH_X86,
23
'License' => BSD_LICENSE,
24
'EncoderType' => Msf::Encoder::Type::AlphanumMixed,
25
'Decoder' =>
26
{
27
'BlockSize' => 1,
28
})
29
end
30
31
#
32
# Returns the decoder stub that is adjusted for the size of the buffer
33
# being encoded.
34
#
35
def decoder_stub(state)
36
modified_registers = []
37
reg = datastore['BufferRegister']
38
off = (datastore['BufferOffset'] || 0).to_i
39
buf = ''
40
41
# We need to create a GetEIP stub for the exploit
42
if (not reg)
43
if(datastore['AllowWin32SEH'] and datastore['AllowWin32SEH'].to_s =~ /^(t|y|1)/i)
44
buf = 'VTX630VXH49HHHPhYAAQhZYYYYAAQQDDDd36FFFFTXVj0PPTUPPa301089'
45
reg = 'ECX'
46
off = 0
47
modified_registers.concat (
48
[
49
Rex::Arch::X86::ESP,
50
Rex::Arch::X86::EDI,
51
Rex::Arch::X86::ESI,
52
Rex::Arch::X86::EBP,
53
Rex::Arch::X86::EBX,
54
Rex::Arch::X86::EDX,
55
Rex::Arch::X86::ECX,
56
Rex::Arch::X86::EAX
57
])
58
else
59
res = Rex::Arch::X86.geteip_fpu(state.badchars, modified_registers)
60
if (not res)
61
raise EncodingError, "Unable to generate geteip code"
62
end
63
buf, reg, off = res
64
end
65
else
66
reg.upcase!
67
end
68
69
stub = buf + Rex::Encoder::Alpha2::AlphaMixed::gen_decoder(reg, off, modified_registers)
70
71
# Sanity check that saved_registers doesn't overlap with modified_registers
72
modified_registers.uniq!
73
if (modified_registers & saved_registers).length > 0
74
raise BadGenerateError
75
end
76
77
stub
78
end
79
80
#
81
# Encodes a one byte block with the current index of the length of the
82
# payload.
83
#
84
def encode_block(state, block)
85
Rex::Encoder::Alpha2::AlphaMixed::encode_byte(block.unpack('C')[0], state.badchars)
86
end
87
88
#
89
# Tack on our terminator
90
#
91
def encode_end(state)
92
state.encoded += Rex::Encoder::Alpha2::AlphaMixed::add_terminator()
93
end
94
95
# Indicate that this module can preserve some registers
96
def can_preserve_registers?
97
true
98
end
99
100
# Convert the SaveRegisters to an array of x86 register constants
101
def saved_registers
102
Rex::Arch::X86.register_names_to_ids(datastore['SaveRegisters'])
103
end
104
end
105
106