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 "${@}"
  • 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 '19 at 4:00
  • The attacker initially could only control the content of ${@}. – Alberto Salvia Novella Oct 13 '19 at 11:09
  • ${@} could contain echo `cat /etc/paswd`;return -1, for sample! – F. Hauri Oct 16 '19 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 – Alberto Salvia Novella Oct 17 '19 at 0:05
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!

  • 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. – Alberto Salvia Novella Oct 13 '19 at 11:06
  • Sample issue: silently Blah 'echo `date`;return 1' – F. Hauri Oct 16 '19 at 6:32
  • Results in: silently: surplus arguments on: Blah echo 'date';return 1 – Alberto Salvia Novella Oct 16 '19 at 23:43
  • By the way I have turned this code into a full application: gitlab.com/es20490446e/silently – Alberto Salvia Novella Oct 16 '19 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! – F. Hauri Oct 17 '19 at 11:48
0

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}"
  • 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. – Alberto Salvia Novella Oct 13 '19 at 11:02
  • @AlbertoSalviaNovella it will, because you are using eval function – Raimonds Liepiņš Oct 13 '19 at 12:24
  • I would need a sample where that happens, because I have been unable to find one. – Alberto Salvia Novella Oct 13 '19 at 14:20
  • Do this silently "function" "whoami;whoami" – Raimonds Liepiņš Oct 13 '19 at 19:56
  • That sample can only be hard-coded, not injected. – Alberto Salvia Novella Oct 13 '19 at 20:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.