We have a system on which users are given a very restricted environment (their shell is a menu) where they should not be able to run arbitrary commands. However, because their shell is not statically linked, ld.so provides a nice clutch of holes for them to exploit. The patch below adds a new configuration option to sshd which quashes their attempts to set LD_PRELOAD etc. using ~/.ssh/environment or the environmentoption in their ~/.ssh/authorized_keys files. It was generated against the OpenBSD version of OpenSSH but applies to the portable version too. Tony. -- f.a.n.finch <dot at dotat.at> http://dotat.at/ SOUTH UTSIRE: NORTHWEST 3 OR 4, OCCASIONALLY 5, BACKING SOUTH FOR A TIME. RAIN AT TIMES. MODERATE OR GOOD. --- sshd_config.5 9 Jul 2002 17:46:25 -0000 1.5 +++ sshd_config.5 24 Jul 2002 16:55:29 -0000 @@ -459,6 +459,21 @@ If this option is set to .Dq no root is not allowed to login. +.It Cm PermitUserEnvironment +Specifies whether +.Pa ~/.ssh/environment +is read by +.Nm sshd +and whether +.Cm environment+options in +.Pa ~/.ssh/authorized_keys +files are permitted. +The default is +.Dq yes . +This option is useful for locked-down installations where +.Ev LD_PRELOAD +and suchlike can cause security problems. .It Cm PidFile Specifies the file that contains the process ID of the .Nm sshd --- sshd_config 20 Jun 2002 23:37:12 -0000 1.56 +++ sshd_config 24 Jul 2002 16:55:27 -0000 @@ -75,6 +75,7 @@ #KeepAlive yes #UseLogin no #UsePrivilegeSeparation yes +#PermitUserEnvironment yes #Compression yes #MaxStartups 10 --- servconf.h 20 Jun 2002 23:05:55 -0000 1.58 +++ servconf.h 24 Jul 2002 16:55:26 -0000 @@ -97,6 +97,7 @@ int challenge_response_authentication; int permit_empty_passwd; /* If false, do not permit empty * passwords. */ + int permit_user_env; /* If true, read ~/.ssh/environment */ int use_login; /* If true, login(1) is used */ int compression; /* If true, compression is allowed */ int allow_tcp_forwarding; --- servconf.c 23 Jun 2002 09:46:51 -0000 1.112 +++ servconf.c 24 Jul 2002 16:55:26 -0000 @@ -87,6 +87,7 @@ options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; options->permit_empty_passwd = -1; + options->permit_user_env = -1; options->use_login = -1; options->compression = -1; options->allow_tcp_forwarding = -1; @@ -204,6 +205,8 @@ options->challenge_response_authentication = 1; if (options->permit_empty_passwd == -1) options->permit_empty_passwd = 0; + if (options->permit_user_env == -1) + options->permit_user_env = 1; if (options->use_login == -1) options->use_login = 0; if (options->compression == -1) @@ -259,7 +262,7 @@ sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, sStrictModes, sEmptyPasswd, sKeepAlives, - sUseLogin, sAllowTcpForwarding, sCompression, + sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, @@ -319,6 +322,7 @@ { "xauthlocation", sXAuthLocation }, { "strictmodes", sStrictModes }, { "permitemptypasswords", sEmptyPasswd }, + { "permituserenvironment", sPermitUserEnvironment }, { "uselogin", sUseLogin }, { "compression", sCompression }, { "keepalive", sKeepAlives }, @@ -670,6 +674,10 @@ case sEmptyPasswd: intptr = &options->permit_empty_passwd; + goto parse_flag; + + case sPermitUserEnvironment: + intptr = &options->permit_user_env; goto parse_flag; case sUseLogin: --- auth-options.c 21 Jul 2002 18:32:20 -0000 1.25 +++ auth-options.c 24 Jul 2002 16:55:25 -0000 @@ -133,7 +133,8 @@ goto next_option; } cp = "environment=\""; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { + if (options.permit_user_env && + strncasecmp(opts, cp, strlen(cp)) == 0) { char *s; struct envstring *new_envstring; --- session.c 22 Jul 2002 11:03:06 -0000 1.145 +++ session.c 24 Jul 2002 16:55:27 -0000 @@ -899,7 +899,7 @@ auth_sock_name); /* read $HOME/.ssh/environment. */ - if (!options.use_login) { + if (options.permit_user_env && !options.use_login) { snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir); read_environment_file(&env, &envsize, buf);
Why are you using a restricted shell that is not staticly compiled? That is asking for trouble. I don't see why we need to apply this to work around an issue with an incorrect configuration you have decided to use. - Ben On Thu, 25 Jul 2002, Tony Finch wrote:> We have a system on which users are given a very restricted environment > (their shell is a menu) where they should not be able to run arbitrary > commands. However, because their shell is not statically linked, ld.so > provides a nice clutch of holes for them to exploit. The patch below > adds a new configuration option to sshd which quashes their attempts > to set LD_PRELOAD etc. using ~/.ssh/environment or the environment> option in their ~/.ssh/authorized_keys files. It was generated against > the OpenBSD version of OpenSSH but applies to the portable version too. > > Tony. > -- > f.a.n.finch <dot at dotat.at> http://dotat.at/ > SOUTH UTSIRE: NORTHWEST 3 OR 4, OCCASIONALLY 5, BACKING SOUTH FOR A TIME. RAIN > AT TIMES. MODERATE OR GOOD. > > > --- sshd_config.5 9 Jul 2002 17:46:25 -0000 1.5 > +++ sshd_config.5 24 Jul 2002 16:55:29 -0000 > @@ -459,6 +459,21 @@ > If this option is set to > .Dq no > root is not allowed to login. > +.It Cm PermitUserEnvironment > +Specifies whether > +.Pa ~/.ssh/environment > +is read by > +.Nm sshd > +and whether > +.Cm environment> +options in > +.Pa ~/.ssh/authorized_keys > +files are permitted. > +The default is > +.Dq yes . > +This option is useful for locked-down installations where > +.Ev LD_PRELOAD > +and suchlike can cause security problems. > .It Cm PidFile > Specifies the file that contains the process ID of the > .Nm sshd > --- sshd_config 20 Jun 2002 23:37:12 -0000 1.56 > +++ sshd_config 24 Jul 2002 16:55:27 -0000 > @@ -75,6 +75,7 @@ > #KeepAlive yes > #UseLogin no > #UsePrivilegeSeparation yes > +#PermitUserEnvironment yes > #Compression yes > > #MaxStartups 10 > --- servconf.h 20 Jun 2002 23:05:55 -0000 1.58 > +++ servconf.h 24 Jul 2002 16:55:26 -0000 > @@ -97,6 +97,7 @@ > int challenge_response_authentication; > int permit_empty_passwd; /* If false, do not permit empty > * passwords. */ > + int permit_user_env; /* If true, read ~/.ssh/environment */ > int use_login; /* If true, login(1) is used */ > int compression; /* If true, compression is allowed */ > int allow_tcp_forwarding; > --- servconf.c 23 Jun 2002 09:46:51 -0000 1.112 > +++ servconf.c 24 Jul 2002 16:55:26 -0000 > @@ -87,6 +87,7 @@ > options->kbd_interactive_authentication = -1; > options->challenge_response_authentication = -1; > options->permit_empty_passwd = -1; > + options->permit_user_env = -1; > options->use_login = -1; > options->compression = -1; > options->allow_tcp_forwarding = -1; > @@ -204,6 +205,8 @@ > options->challenge_response_authentication = 1; > if (options->permit_empty_passwd == -1) > options->permit_empty_passwd = 0; > + if (options->permit_user_env == -1) > + options->permit_user_env = 1; > if (options->use_login == -1) > options->use_login = 0; > if (options->compression == -1) > @@ -259,7 +262,7 @@ > sPrintMotd, sPrintLastLog, sIgnoreRhosts, > sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, > sStrictModes, sEmptyPasswd, sKeepAlives, > - sUseLogin, sAllowTcpForwarding, sCompression, > + sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, > sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, > sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, > sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, > @@ -319,6 +322,7 @@ > { "xauthlocation", sXAuthLocation }, > { "strictmodes", sStrictModes }, > { "permitemptypasswords", sEmptyPasswd }, > + { "permituserenvironment", sPermitUserEnvironment }, > { "uselogin", sUseLogin }, > { "compression", sCompression }, > { "keepalive", sKeepAlives }, > @@ -670,6 +674,10 @@ > > case sEmptyPasswd: > intptr = &options->permit_empty_passwd; > + goto parse_flag; > + > + case sPermitUserEnvironment: > + intptr = &options->permit_user_env; > goto parse_flag; > > case sUseLogin: > --- auth-options.c 21 Jul 2002 18:32:20 -0000 1.25 > +++ auth-options.c 24 Jul 2002 16:55:25 -0000 > @@ -133,7 +133,8 @@ > goto next_option; > } > cp = "environment=\""; > - if (strncasecmp(opts, cp, strlen(cp)) == 0) { > + if (options.permit_user_env && > + strncasecmp(opts, cp, strlen(cp)) == 0) { > char *s; > struct envstring *new_envstring; > > --- session.c 22 Jul 2002 11:03:06 -0000 1.145 > +++ session.c 24 Jul 2002 16:55:27 -0000 > @@ -899,7 +899,7 @@ > auth_sock_name); > > /* read $HOME/.ssh/environment. */ > - if (!options.use_login) { > + if (options.permit_user_env && !options.use_login) { > snprintf(buf, sizeof buf, "%.200s/.ssh/environment", > pw->pw_dir); > read_environment_file(&env, &envsize, buf); > _______________________________________________ > openssh-unix-dev at mindrot.org mailing list > http://www.mindrot.org/mailman/listinfo/openssh-unix-dev >
On Thu, Jul 25, 2002 at 02:16:10PM -0500, Ben Lindstrom wrote:> > Why are you using a restricted shell that is not staticly compiled?The ABI for Solaris is dynamic only. Only binaries in /sbin are statically linked, and only Sun compile them, and they are not used as login shells. $ uname -a SunOS prism.csi.cam.ac.uk 5.6 Generic_105181-31 sun4u sparc SUNW,Ultra-1 $ ldd /bin/sh libc.so.1 => /usr/lib/libc.so.1 libdl.so.1 => /usr/lib/libdl.so.1 /usr/platform/SUNW,Ultra-1/lib/libc_psr.so.1 $ ldd /usr/bin/ksh libsocket.so.1 => /usr/lib/libsocket.so.1 libnsl.so.1 => /usr/lib/libnsl.so.1 libc.so.1 => /usr/lib/libc.so.1 libdl.so.1 => /usr/lib/libdl.so.1 libmp.so.2 => /usr/lib/libmp.so.2 /usr/platform/SUNW,Ultra-1/lib/libc_psr.so.1 In my case the shell is a menu system rather than a shell. Tony. -- f.a.n.finch <dot at dotat.at> http://dotat.at/ NORTH FITZROY SOLE: WEST OR SOUTHWEST 3 OR 4. DRIZZLE. MODERATE OR POOR.