Здравсвуйте начинающие и другие администраторы unix. В данной статья я расскажу Вам, что такое exploit и как с ним можно бороться.
Эксплойт, эксплоит, сплоит (англ. exploit, эксплуатировать) — это компьютерная программа, фрагмент программного кода или последовательность команд, использующие уязвимости в программном обеспечении и применяемые для проведения атаки на вычислительную систему. Целью атаки может быть как захват контроля над системой (повышение привилегий), так и нарушение её функционирования (DoS-атака).
Представлю вам скрипт, который будет искать exploits, phpshells на Вашем сервере в директориях юзеров.
#!/usr/bin/perl
# This will look for all the php view scripts we know about right now
# This one will mail sysadmins
# viewscan 2.0 Stephanie
#-----------------------------------------------------------------------#
use DBI;
use File::Find;
no warnings 'File::Find';
use vars qw(%userdata *fname $admin %legend);
# данные для коннект к базе данных. чтобы дернуть емайлы клиентов
$dbname = "hsphere";
$username = "xxxxxr";
$dbhost="db_host";
$password="xxxx";
$dbport = "5432";
$dboptions = "-e";
$dbtty = "ansi";
$dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=$dbhost;;port=$dbport;options=$dboptions;tty=$dbtty","$username","$password",
{PrintError => 0});
if ($DBI::err != 0) {
print $DBI::errstr . "\n";
exit($DBI::err);
}
# define some descriptions
%legend = (
'rem' => "remote viewing script",
'shl' => "PhpShell",
'rg' => "r00t_Group exploit",
'r5' => "r57 shell viewer",
'c99' => "c99 shell viewer",
'xss' => "XSS shell backdoor",
'tvi' => "TView viewer",
'dxs' => "DxShell",
'gfs' => "Group Freedom Search",
'nfm' => "Network File Manager",
'pcs' => "Php Config Spy",
'mys' => "MyShell Viewer",
'dm' => "Possible Dark Mailer or r57 script please check",
'l57' => "L57 shell script",
'vs' => "V99x Shell Script",
'cc' => "Captain Crunch shell viewer",
'snp' => "Sniper Symlink Tool",
'maa' => "Maanyan crew file uploader",
'dh' => "Dragon Hacker php script",
'aoc' => "Angel Of Computer Shell",
'webb' => "Web Shell",
'shell' => "Shell",
'shel' => "shell"
);
# for ease of access, glob the fname
*fname = *File::Find::name;
# the address to which to send no-email user notices
$admin = "Sysadmins
sub main {
# pull password entries
print "Fetching users... ";
&fetchUsers;
print "DONE.\n";
# find the scripts and add them to the user data
print "Searching scripts... please wait.\n";
&findScripts;
# disable scripts & email them about it
&disableScripts;
}
sub fetchUsers {
while (my ($user, $uid, $home, $shell) = (getpwent())[0,2,7,8]) {
# if you have a UID smaller than 500, skip it
next if ($uid < 500);
# skip specific users we don't want touched
next if ($user =~ m/cpanel/);
# build their data reference and add them
print $home."\r\n";
$userdata{$user}->{'home'} = $home;
}
}
sub testScript {
my ($user, $file) = @_;
open(FH, $file) or return 0;
undef $/; my $contents =
close(FH);
if (($file =~ m/\.(set|pl)$/i) && ($contents =~ m/NMS\s+/i)) {
return 0;
}
sub findScripts {
foreach my $user (keys(%userdata)) {
my $webdir = $userdata{$user}->{'home'};
# iterate through their set/pl/php scripts
my @scripts;
File::Find::find(
sub {
# skip if we're in an guestbook, webalizer, or _vti directory
return if ($fname =~ m/(\.(htpasswds|trash)|_vti)/);
if (/^.*\.(cgi|pl|asp|php)$/si) {
&testScript($user, $fname);
}
}, $webdir
);
}
}
## check for remote view scripts
if ($file =~ m/php$/i) {
if ($contents =~ m/Welcome\s+to phpRemoteView/) {
my @violation = ($file, "rem");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (possible remote viewing script)\n", $user, $file);
return 1;
}
}
## check for remote view scripts
if ($file =~ m/php$/i) {
if ($contents =~ m/PhpShell\s+2.0 /) {
my @violation = ($file, "shl");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (PhpShell script)\n", $user, $file);
return 1;
}
}
## check for r00t_Group scripts
if ($file =~ m/php$/i) {
if ($contents =~ m/r00t_Group\s+/) {
my @violation = ($file, "rg");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (r00t_group exploit)\n", $user, $file);
return 1;
}
}
## check for r57 shell scripts
if ($file =~ m/php$/i) {
if ($contents =~ m/r57shell\s+/) {
my @violation = ($file, "r5");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (r57 shell viewer)\n", $user, $file);
return 1;
}
}
## check for c99 shell scripts
if ($file =~ m/php$/i) {
if ($contents =~ m/c99shell\s+/) {
my @violation = ($file, "c99");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (c99 shell viewer)\n", $user, $file);
return 1;
}
}
## check for c99.php shell scripts
if ($file =~ m/php$/i) {
if ($contents =~ m/c99shell.php\s+/) {
my @violation = ($file, "c99");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (c99 shell viewer)\n", $user, $file);
return 1;
}
}
## check for TView viewer
if ($file =~ m/php$/i) {
if ($contents =~ m/nst.void.ru\s+/) {
my @violation = ($file, "tvi");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (TVI viewer)\n", $user, $file);
return 1;
}
}
## check for DxShell
if ($file =~ m/php$/i) {
if ($contents =~ m/DxShell\s+/) {
my @violation = ($file, "dxs");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (DxShell)\n", $user, $file);
return 1;
}
}
## check for Angel Of Computer Shell
if ($file =~ m/php$/i) {
if ($contents =~ m/Angel\s+Of\s+Computer\s+\Shell/) {
my @violation = ($file, "aoc");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (Angel Of Computer Shell)\n", $user, $file);
return 1;
}
}
## check for Group Freedom Search
if ($file =~ m/php$/i) {
if ($contents =~ m/GFS\s+Web-Shell/) {
my @violation = ($file, "gfs");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (Group Freedom Search)\n", $user, $file);
return 1;
}
}
## check for Network File Manager
if ($file =~ m/php$/i) {
if ($contents =~ m/NetworkFileManagerPHP\s+/) {
my @violation = ($file, "nfm");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (Network File Manager)\n", $user, $file);
return 1;
}
}
## check for php config spy
if ($file =~ m/php$/i) {
if ($contents =~ m/PhpConfigSpy\s+v0.1/) {
my @violation = ($file, "pcs");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (php config spy)\n", $user, $file);
return 1;
}
}
## check for XSS Backdoor
if ($file =~ m/asp$/i) {
if ($contents =~ m/XSS\s+Backdoor/) {
my @violation = ($file, "xss");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (Xss Backdoor)\n", $user, $file);
return 1;
}
}
## check for crunchy stuff (Lotus7 group)
if ($file =~ m/php$/i) {
if ($contents =~ m/Modified\s+c100\s+Shell/) {
my @violation = ($file, "cc");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (Cap Crunch script)\n", $user, $file);
return 1;
}
}
## check for Sniper Symlink tool
if ($file =~ m/php$/i) {
if ($contents =~ m/Developer\s+by\s+SnIpEr_SA/) {
my @violation = ($file, "snp");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (sniper Symlink script)\n", $user, $file);
return 1;
}
}
## check for L57
if ($file =~ m/php$/i) {
if ($contents =~ m/L!nux\s+Hack3r/) {
my @violation = ($file, "l57");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (L57 Shell Script)\n", $user, $file);
return 1;
}
}
## check for V99x
if ($file =~ m/php$/i) {
if ($contents =~ m/shell\s+Hack15/) {
my @violation = ($file, "vs");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (V99x Shell Script)\n", $user, $file);
return 1;
}
}
## check for file uploader maanyan
if ($file =~ m/php$/i) {
if ($contents =~ m/DAYAK\s+MA'ANYAN/) {
my @violation = ($file, "maa");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (ma anyan crew file uploader)\n", $user, $file);
return 1;
}
}
## check for dragon hacker
if ($file =~ m/php$/i) {
if ($contents =~ m/Dragon\s+Hacker/) {
my @violation = ($file, "dh");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (Dragon hacker script)\n", $user, $file);
return 1;
}
}
## Dark Mailer stuff
if (($file =~ m/\/(dm)\.(cgi|pl)$/i) || ($file =~ m/\/dm.cgi/i) || ($file =~ m/\/r57.php/i)) {
my @violation = ($file, "dm");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (possible Dark Mailer Script please check)\n", $user, $file);
return 1;
}
## check for MyShell viewers
if ($file =~ m/php$/i) {
if ($contents =~ m/shell.php,v\s+1.1.0 beta/) {
my @violation = ($file, "mys");
push(@{$userdata{$user}->{'exploited'}}, \@violation);
printf("%s -> %s (MyShell Viewer)\n", $user, $file);
return 1;
}
}
}
sub disableScripts {
foreach my $user (keys(%userdata)) {
if (exists($userdata{$user}->{'exploited'})) {
foreach my $pair (@{$userdata{$user}->{'exploited'}}) {
my ($script, $reason) = @$pair;
printf("Renaming %s -> %s_contact.support\n", $script, $script);
rename($script, $script . "_contact.support");
chmod 0000,$script."_contact.support";
chown 0,0,$script."_contact.support";
}
# if the user has an email - tell them about it
# if (exists($userdata{$user}->{'email'})) {
# # email the user a notice
# &emailTech($user);
# } else {
&emailUser($user);
&emailTech($user);
# }
}
}
}
sub emailUser {
my $user = shift;
my $message;
# now i have to check if customer having email
#long way :)
$query = "select id from users where username='$user'";
$sth = $dbh->prepare($query);
$rv = $sth->execute();
$userid = $sth->fetchrow_array();
$sth->finish();
$query = "select account_id from user_account where user_id='$userid'";
$sth = $dbh->prepare($query);
$rv = $sth->execute();
$ac_id = $sth->fetchrow_array();
$sth->finish();
$query = "select ci_id from accounts where id='$ac_id'";
$sth = $dbh->prepare($query);
$rv = $sth->execute();
$ci_id = $sth->fetchrow_array();
$sth->finish();
$query = "select email from contact_info where id='$ci_id'";
$sth = $dbh->prepare($query);
$rv = $sth->execute();
$email = $sth->fetchrow_array();
$sth->finish();
#print "I will send email to $email";
$message = "From: Support
$message .= "To: $email\n";
$message .= "Subject: Potentially Exploited Script(s)\n\n";
$message .= < <"EOF";
Уважаемый клиент, дальше текст ваш
EOF
# add the script names to the message
foreach my $pair (@{$userdata{$user}->{'exploited'}}) {
my ($script, $reason) = @$pair;
$message .= "Script: " . $script . "\n";
$message .= "Description: " . $legend{$reason} . "\n\n";
}
$message .= < <"EOF";
Здесь тоже можете свой текст вставить
EOF
&sendMail($message);
return 1;
}
sub emailTech {
my $user = shift;
my $message;
$message = "From: Server security scanner
$message .= "To: $admin\n";
$message .= "Subject: Potential ssh/viewing Script(s)\n\n";
$message .= "User: $user\n";
# $message .= "System: " . &getHost . "\n\n";
$message .= "Viewscan found the following security issues:\n\n";
# add the script names to the message
foreach my $pair (@{$userdata{$user}->{'exploited'}}) {
my ($script, $reason) = @$pair;
$message .= "Script: " . $script . "\n";
$message .= "Reason: " . $legend{$reason} . "\n\n";
}
$message .= "The script has been disabled, please check the script and mail the customer.\n\n";
$message .= "Also note on this account in Billing Manager.\n\n";
$message .= "- Viewscan (Is your friend)\n\n";
&sendMail($message);
}
sub sendMail {
my $message = shift;
#print "SEND EMAIL";
# send the message to the user
open(SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq") or
die "Can't fork for sendmail: $!\n";
print SENDMAIL $message;
close(SENDMAIL) or warn "sendmail didn't close nicely";
return 1;
}
sub getHost {
my $system = `hostname`;
# pull the subdomain out
my $host = (split(/\./, $system))[0];
return $host;
}
&main;
Сохраняете данный скрипт в какой-либо директории и добавляете в крон задачу. Примерно так:
0 0 * * * /root/exploits.pl
И все. Теперь в 00:00 скрипт будет запускаться и делать свою работу.
Так же Вы можете установить rkhunter на свой сервер и запускать его раз в сутки для обнаружения изменений в основных файлах.