Consider the case of a setUID binary that runs as root and allows the caller to execute certain other scripts and binaries from a given restricted directory. The Portcullis Labs team recently spotted such a case and I was asked to take a look to determine exploitablity. What follows is a short analysis of what I found.
The binary concerned took several steps to protect itself including:
- Validating that the sub-command wasn’t overly long
- Validating that the sub-command didn’t contain sensitive characters
- Validating that the sub-command existed in the restricted location
- Checking that the sub-command had the setUID bit set
- Clearing down sensitive environment variables such as PATH and LD_PRELOAD prior to transferring control to the sub-command
So what could go wrong?
Well, it turns out that the way it cleared down sensitive variables left a little to be desired.
If you break out IDA (or even plain old strings), you’ll see that the binary sets PATH etc to “”. This is fine in most cases, but if the script uses an interpreter that doesn’t reset PATH (sadly sh will nomally reset it via the rc files etc) then the interpreter will attempt to run commands from “” i.e. the current working directory.
For example:
$ ls -la /restricted/allowed -rwsr-xr-x 1 root root 56 Feb 12 20:27 /restricted/allowed $ cat /restricted/allowed #!/usr/bin/tclsh8.6 exec id $ cat ./id #!/bin/sh touch foo $ ls -l foo -rw-r--r-- 1 root user 0 Feb 12 20:29 foo