COMMAND
ssh
SYSTEMS AFFECTED
Linux, SunOS (others?)
PROBLEM
Ivo van der Wijk posted following. To understund it in all,
you'll have to read ssh #3 from 'mUNIXes' section. (if you missed
it, adding a line like:
LocalForward 80 remotehost:80
to your $HOME/.ssh/config will forward a priviliged port to a
remote port, whithout needing root).
Anyway, after appling fix the bug still works when using 2^16 + 80
(ie. 16 bit wrap). Make sure that if you decide not to remove the
suid-root bit, but patch ssh itself, not to make this mistake. If
you did so, Ivo found something new.
On host1, you open an ssh connection to a machine running sshd
where you have a working account using -R (RemoteForward, which
is somewhat the opposite of LocalForward, but behaves the same in
this case) like this:
host1$ ssh -R 65621:host1.com:80 victim.com
ivo's passord:
victim$
(in this case, 65621 is equal to 2^16+85, i.e. port 85, the other
ports were in use. And sshd on victim.com will hapilly forward
priviliged port victim.com:85 to host1.com:80!
SOLUTION
Thamer Al-Herbish posted patch. These are against 1.2.17.
Common subdirectories: ssh-1.2.17/gmp-2.0.2-ssh-2 and ssh-fixed-1.2.17/gmp-2.0.2-ssh-2
diff -c ssh-1.2.17/newchannels.c ssh-fixed-1.2.17/newchannels.c
*** ssh-1.2.17/newchannels.c Wed Oct 30 04:27:54 1996
--- ssh-fixed-1.2.17/newchannels.c Sat Aug 23 14:19:29 1997
***************
*** 1247,1252 ****
--- 1247,1256 ----
/* Check that an unprivileged user is not trying to forward a privileged
port. */
+
+ if (port > 65535)
+ packet_disconnect("Requested port is %d is invalid",port);
+
if (port < 1024 && !is_root)
packet_disconnect("Requested forwarding of port %d but user is not root.",
port);
diff -c ssh-1.2.17/readconf.c ssh-fixed-1.2.17/readconf.c
*** ssh-1.2.17/readconf.c Wed Oct 30 04:27:53 1996
--- ssh-fixed-1.2.17/readconf.c Sat Aug 23 14:29:08 1997
***************
*** 389,394 ****
--- 389,400 ----
fatal("%.200s line %d: Badly formatted port number.",
filename, linenum);
fwd_port = atoi(cp);
+
+ if(fwd_port < 1024 && original_real_uid)
+ fatal("Port %d may only be forwarded by root.",fwd_port);
+ if(fwd_port > 65535)
+ fatal("Port %d is illegal",fwd_port);
+
cp = strtok(NULL, WHITESPACE);
if (!cp)
fatal("%.200s line %d: Missing second argument.",
***************
*** 408,413 ****
--- 414,425 ----
fatal("%.200s line %d: Badly formatted port number.",
filename, linenum);
fwd_port = atoi(cp);
+
+ if(fwd_port < 1024 && original_real_uid)
+ fatal("Port %d may only be forwarded by root.",fwd_port);
+ if(fwd_port > 65535)
+ fatal("Port %d is illegal",fwd_port);
+
cp = strtok(NULL, WHITESPACE);
if (!cp)
fatal("%.200s line %d: Missing second argument.",
diff -c ssh-1.2.17/ssh.c ssh-fixed-1.2.17/ssh.c
*** ssh-1.2.17/ssh.c Wed Oct 30 04:27:54 1996
--- ssh-fixed-1.2.17/ssh.c Sat Aug 23 14:18:59 1997
***************
*** 483,488 ****
--- 483,499 ----
usage();
/*NOTREACHED*/
}
+
+ if(fwd_port > 65535) {
+ fprintf(stderr,"Illegal port specified %d\n",fwd_port);
+ exit(1);
+ }
+ if (fwd_port < 1024 && original_real_uid != 0) {
+ fprintf(stderr,
+ "Privileged ports can only be forwarded by root.\n");
+ exit(1);
+ }
+
add_remote_forward(&options, fwd_port, buf, fwd_host_port);
break;
***************
*** 496,503 ****
}
if (fwd_port < 1024 && original_real_uid != 0)
{
! fprintf(stderr,
! "Privileged ports can only be forwarded by root.\n");
exit(1);
}
add_local_forward(&options, fwd_port, buf, fwd_host_port);
--- 507,517 ----
}
if (fwd_port < 1024 && original_real_uid != 0)
{
! if(fwd_port > 65535)
! fprintf(stderr,"Ilegal port specified %d\n",fwd_port);
! else
! fprintf(stderr,
! "Privileged ports can only be forwarded by root.\n");
exit(1);
}
add_local_forward(&options, fwd_port, buf, fwd_host_port);
Common subdirectories: ssh-1.2.17/zlib-1.0.3 and ssh-fixed-1.2.17/zlib-1.0.3