#!/usr/bin/perl use warnings; use strict; use AnyEvent; use AnyEvent::DBI::MySQL; use Config::Tiny; use FindBin; use utf8; use Coro; use Coro::Socket; use Coro::Handle; use lib "$FindBin::Bin/../module"; my $server_config_file = "$FindBin::Bin/../etc/config.ini"; my $config = Config::Tiny->new; my $server_config = $config->read($server_config_file); my $server_log_info = $server_config->{'server_config_info'}; my $username = $server_log_info->{'username'}; my $password = $server_log_info->{'password'}; my $port = $server_log_info->{'server_port'}; my $host = $server_log_info->{'host'}; my $database = $server_log_info->{'database'}; my $server_ip = $server_log_info->{'server_ip'}; $|++; print "Start listening Port:$port", "\n"; my $s = Coro::Socket->new( LocalAddr => $server_ip, # 创建一个侦听socket LocalPort => $port, Listen => 5, Proto => 'tcp' ) or die $@; my @coro; while (1) { my ( $fh, $peername ) = $s->accept; next unless $peername; &doit($fh); } sub doit { my $dbh = AnyEvent::DBI::MySQL->connect( "dbi:mysql:database=$database", "$username", "$password" ); my $fh = shift; push @coro, async { $fh->autoflush(1); while ( my $line = $fh->readline() ) { log_regex_do( $line, $dbh ) } $fh->close; } } sub log_regex_do { my ( $log, $dbh, $cv ) = @_; my ( $log_type, $url, $source, $local, $date, $option, $offer, $user ) = $log =~ /t:(.*)\|me:(.*)\|so:(.*)\|lo:(.*)\|date:(.*)\|opt:(.*)\|of:(.*)\|u:(.*)$/; my $log_class = type_result( $log_type, $dbh, $cv ); if ( defined bool( $local, $user, $dbh ) ) { my ($log_result) = log_result( $url, $dbh ); if ($log_result) { get_result_db( $log_type, $log_result, $url, $source, $user, $date, $option, $offer, $dbh ); } } } sub type_result { my ( $method, $dbh ) = @_; my $cvs = AnyEvent->condvar; my $type; $dbh->do("set names utf8"); $dbh->selectall_hashref( "select * from w3a_log_monitor_type", 'id', sub { my ($ary_ref) = @_; for my $id ( keys %$ary_ref ) { $type = $ary_ref->{$id}->{'id'} if ( $method eq $ary_ref->{$id}->{'log_type_name'} ); } $cvs->send; } ); $cvs->recv; return $type; } sub bool { my ( $local, $user, $dbh ) = @_; my $cv = AnyEvent->condvar; my $count; # $dbh->do("set names utf8"); $dbh->selectcol_arrayref( "select * from w3a_log_monitor where task_name='$user' and task_url='$local'", sub { my ($ref_ary) = @_; $count = @$ref_ary; $cv->send; } ); $cv->recv; return $count; } sub get_result_db { my ( $type, $method_id, $method_url, $method_source, $method_user, $method_date, $method_option, $method_offer, $dbh ) = @_; my $cv = AnyEvent->condvar; my $sth = $dbh->prepare( " insert into w3a_log_monitor_attack ( method_name, method_url, attack_source, attack_user, attack_date, attack_option, attack_offer, log_type )values(?,?,?,?,?,?,?,?) " ); $sth->bind_param( 1, $method_id ); $sth->bind_param( 2, $method_url ); $sth->bind_param( 3, $method_source ); $sth->bind_param( 4, $method_user ); $sth->bind_param( 5, $method_date ); $sth->bind_param( 6, $method_option ); $sth->bind_param( 7, $method_offer ); $sth->bind_param( 8, $type ); $sth->execute( sub { my ($rv) = @_; $cv->send; } ); $cv->recv; } sub log_result { my ( $method, $dbh ) = @_; my $cv = AnyEvent->condvar; my $sum_dbh = $dbh; my @target_id; $dbh->do("set names utf8"); $dbh->selectall_hashref( "select * from w3a_log_method", 'id', sub { my ($ary_ref) = @_; for my $id ( keys %$ary_ref ) { $cv->begin; my $switch = $ary_ref->{$id}->{'method_switch'}; unless ( $switch == 0 ) { if ( $method =~ /$ary_ref->{$id}->{'method_regex'}/i ) { print "Match regular is: ", $ary_ref->{$id}->{'method_regex'}, "\n"; push @target_id, $ary_ref->{$id}->{'id'}; } } $cv->end; } } ); $cv->recv; attack_update( $_, $dbh ) for @target_id; return @target_id; } sub attack_update { my ( $id, $dbh ) = @_; my $cv = AnyEvent->condvar; $dbh->selectcol_arrayref( "select attack_sum from w3a_log_method where id='$id' ", sub { my ($ref_ary) = @_; my $sum = $ref_ary->[0] + 1; $dbh->do( "update w3a_log_method set attack_sum='$sum' where id='$id'"); $cv->send; } ); $cv->recv; }
使用方法如下:
1.服务端监控
2.客户端监控
3.进行XSS模拟
4.查看服务端状态
XSS之前的数据库查询状态
XSS之后的数据库查询状态