Exploiting Linux Capabilities – Part 4
Learn about Linux file capabilities like cap_fowner, cap_setfcap, cap_dac_override and cap_linux_immutable and how to exploit these in order to read privileged files or get the root user shell
In the previous posts, I have discussed the working Linux capabilities and how to exploit capabilities that sysadmin often requires. If you want to learn Linux privilege escalation from starting, here is the list of all the topics I have published so far – https://tbhaxor.com/linux-privilege-escalation/.
In this post, I will again discuss the labs to cover more about file related capabilities. There are two posts on the same topic – Part 1 and Part 2 on exploiting the Linux capabilities.
- The Basics: CAP_FOWNER
- The Basics: CAP_SETFCAP
- The Basics: CAP_DAC_OVERRIDE III
- The Basics: CAP_LINUX_IMMUTABLE
So let's begin ...
LAB: The Basics: CAP_FOWNER
In this lab, I found that the python interpreter has the capability "cap_fowner" in both effective and the permitted set
When a program is running with cap_fowner capabilities, it bypasses all the current uid and file owner uid match required for all the operations excluding what is required for cap_dac_read_search and cap_dac_override capabilities (discussed in part 2 of exploiting Linux capabilities). These are calling syscalls like chmod and utime
If any program that can call chmod syscall has this capability set, it could lead to direct privilege escalate. All I need to do is set the read-write permissions on the /etc/passwd file
Since now the file is world-writable, I can change the password of the root user in the /etc/passwd file using the vim spawned by the current user (i.e student). Later perform switch user with -l flag to login and land in the home directory of the root user
LAB: The Basics: CAP_SETFCAP
In this lab, I found that the python interpreter has the capability "cap_setfcap" in both effective and the permitted set
When a program is running with cap_setfcap capability in the effective set, it can set any capability on any file. This could lead to a direct system takeover, as the program can go ahead and set cap_setuid on the program that can call setuid syscall to spawn a privileged shell
I have retrieved the following exploit code from hacktricks. It will set
cap_setuid+ep capability to any file passed as the first argument to the script
In this case, I will set this capability on the python interpreter. The cap_set_file function in libc only accepts the path of the actual file. So if you will give the path of symlink it will throw an error
Since python binary now has cap_setuid capability set, I can perform the os.setuid function and spawn the root user shell and read-protected files
LAB: The Basics: CAP_DAC_OVERRIDE III
In my last posts, I have discussed cap_dac_override capability in detail. It allows you to perform read/write operations on any file and execute permission of directories. In this lab, I found an interesting program that has this capability.
This program is a linker – x86_64-linux-gnu-ld.bfd
I learnt this technique from one of the CTF writeups from attackdefense's lab – https://happybear.medium.com/sincon-wonderland-ctf-privilege-escalation-points-200-6bf3aaaa330
You can read files by fooling the linker to interpret them as binary output from the compiler.
The explanation of the above command is as follows
-rgenerate the reallocatable output, otherwise, the linker will not able to find the _start section. This flag is optional
-b binarytells the linker to treat the input file as binary output from the assembler. This is required because if it's omitted, the linker will treat the input file as a script
/root/flagis the input file
-o flag.otells the linker where to output the file
In this lab, I found that the python interpreter has cap_linux_immutable capability in both effective and privileged sets
Generally, all the files that a current user owns or are world-writable can be deleted or modified by the user. But in some situations to prevent accidental deletion of the file, it is recommended to make that file immutable. This means even if you own a file, you can not delete it or update its contents, but you can read the file without any issue. To set or unset this flag, you need to run the
chattr command via root user.
However, if a program is running with cap_linux_immutable capability in the effective set, it can modify the contents of the immutable file
I see there is a file named backup.sh and same file is executed via root user every minute from a cronjob
Directly I can't update the file content as the file is immutable and unsetting the immutable attribute seems impossible
Since python has the file capability to change the contents of an immutable file, I got the exploit code from hacktricks gitbook which does exactly the same.
This will set suid bit on /bin/bash file and I get privileged shell using
/bin/bash -p flag
After running the exploit code on the /home/student/backup.sh I was able to append malicious code in the backup.sh file
On the next hit, I was able to spawn the shell as root user. If you want to learn about how suid works and how it can be exploited, here are my two posts – Demystifying SUID and SGID bits and Exploiting SUID Binaries to Get Root User Shell