kitan Posted October 18, 2016 · Report post Последнее время наблюдаем резкое повышение исходящего трафика от некоторых клиентов. Выяснилось, что у всех клиентов стоят похожие видеорегистраторы в которых пароль от telnet вшит в прошивку. Регистраторы клиенты подключают напрямую, без роутера. Благодаря этой уязвимости видеорегистраторы заражаются и начинают одновременно Ddos'ить внешние ресурсы. К слову, проблема известная http://www.securitylab.ru/news/483934.php . Инсталяторы клиента ничего сделать с этой проблемой не могут и разводят руки. Прошивка регистраторов непомогает. Некоторые клиенты считают что это не их проблема и делать ничего не хотят. Может кто сталкивался с такой проблемой? Какие варианты борьбы? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Negator Posted October 18, 2016 · Report post Регистраторы клиенты подключают напрямую, без роутера. Вот что бывает если выдавать пул реальников на порт каждому. Варианты борьбы следующие: 1. Заблокировать порт телнета. В реале он мало кому нужен. Сообразительные откроют в личном кабинете или по звонку. 2. Отключать таких клиентов до решения проблемы. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
maxlapshin Posted October 18, 2016 · Report post в шутку могу вам предложить самостоятельно перепрошить такой регистратор. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
kitan Posted October 19, 2016 · Report post maxlapshin, черевато вероятностью получить кирпич. Пока ничего лучше не приходит в голову, чем написать скрипт, который будет анализировать netflow и на заданное время гасить порты клиентов Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
maxlapshin Posted October 21, 2016 · Report post Кирпич можно, но это крайне редко. За этот год мы в кирпич смогли превратить только две камеры: одну прошили не той прошивкой (от другого чипсета, надо через SPI перешивать) и камеру Сони (там посерьезнее проверка). Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
SerJiо Posted November 8, 2016 · Report post Я обладатель такого регистратора. Как решить эту проблему? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Blacklotus Posted November 8, 2016 · Report post Что за рег используете? http://forum.nag.ru/forum/index.php?showtopic=123303 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
roysbike Posted November 18, 2016 (edited) · Report post Да , была такая проблема. Модифицировал spamblock (разработчик скрипта на этом сайте). Анализирует и блокирует на 9600 сек IP адрес на dst port 23 и 25 #iptables #Spamblock ipset destroy spammers ipset -N spammers iphash --probes 2 --resize 100 timeout 9600 $IPTABLES -A FORWARD -p tcp --dport 23 -m set --match-set spammers src -j DROP $IPTABLES -A FORWARD -p tcp --dport 25 -m set --match-set spammers src -j DROP spamblock.pl.conf #!/bin/sh # spamblock.conf IFACE="eth0" #uplink FIREWALL_TYPE="ipset" IPSET_NAME=spammers IPFW_TABLE="15" POLICY="5 1 10 3 15 6 20 10 60 60 300 600 1000 3000" EMAIL=your_mail@mail.ru" WHITELIST="1.2.3.4, 5.6.7.8" ## EOF ## cat spamblock.pl #!/usr/bin/perl # # spamblock -- detect and block spammers on FreeBSD- and Linux-based routers. # # Written at Jun 2009, Apr 2010 by ilya.evseev@gmail.com # Distributed as public domain from here: # http://sources.homelink.ru/spamblock/ # use strict; use warnings; use FindBin; use Config::General; use Time::Local; my $cfgname = @ARGV ? shift @ARGV : "$FindBin::Bin/$FindBin::Script.conf"; my $cfgfile = new Config::General($cfgname) or die "Cannot open $cfgname: $!\n"; my %Config = $cfgfile->getall; my $watch_iface = ($Config{IFACE} || $ARGV[0]) or die "Configuration line missing: IFACE=<string>\n"; my $BLOCK_TTL = $Config{BLOCK_TTL} || 3600; my $blocks_filename = $Config{BLOCKS_FILE} || '/var/log/spamblock_blocklist.txt'; my $stats_filename = $Config{STATS_FILE} || '/var/log/spamblock_fullstats.txt'; my $import_semaphore = $Config{IMPORT_SEMAPHORE} || '/var/lock/spamblock_import.semaphore'; my $export_semaphore = $Config{EXPORT_SEMAPHORE} || '/var/lock/spamblock_export.semaphore'; my $email_recipient = $Config{EMAIL}; # ..good for default: root@localhost? my %whitelist = map { $_ => 1 } split(/[,\s]\s*/, $Config{WHITELIST} || ''); my $check_policy = $Config{POLICY} or die "Configuration line missing: POLICY=\"count_1 period_1 count_2 period_2\"\n"; my @checks = split(/\s+/, $check_policy) or die "Configuration line empty: POLICY\n"; die "Policy MUST be even-sized in \"count period ...\" format" if @checks % 2; my %stats; # IP => { count => lasttime, ... } my %blocks; # IP => 1 my $tstamp = time; my $tstart = $tstamp; my $total_checks = 0; my $total_blocks = 0; my $fw; #use Data::Dumper; sub tprint { my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($tstamp); printf("[ %04d.%02d.%02d %02d:%02d:%02d ] @_\n", $year+1900, $mon+1, $mday, $hour, $min, $sec); } sub import_state() { tprint "Import state..."; my %new_blocks; $fw->import_state(\%new_blocks); my ($readed, $added, $deleted, $total) = (0,0,0,0); while (my ($ip, undef) = each %blocks) { $total++; next if $new_blocks{$ip}; $deleted++; delete $blocks{$ip}; $total--; } while (my ($ip, undef) = each %new_blocks) { $readed++; next if $blocks{$ip}; $added++; $blocks{$ip} = 1; $total++; } tprint sprintf("Import done. Total %d, readed %d, added %d, deleted %d blocks.", $total, $readed, $added, $deleted); } sub mkoutfile($$) { my ($fname, $desc) = @_; return if not $fname or $fname eq '-'; tprint "Dump $desc to $fname..."; my $fd; unless (open $fd, "> $fname") { print STDERR "Cannot open $fname: $!\n"; return; } $fd; } sub ip2hex($) { my @a = split(/\./, shift); my $b = 0; $b = $b * 256 + $_ foreach @a; sprintf("%08X", $b); } sub export_blocks() { my $fd = mkoutfile($blocks_filename, 'blocks') or return; print $fd "$_\n" foreach sort { ip2hex($a) cmp ip2hex($b) } keys %blocks; close $fd; } sub export_stats() { $tstamp = time; my $fd = mkoutfile($stats_filename, 'stats') or return; printf $fd "# Uptime: %d seconds, %d checks, %d blocks.\n", ($tstamp - $tstart), $total_checks, $total_blocks; printf $fd "# %-18s%8s %6s", 'IP', 'Checks', 'Blocks'; my @iplist = sort { ip2hex($a) cmp ip2hex($b) } keys %stats; foreach my $ip (@iplist) { my $stat = $stats{$ip}; my @fields = sort { # use numeric-based sorting for numeric fields ($a =~ /^\d+$/ and $b =~ /^\d+$/) ? ($a <=> $b) : ($a cmp $b); } keys %$stat; printf $fd "%-20s%8d%6s\n", $ip, $stat->{total_count} || 0, $stat->{blocks_count} || '-'; } close $fd; } sub export_state() { tprint "Dump state..."; export_blocks(); export_stats(); tprint "Dump done."; } sub handle_semaphore($$$) { my ($fname, $handler, $description) = @_; return if not $fname or $fname eq '-' or not -w $fname; tprint "Found $fname semaphore, perform $description..."; $handler->(); unlink $fname; tprint "Delete $fname, $description done."; } my $typ = lc($Config{FIREWALL_TYPE} || 'auto'); $fw = new ipset (\%Config) if $typ eq 'ipset' or ($typ eq 'auto' and -x '/sbin/ipset'); $fw ||= new iptables(\%Config) if $typ eq 'iptables' or ($typ eq 'auto' and -x '/sbin/iptables'); $fw ||= new pf (\%Config) if $typ eq 'pf' or ($typ eq 'auto' and -w '/dev/pf'); $fw ||= new ipfw (\%Config) if $typ eq 'ipfw' or ($typ eq 'auto' and -x '/sbin/ipfw'); tprint "Started now."; import_state(); #tprint "Debug export and exit!"; export_state(); exit; $SIG{USR1} = \&import_state; $SIG{USR2} = \&export_state; open F, "tcpdump -lnnqttpi $watch_iface tcp and dst port 23 or dst port 25 and 'tcp[13] == 2' 2>&1 |" #open F, "tcpdump -lnnqttpi $watch_iface tcp 2>&1 |" #open F, "tcpdump -lnnqttpi $watch_iface tcp and dst port 23 2>&1 |" or die "Cannot run tcpdump: $!\n"; select((select(F), $|=1)[0]); # ..disable buffering while(<F>) { #chomp; #tprint "line = \"$_\""; next unless /^(\d+)\.(\d+) IP (\d+\.\d+\.\d+\.\d+)\.\d+ \> \d+\.\d+\.\d+\.\d+\.2[3,5]: /; my ($tstamp0, $tstamp0_msecs, $ip) = ($1, $2, $3); $total_checks++; handle_semaphore($import_semaphore, \&import_state, 'import'); handle_semaphore($export_semaphore, \&export_state, 'export'); my $s = ($stats{$ip} ||= {}); ($s->{total_count} ||= 0)++; $tstamp = time; next if $whitelist{$ip}; next if $blocks{$ip} and $tstamp0 - $blocks{$ip} < $BLOCK_TTL; my @stats; my $blockmsg; for (my $i = 0; $i < @checks; $i+=2) { my $maxcount = $checks[$i]; my $period = $checks[$i+1]; $s->{$maxcount} ||= $tstamp0; next if $s->{total_count} % $maxcount; my $delta = $tstamp0 - $s->{$maxcount}; push @stats, "$maxcount:$delta"; if ($delta >= $period) { $s->{$maxcount} = $tstamp0; next; } $total_blocks++; ($s->{blocks_count} ||= 0)++; $blocks{$ip} = $tstamp0; $blockmsg = "Block $ip: trap #$s->{blocks_count}" ." by rule $maxcount:$period ticks:seconds," ." actually $delta seconds"; $fw->block($ip); last; } tprint sprintf(" %-20s%8d:%d \t@stats", $ip, $s->{total_count}, $tstamp - $tstart); next unless $blockmsg; tprint $blockmsg; # Report by email next if not $email_recipient or $email_recipient eq '-'; unless (open M, "| mail -s 'SpamBlock $ip' $email_recipient") { warn "Cannot run mail: $!\n"; next; } print M $blockmsg, "\n"; close M; } close F; #======================================================================= package fwbase; sub new($$$$$) { my ($class, $cfg, $paramname, $hint) = @_; my ($package, $filename, $line) = caller; ::tprint "Firewall type: $package"; my $val = $cfg->{$paramname} or die "Missing $hint in configuration file!\n"; bless({ $paramname => $val }, ref($class) || $class); } sub import_custom($$$$) { my ($class, $blocks, $infile, $filter) = @_; open S, $infile or die "Cannot get $infile: $!\n"; while (<S>) { $blocks->{$1} = 1 if $_ =~ $filter; } close S; $blocks; } #======================================================================= package ipfw; use base 'fwbase'; sub new($$) { my ($class, $cfg) = @_; my $self = $class->SUPER::new($cfg, 'IPFW_TABLE', 'IPFW_TABLE=<number>'); bless($self, ref($class) || $class); } sub import_state($$) { my ($self, $blocks) = @_; $self->import_custom($blocks, "/sbin/ipfw table $self->{IPFW_TABLE} list |", '^(\d+\.\d+\.\d+\.\d+)\/\d+ \d+$'); } sub block($$) { my ($self, $ip) = @_; system("/sbin/ipfw -q table $self->{IPFW_TABLE} add $ip"); } #======================================================================= package pf; use base 'fwbase'; sub new($$) { my ($class, $cfg) = @_; my $self = $class->SUPER::new($cfg, 'PF_TABLE', 'PF_TABLE=<string>'); bless($self, ref($class) || $class); } sub import_state($$) { my ($self, $blocks) = @_; $self->import_custom($blocks, "/sbin/pfctl -t $self->{PF_TABLE} -T show |", '^\s*(\d+\.\d+\.\d+\.\d+)$'); } sub block($$) { my ($self, $ip) = @_; system("/sbin/pfctl -t $self->{PF_TABLE} -T add $ip"); } #======================================================================= package ipset; use base 'fwbase'; sub new($$) { my ($class, $cfg) = @_; my $self = $class->SUPER::new($cfg, 'IPSET_NAME', 'IPSET_NAME=<string>'); bless($self, ref($class) || $class); } sub import_state($$) { my ($self, $blocks) = @_; $self->import_custom($blocks, "/sbin/ipset -L $self->{IPSET_NAME} |", '^(\d+\.\d+\.\d+\.\d+)$'); } sub block($$) { my ($self, $ip) = @_; system("/sbin/ipset -A $self->{IPSET_NAME} $ip"); #system("/usr/sbin/ipset -qA $self->{IPSET_NAME} $ip"); } #======================================================================= package iptables; use base 'fwbase'; sub new($$) { my ($class, $cfg) = @_; my $self = $class->SUPER::new($cfg, 'IPTABLES_CHAIN', 'IPTABLES_CHAIN=<string>'); bless($self, ref($class) || $class); } sub import_state($$) { my ($self, $blocks) = @_; $self->import_custom($blocks, "/sbin/iptables -nL $self->{IPTABLES_CHAIN} |", '^(\d+\.\d+\.\d+\.\d+)$'); } sub block($$) { my ($self, $ip) = @_; system("/sbin/iptables -nL $self->{IPTABLES_CHAIN}" ." | grep -q -- ' $ip '" ." || /sbin/iptables -I $self->{IPTABLES_CHAIN} -s $ip -j DROP" ); } ## EOF ## Запускать /opt/spamblock.pl >> /var/log/spamblock.log 2>&1 & Edited November 18, 2016 by roysbike Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...