2

I'm writing a libre program named "silently" for enhancing error handling in Bash, emulating the behavior of a jidoka.

My question is if that eval would be vulnerable to code injection if the invoking program surrounds its input with doble quotes, like this:

silently "function" "command \"${@}\""

Having silently this code:

#! /bin/bash


mainFunction () {
    if [ "${function}" != "" ]; then
        function="${function}: "
    fi

    error=$(eval "${command}" 2>&1)

    if [ ${?} -ne 0 ]; then
        echo "${function}${error}" >&2
        exit "${exit}"
    fi
}


setArguments () {
    if [ "${1}" == "-try" ]; then
        function="${2}"
        command="${3}"
        exit="0"
    else
        function="${1}"
        command="${2}"
        exit="1"
    fi
}


setArguments "${@}"
mainFunction "${@}"
4
  • 1
    Just checking: is your threat scenario that somebody who can run an arbitrary command in your shell might... inject a command into your shell? Or are you imagining an attacker who can control at least part of one parameter but not the rest of the command line?
    – CBHacking
    Oct 12, 2019 at 4:00
  • The attacker initially could only control the content of ${@}. Oct 13, 2019 at 11:09
  • ${@} could contain echo `cat /etc/paswd`;return -1, for sample! Oct 16, 2019 at 9:18
  • It doesn't result in code execution:./test.sh "echo cat /etc/paswd;return -1" cat: /etc/paswd: No such file or directory /usr/bin/silently: line 9: echo ;return -1: command not found Oct 17, 2019 at 0:05

2 Answers 2

2

There are two quick observation:

  • Using eval is very dangerous and your variable ${command} is not efficiently sanitized. (They could contain backticks, period, control chars, etc)

  • Using bash for sensible operation is not recommended as they suffer from a lot of vulnerabilities. I recommend using poor shell (like dash), for critical scripts. (Or more evolved languages like Python or Perl).

  • Sample of unexpected behaviour:

    /path/to/silently Blah "'echo `date`;return 1'"
    Blah: Wed Oct 16 08:26:16 CEST 2019
    

    Where command between backticks are executed, semicolons do command separation (as usual) and return 1 force mainFunction to consider the result as an error then print them.

    By using the code you've published @gitlab.com, result of this look like:

    /path/to/silently Blah "'echo `date`;return 1'"
    silently: surplus arguments on: Blah 'echo Thu Oct 17 13:54:36 CEST 2019;return 1'
    Note that command must be quoted
    

    date command is executed and result shown as error text.

    Then you could try:

    /path/to/silently Blah "'echo `cat /etc/passwd`;return 1'"
    

Using to do sensible operation is something possible, but do require strong experience. I personally recomand to not do that!

6
  • Thanks. command is not the variable, but a hard-coded command. The variable is ${@}. When I put it between double quotes the terminal didn't interpret control chars as such, so I was wondering if that's the case under any circumstance. Oct 13, 2019 at 11:06
  • Sample issue: silently Blah 'echo `date`;return 1' Oct 16, 2019 at 6:32
  • Results in: silently: surplus arguments on: Blah echo 'date';return 1 Oct 16, 2019 at 23:43
  • By the way I have turned this code into a full application: gitlab.com/es20490446e/silently Oct 16, 2019 at 23:46
  • Ok, I've downloaded your code then tryed: ./silently Blah "'echo `cat /etc/passwd`;return 1'". Please note double-quote enclosed quotes, enclosing backticks... I think showing password file is an unexpected behaviour! Note: eval is evil! Oct 17, 2019 at 11:48
1

First of all, there is no reason to worry about code injection on a local shell script.

If you are running this remotely it could be an issue. I did some experimenting with the example below and didn't find any direct ways to inject any extra commands, except for the one word. Keep in mind, that you should also whitelist the allowed commands in a production environment.

Example: silently "command \"whoami\""

#! /bin/bash
command="${@}"
result=$(eval "${command}" 2>&1)
echo "${result}"
6
  • Thank you. For example silently echo this; ls will execute ls, where silently "echo this; ls" will not. So if we have silently "command ${arguments}", arguments inside double quotes, it seems enough for the terminal to understand that arguments shall not be executed in any case. I was wondering if there could be a case where that's not true. Oct 13, 2019 at 11:02
  • @AlbertoSalviaNovella it will, because you are using eval function Oct 13, 2019 at 12:24
  • I would need a sample where that happens, because I have been unable to find one. Oct 13, 2019 at 14:20
  • Do this silently "function" "whoami;whoami" Oct 13, 2019 at 19:56
  • That sample can only be hard-coded, not injected. Oct 13, 2019 at 20:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .