I am working on a SUID root binary "app" that runs a system("ls -la /dir") command. I managed to exploit it by writing a malicious replacement ls that starts a shell, and changed my user's $PATH such that the malicious ls executes instead of the one in /bin.

I noticed that executing it as user returns a root shell while executing it with sudo "./example" uses root's path and simply lists the files in dir. As far as I know, setuid inherits owner's (in this case root) privileges to user and sudo executes as root.

What are such vulnerabilities called? How would an app developer patch it? Is there any way I can force users to use sudo ./app to execute a program?

**the binary is a statically linked executable

  • Did you modify the code of ls? So essentially you are replacing a benign binary used by the app and getting a root shell as a result? – Limit May 12 '18 at 0:21
  • @Limit: Running the setuid executable with a different PATH. – Ry- May 12 '18 at 0:50
  • yes, that's what i did. – Gian May 12 '18 at 2:28
  • sudo itself executes as root, and can execute the given command as any user depending on configuration usually root, but first it sanitizes the environment including PATH to prevent exactly the attack you are attempting. If app does things that require privilege and you make it not suid-root (and not setcap, if applicable) then non-root users who run it without sudo will presumably have it fail harmlessly. – dave_thompson_085 May 12 '18 at 5:28

Tricking a program with more privileges to do something that the owner of the program didn't intend is called privilege escalation.

When a privileged program reads data from the outside, it should verify that this data is harmless. This is called data sanitization. For example, a setuid program that executes an external program should verify that the program it's executing is the intended one. In this case the program depends both on the comamnd string ls -la /dir and on the value of the PATH environment variable¹. The only safe values for PATH are those such that the first entry for ls and any other command that the program might execute is the intended one; in practice that means completely ignoring the external information (the value of PATH in the environment) and setting PATH to a known safe value.

Sudo removes most environment variables, including PATH which it sets to a safe default. This makes it easier to write safe privileged components by using sudo rather than a custom setuid program for privilege elevation. A program run through sudo starts up with a safe value for PATH. You can still get things wrong, of course. For example allowing a user to run sudo ./example allows them to run whatever they want since they can create an executable called example in the directory of their choice.

¹ And LD_xxx variables used by the dynamic linker, but the dynamic linker of the setuid program wipes those when it sees that the program it's linking is setuid.

| improve this answer | |
  • Would setting up a sudo entry, without need to type the password, to allow your users to run the 'example' binary with its owner's ID be a safe solution ? – Gian May 12 '18 at 22:32
  • @Gian Safe for what? It allows the user to run example as root. What do you mean by “with its owner's ID”? – Gilles 'SO- stop being evil' May 12 '18 at 22:48
  • i just got this. By owner i mean the binary owner. Anyway Thanks – Gian May 12 '18 at 23:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.