Subsystem sftp invoked even though forced command created

Damien Miller djm at mindrot.org
Wed Jul 5 10:50:56 AEST 2023


On Mon, 3 Jul 2023, Jochen Bern wrote:

> On 30.06.23 17:56, MCMANUS, MICHAEL P wrote:
> > The actual command is similar to the following (parameters inserted to
> > protect the source):
> >          (print ${FQDN} ; print ${Environment} ; cat ${OutFileXML}) | \
> >          ssh -Ti ${EmbeddedPrivateKey} \
> >                  -o HostKeyAlias="${Alias}" \
> >                  -o GlobalKnownHostsFile="${EmbeddedKnownHosts}"  \
> >                  -o UserKnownHostsFile="${ClientSpecificKnownHosts}" \
> >                  -o StrictHostKeyChecking="yes" \
> >                  -o CheckHostIP="no" \
> >                  -o NumberOfPasswordPrompts=0 \
> >                  ${User}@${Host} 2>/dev/null
> 
> Then whatever executes this command line does *not* understand (and eat) the
> "2>/dev/null" like shells of the Bourne family should, hence it winding up in
> the server-side $SSH_ORIGINAL_COMMAND ...
> 
> > debug1: server_input_channel_req: channel 0 request subsystem reply 1
> > debug1: session_by_channel: session 0 channel 0
> > debug1: session_input_channel_req: session 0 req subsystem
> > debug2: subsystem request for sftp by user m61586
> > debug1: subsystem: exec() /usr/libexec/openssh/sftp-server
> > Starting session: forced-command (key-option)
> > '/opt/app/workload/secgov/opt/sact-central/bin/receive.ksh' for m61586 from
> > 135.99.45.25 port 49734 id 0
> 
> Well, I'll be ... Looks like the server side recognizes the forced-command
> setup, but honors the SFTP subsystem request by exec()ing that nonetheless ...

no, that's the log message being misleading. At the point of the
"Starting session: forced-command" in session.c:do_exec() the command
variable contains the requested forced command and that is what is
actually executed.

https://github.com/openssh/openssh-portable/blob/V_7_4_P1/session.c#L623-L663

The "subsystem: exec()" comes earlier from
session.c:session_subsystem_req(), which is recording (badly) which
subsystem was requested, but this is before the forced command is applied
in do_exec().

https://github.com/openssh/openssh-portable/blob/V_7_4_P1/session.c#L1938-L1944

Further evidence that this is the case is the audit calls that log the
command being executed:

debug3: mm_audit_run_command entering command
/opt/app/workload/secgov/opt/sact-central/bin/receive.ksh
debug3: mm_audit_end_command entering command
/opt/app/workload/secgov/opt/sact-central/bin/receive.ksh

So the command appears to have been correctly overridden and nothing in
the debug logs explains the behaviour you're reporting.

Some possibilities:

1. the receive.ksh script is faulty in some way that causes it to invoke
   sftp-server
2. some changes made by Redhat in the binaries they provided, not present
   in the OpenSSH source we release have broken forced commands.

#2 could be excluded by reproducing the problem using a sshd built from
source, without redhat's patches.

-d


More information about the openssh-unix-dev mailing list