Path: blob/master/modules/encoders/cmd/generic_sh.rb
19813 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Encoder67# Has some issues, but overall it's pretty good8Rank = ManualRanking910def initialize11super(12'Name' => 'Generic Shell Variable Substitution Command Encoder',13'Description' => %q{14This encoder uses standard Bourne shell variable substitution15tricks to avoid commonly restricted characters.16},17'Author' => 'hdm',18'Arch' => ARCH_CMD,19'Platform' => 'unix')20end2122#23# Encodes the payload24#25def encode_block(state, buf)26# Skip encoding for empty badchars27if state.badchars.empty?28return buf29end3031if state.badchars.include?('-')32# Then neither of the others will work. Get rid of spaces and hope33# for the best. This obviously won't work if the command already34# has other badchars in it, in which case we're basically screwed.35if state.badchars.include?(' ')36buf.gsub!(/\s/, '${IFS}')37end38elsif state.badchars.include?('\\')39# Without an escape character we can't escape anything, so echo40# won't work. Try perl.41buf = encode_block_perl(state, buf)42else43buf = encode_block_bash_echo(state, buf)44end4546return buf47end4849#50# Uses the perl command to hex encode the command string51#52def encode_block_perl(state, buf)53hex = buf.unpack('H*')54cmd = 'perl -e '55qot = ',-:.=+!@#$%^&'5657# Find a quoting character to use58state.badchars.unpack('C*') { |c| qot.delete(c.chr) }5960# Throw an error if we ran out of quotes61raise EncodingError if qot.empty?6263sep = qot[0].chr6465# Convert spaces to IFS...66if state.badchars.include?(' ')67cmd.gsub!(/\s/, '${IFS}')68end6970# Can we use single quotes to enclose the command string?71if state.badchars.include?("'")7273if state.badchars.match(/\(|\)/)7475# No parenthesis...76raise EncodingError77end7879cmd << "system\\(pack\\(qq#{sep}H\\*#{sep},qq#{sep}#{hex}#{sep}\\)\\)"8081elsif state.badchars.match(/\(|\)/)82if state.badchars.include?(' ')83# No spaces allowed, no parenthesis, give up...84raise EncodingError85end8687cmd << "'system pack qq#{sep}H*#{sep},qq#{sep}#{hex}#{sep}'"88else89cmd << "'system(pack(qq#{sep}H*#{sep},qq#{sep}#{hex}#{sep}))'"90end9192return cmd93end9495#96# Uses bash's echo -ne command to hex encode the command string97#98def encode_block_bash_echo(state, buf)99hex = ''100101# Can we use single quotes to enclose the echo arguments?102if state.badchars.include?("'")103hex = buf.unpack('C*').collect { |c| '\\\\\\x%.2x' % c }.join104else105hex = "'" + buf.unpack('C*').collect { |c| '\\x%.2x' % c }.join + "'"106end107108# Are pipe characters restricted?109if state.badchars.include?('|')110# How about backticks?111if state.badchars.include?('`')112# Last ditch effort, dollar paren113if state.badchars.include?('$') || state.badchars.include?('(')114raise EncodingError115else116buf = "$(/bin/echo -ne #{hex})"117end118else119buf = "`/bin/echo -ne #{hex}`"120end121else122buf = "/bin/echo -ne #{hex}|sh"123end124125# Remove spaces from the command string126if state.badchars.include?(' ')127buf.gsub!(/\s/, '${IFS}')128end129130return buf131end132end133134135