Add @jlee-r7's changes to perl encoding

bug/bundler_fix
jvazquez-r7 2014-10-07 00:16:16 -05:00
parent 0ec855cd07
commit e63b389713
1 changed files with 62 additions and 32 deletions

View File

@ -48,10 +48,67 @@ class Metasploit3 < Msf::Encoder
#
def encode_block_perl(state, buf)
hex = buf.unpack("H*")
hex = buf.unpack("H*").join
cmd = 'perl -e '
qot = ',-:.=+!@#$%^&'
# Convert spaces to IFS...
if state.badchars.include?(" ")
if state.badchars.match(/[${IFS}]/n)
raise RuntimeError
end
cmd.gsub!(/\s/, '${IFS}')
end
# Can we use single quotes to enclose the command string?
if state.badchars.include?("'")
if (state.badchars.match(/[()\\]/))
# We don't have parens, quotes, or backslashes so we have to use
# barewords on the commandline for the argument to the pack
# function. As a consequence, we can't use things that the shell
# would interpret, so $ and & become badchars.
qot.delete("$")
qot.delete("&")
# Perl chains -e with newlines, but doesn't automatically add
# semicolons, so the following will result in the interpreter
# seeing a file like this:
# system
# pack
# qq^H*^,qq^whatever^
# Since system and pack require arguments (rather than assuming
# $_ when no args are given like many other perl functions),
# this works out to do what we need.
cmd << "system -e pack -e #{perl_qq(state, qot, hex)}"
if state.badchars.include?(" ")
# We already tested above to make sure that these chars are ok
# if space isn't.
cmd.gsub!(" ", "${IFS}")
end
else
# Without quotes, we can use backslash to escape parens so the
# shell doesn't try to interpreter them.
cmd << "system\\(pack\\(#{perl_qq(state, qot, hex)}\\)\\)"
end
else
# Quotes are ok, but we still need parens or spaces
if (state.badchars.match(/[()]/n))
if state.badchars.include?(" ")
# No spaces allowed, no paranthesis, give up...
raise RuntimeError
end
cmd << "'system pack #{perl_qq(state, qot, hex)}'"
else
cmd << "'system(pack(#{perl_qq(state, qot, hex)}))'"
end
end
return cmd
end
def perl_qq(state, qot, hex)
# Find a quoting character to use
state.badchars.unpack('C*') { |c| qot.delete(c.chr) }
@ -59,37 +116,10 @@ class Metasploit3 < Msf::Encoder
raise RuntimeError if qot.length == 0
sep = qot[0].chr
# Convert spaces to IFS...
if state.badchars.include?(" ")
cmd.gsub!(/\s/, '${IFS}')
end
# Can we use single quotes to enclose the command string?
if state.badchars.include?("'")
if state.badchars.match(/\(|\)/)
# No paranthesis...
raise RuntimeError
end
cmd << "system\\(pack\\(qq#{sep}H\\*#{sep},qq#{sep}#{hex}#{sep}\\)\\)"
else
if state.badchars.match(/\(|\)/)
if state.badchars.include?(" ")
# No spaces allowed, no paranthesis, give up...
raise RuntimeError
end
cmd << "'system pack qq#{sep}H*#{sep},qq#{sep}#{hex}#{sep}'"
else
cmd << "'system(pack(qq#{sep}H*#{sep},qq#{sep}#{hex}#{sep}))'"
end
end
return cmd
# Use an explicit length for the H specifier instead of just "H*"
# in case * is a badchar for the module, and for the case where this
# ends up unquoted so the shell doesn't try to expand a path.
"qq#{sep}H#{hex.length}#{sep},qq#{sep}#{hex}#{sep}"
end
end