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/nops/x86/single_byte.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
###
7
#
8
# This class implements single-byte NOP generation for X86. It takes from
9
# ADMmutate and from spoonfu.
10
#
11
###
12
class MetasploitModule < Msf::Nop
13
14
SINGLE_BYTE_SLED =
15
{
16
# opcode affected registers
17
# ------ ------------------
18
"\x90" => nil , # nop
19
"\x97" => [ 'eax', 'edi' ], # xchg eax,edi
20
"\x96" => [ 'eax', 'esi' ], # xchg eax,esi
21
"\x95" => [ 'eax', 'ebp' ], # xchg eax,ebp
22
"\x93" => [ 'eax', 'ebx' ], # xchg eax,ebx
23
"\x92" => [ 'eax', 'edx' ], # xchg eax,edx
24
"\x91" => [ 'eax', 'ecx' ], # xchg eax,ecx
25
"\x99" => [ 'edx' ], # cdq
26
"\x4d" => [ 'ebp' ], # dec ebp
27
"\x48" => [ 'eax' ], # dec eax
28
"\x47" => [ 'edi' ], # inc edi
29
"\x4f" => [ 'edi' ], # dec edi
30
"\x40" => [ 'eax' ], # inc eax
31
"\x41" => [ 'ecx' ], # inc ecx
32
"\x37" => [ 'eax' ], # aaa
33
"\x3f" => [ 'eax' ], # aas
34
"\x27" => [ 'eax' ], # daa
35
"\x2f" => [ 'eax' ], # das
36
"\x46" => [ 'esi' ], # inc esi
37
"\x4e" => [ 'esi' ], # dec esi
38
"\xfc" => nil , # cld
39
"\xfd" => nil , # std
40
"\xf8" => nil , # clc
41
"\xf9" => nil , # stc
42
"\xf5" => nil , # cmc
43
"\x98" => [ 'eax' ], # cwde
44
"\x9f" => [ 'eax' ], # lahf
45
"\x4a" => [ 'edx' ], # dec edx
46
"\x44" => [ 'esp', 'align' ], # inc esp
47
"\x42" => [ 'edx' ], # inc edx
48
"\x43" => [ 'ebx' ], # inc ebx
49
"\x49" => [ 'ecx' ], # dec ecx
50
"\x4b" => [ 'ebx' ], # dec ebx
51
"\x45" => [ 'ebp' ], # inc ebp
52
"\x4c" => [ 'esp', 'align' ], # dec esp
53
"\x9b" => nil , # wait
54
"\x60" => [ 'esp' ], # pusha
55
"\x0e" => [ 'esp', 'align' ], # push cs
56
"\x1e" => [ 'esp', 'align' ], # push ds
57
"\x50" => [ 'esp' ], # push eax
58
"\x55" => [ 'esp' ], # push ebp
59
"\x53" => [ 'esp' ], # push ebx
60
"\x51" => [ 'esp' ], # push ecx
61
"\x57" => [ 'esp' ], # push edi
62
"\x52" => [ 'esp' ], # push edx
63
"\x06" => [ 'esp', 'align' ], # push es
64
"\x56" => [ 'esp' ], # push esi
65
"\x54" => [ 'esp' ], # push esp
66
"\x16" => [ 'esp', 'align' ], # push ss
67
"\x58" => [ 'esp', 'eax' ], # pop eax
68
"\x5d" => [ 'esp', 'ebp' ], # pop ebp
69
"\x5b" => [ 'esp', 'ebx' ], # pop ebx
70
"\x59" => [ 'esp', 'ecx' ], # pop ecx
71
"\x5f" => [ 'esp', 'edi' ], # pop edi
72
"\x5a" => [ 'esp', 'edx' ], # pop edx
73
"\x5e" => [ 'esp', 'esi' ], # pop esi
74
"\xd6" => [ 'eax' ], # salc
75
}
76
77
def initialize
78
super(
79
'Name' => 'Single Byte',
80
'Alias' => 'ia32_singlebyte',
81
'Description' => 'Single-byte NOP generator',
82
'Author' => 'spoonm',
83
'License' => MSF_LICENSE,
84
'Arch' => ARCH_X86)
85
86
register_advanced_options(
87
[
88
OptBool.new('RandomNops', [ false, "Generate a random NOP sled", true ])
89
])
90
end
91
92
# Generate a single-byte NOP sled for X86
93
def generate_sled(length, opts = {})
94
sled_hash = SINGLE_BYTE_SLED
95
sled_max_idx = sled_hash.length
96
sled_cur_idx = 0
97
out_sled = ''
98
99
random = opts['Random']
100
badchars = opts['BadChars'] || ''
101
badregs = opts['SaveRegisters'] || []
102
103
# Did someone specify random NOPs in the environment?
104
if (!random and datastore['RandomNops'])
105
random = datastore['RandomNops']
106
end
107
108
# Generate the whole sled...
109
1.upto(length) { |current|
110
111
cur_char = nil
112
threshold = 0
113
114
# Keep snagging characters until we find one that satisfies both the
115
# bad character and bad register requirements
116
begin
117
sled_cur_idx = rand(sled_max_idx) if (random == true)
118
cur_char = sled_hash.keys[sled_cur_idx]
119
sled_cur_idx += 1 if (random == false)
120
sled_cur_idx = 0 if (sled_cur_idx >= sled_max_idx)
121
122
# Make sure that we haven't gone over the sled repeat threshold
123
if ((threshold += 1) > self.nop_repeat_threshold)
124
return nil
125
end
126
127
end while ((badchars.include?(cur_char)) or
128
((sled_hash[cur_char]) and
129
((sled_hash[cur_char] & badregs).length > 0)))
130
131
# Add the character to the sled now that it's passed our checks
132
out_sled += cur_char
133
}
134
135
# If the sled fails to entirely generate itself, then that's bogus,
136
# man...
137
if (out_sled.length != length)
138
return nil
139
end
140
141
return out_sled
142
end
143
end
144
145