COMMAND

    SSH LocalForward

SYSTEMS AFFECTED

    Systems running ssh

PROBLEM

    Aeneas bumped into a weird 'feature' of ssh 1.2.20. When you run:

        ssh -L 80:remotehost:80 remotehost

    as a normal user you should get the expected error:

        Privileged ports can only be forwarded by root.

    But if you put:

        LocalForward    80      remotehost:80

    in your  ~/.ssh/config file  and connect  to the  remote host  you
    don't get the  error and port  80 is opened  on the localhost  (an
    httpd was  not running,  the port  must be  available).   When you
    connect to it you get  a normal redirection to remotehost:80  over
    the secure channel.   This means however  that a non-root  user is
    able to open privileged ports on the localhost and redirect  them.
    This was checked on Linux and Solaris.

    It seems that ssh rejects attempts to forward privileged ports for
    non-root  users  while  parsing  the  command line arguments - the
    config file is read further down in the code, without performing a
    similar test.

    The implications are a bit scary  -- on a machine where telnet  or
    rlogin is  normally disabled  an ordinary  user could  set up  ssh
    port redirection  of the  telnet or  rlogin service  to a  machine
    under their  own control.  A user  with ordinary  privileges could
    "run" a  Web server  on a  machine not  currently running a server
    bound to port 80 by redirecting port 80 to another host, etc.

SOLUTION

    ssh only has this ability because it is normally installed setuid.
    Turning  off  the  setuid  bit  on  the ssh client program doesn't
    appear  to  impair  the  normal  operation  of ssh and scp, but it
    definitely turns off the hole which allows privileged TCP/IP ports
    to be forwarded.  So, turn off the setuid bit

        chmod u-s /usr/local/bin/ssh

    until the posted code fix is installed and tested.

    The immediate  fix is  chmod -s  (which will  get rid of potential
    similar holes in ssh as  well...) - the more reasonable  method is
    to move the check into add_local_forward():

    --- readconf.c.orig     Sun Aug  3 00:57:21 1997
    +++ readconf.c  Sun Aug  3 13:20:08 1997
    @@ -204,6 +204,10 @@
       Forward *fwd;
       if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
         fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
    +  if (port < 1024 && original_real_uid != UID_ROOT)
    +  {
    +     fatal("Privileged ports can only be forwarded by root.\n");
    +  }
       fwd = &options->local_forwards[options->num_local_forwards++];
       fwd->port = port;
       fwd->host = xstrdup(host);