Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/encoders/cmd/generic_sh.rb
19813 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Encoder
7
8
# Has some issues, but overall it's pretty good
9
Rank = ManualRanking
10
11
def initialize
12
super(
13
'Name' => 'Generic Shell Variable Substitution Command Encoder',
14
'Description' => %q{
15
This encoder uses standard Bourne shell variable substitution
16
tricks to avoid commonly restricted characters.
17
},
18
'Author' => 'hdm',
19
'Arch' => ARCH_CMD,
20
'Platform' => 'unix')
21
end
22
23
#
24
# Encodes the payload
25
#
26
def encode_block(state, buf)
27
# Skip encoding for empty badchars
28
if state.badchars.empty?
29
return buf
30
end
31
32
if state.badchars.include?('-')
33
# Then neither of the others will work. Get rid of spaces and hope
34
# for the best. This obviously won't work if the command already
35
# has other badchars in it, in which case we're basically screwed.
36
if state.badchars.include?(' ')
37
buf.gsub!(/\s/, '${IFS}')
38
end
39
elsif state.badchars.include?('\\')
40
# Without an escape character we can't escape anything, so echo
41
# won't work. Try perl.
42
buf = encode_block_perl(state, buf)
43
else
44
buf = encode_block_bash_echo(state, buf)
45
end
46
47
return buf
48
end
49
50
#
51
# Uses the perl command to hex encode the command string
52
#
53
def encode_block_perl(state, buf)
54
hex = buf.unpack('H*')
55
cmd = 'perl -e '
56
qot = ',-:.=+!@#$%^&'
57
58
# Find a quoting character to use
59
state.badchars.unpack('C*') { |c| qot.delete(c.chr) }
60
61
# Throw an error if we ran out of quotes
62
raise EncodingError if qot.empty?
63
64
sep = qot[0].chr
65
66
# Convert spaces to IFS...
67
if state.badchars.include?(' ')
68
cmd.gsub!(/\s/, '${IFS}')
69
end
70
71
# Can we use single quotes to enclose the command string?
72
if state.badchars.include?("'")
73
74
if state.badchars.match(/\(|\)/)
75
76
# No parenthesis...
77
raise EncodingError
78
end
79
80
cmd << "system\\(pack\\(qq#{sep}H\\*#{sep},qq#{sep}#{hex}#{sep}\\)\\)"
81
82
elsif state.badchars.match(/\(|\)/)
83
if state.badchars.include?(' ')
84
# No spaces allowed, no parenthesis, give up...
85
raise EncodingError
86
end
87
88
cmd << "'system pack qq#{sep}H*#{sep},qq#{sep}#{hex}#{sep}'"
89
else
90
cmd << "'system(pack(qq#{sep}H*#{sep},qq#{sep}#{hex}#{sep}))'"
91
end
92
93
return cmd
94
end
95
96
#
97
# Uses bash's echo -ne command to hex encode the command string
98
#
99
def encode_block_bash_echo(state, buf)
100
hex = ''
101
102
# Can we use single quotes to enclose the echo arguments?
103
if state.badchars.include?("'")
104
hex = buf.unpack('C*').collect { |c| '\\\\\\x%.2x' % c }.join
105
else
106
hex = "'" + buf.unpack('C*').collect { |c| '\\x%.2x' % c }.join + "'"
107
end
108
109
# Are pipe characters restricted?
110
if state.badchars.include?('|')
111
# How about backticks?
112
if state.badchars.include?('`')
113
# Last ditch effort, dollar paren
114
if state.badchars.include?('$') || state.badchars.include?('(')
115
raise EncodingError
116
else
117
buf = "$(/bin/echo -ne #{hex})"
118
end
119
else
120
buf = "`/bin/echo -ne #{hex}`"
121
end
122
else
123
buf = "/bin/echo -ne #{hex}|sh"
124
end
125
126
# Remove spaces from the command string
127
if state.badchars.include?(' ')
128
buf.gsub!(/\s/, '${IFS}')
129
end
130
131
return buf
132
end
133
end
134
135