The moment any child process of these hit a system() or popen() like call, /bin/sh initializes and may hit the bug.
Apache takes SSL_* headers, say, from a client and simply passes those to BASH and this exploit means that BASH will execute a payload dropped in to the header?Am I close? Wouldn't that also be an Apache [httpd] bug in that it's allowing unsanitised user data to hit the shell?
Similarly are you saying that if I set a LANG variable and SSH to a server that the server will use that variable to give to BASH, even if it's not a recognised LANG variable?
Perhaps I'm misunderstanding as such things would be massive holes any way regardless of this BASH issue.
From the example code at the top of the thread it seems that you only need to affect a single variable, that bash reads, in order to pwn the whole server.
Interestingly on Ubuntu the BASH update for this is rated "medium".
Apache sets environment variables, it does not pass user input directly to bash as code or anything like that. The fact that bash can be tricked to execute this code is a problem that needs to be addressed by bash, not any other software.
This can also happen with other service processes - such as OpenSSH, that sets ORIG_SSH_COMMAND variable to the command that the user supplies. That may allow people to break out of restricted accounts -i.e. accounts that are supposed to run just one command (ssh-based services, like SVN or Git, may be an example) and run arbitrary commands under such user.
So they set shell vars without sanitising them first?
In this case, the shell variables are correctly sanitized by Apache or whatever, and then mishandled by bash. For example, imagine this very simple system:
- Web server receives a GET request with the user's name. - Web server sets the environment variable USERS_NAME='<whatever was submitted with quotes escaped>'. - Web server sends back the result of running `bash print_welcome_message.sh`.
It might not be considered great design, but there's nothing inherently insecure in this system, and there are plenty of actual systems that more or less work this way. And it's also perfectly valid for a user to have the name `() { :;}; echo vulnerable`. It ought to work fine to set USERS_NAME to that value and send back `Welcome, () { :;}; echo vulnerable.`
Instead, an unpatched bash will execute the contents of USERS_NAME. The only way for the web server to prevent that would be to change the user's name, which would be wrong behavior -- given a properly working shell, it would print the wrong name in the response. The web server does its sanitization job correctly when it successfully sets USERS_NAME in spite of any single quotes or what-have-you -- this part isn't its problem.
#include<stdio.h>
#include <stdlib.h>
int main()
{
setenv("VAR", "() { :;}; echo vulnerable", 0);
system("ls");
}#./a.out
vulnerable
a.out
#
Does system() invoke /bin/sh? Does it look for 'sh' on the path? What are the rules?
I can certainly imagine that I might have designed a web page that passed user input direct to a BASH script to do a ping or some such, but not if it's public facing.
Only a few environment variables are given any meaning by the system. Other environment variables don't have any predefined meaning and can be any null-terminated string.
That'd be pretty easy to do this if they weren't honest or man in the middle attack the site.
The reason this is newsworthy is because there are some network-facing programs (CGI-based web servers, some SSH configurations) that will set the value of some environment variables to a user-supplied value, which bash will then be executed by bash when that program spawns a new process.