Path: csiph.com!au2pb.net!feeder.erje.net!2.us.feeder.erje.net!news.glorb.com!usenet.stanford.edu!not-for-mail From: up201407890@alunos.dcc.fc.up.pt Newsgroups: gnu.bash.bug Subject: SHELLOPTS=xtrace security hardening Date: Thu, 10 Dec 2015 20:16:49 +0100 Lines: 151 Approved: bug-bash@gnu.org Message-ID: NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; DelSp="Yes"; format="flowed" Content-Transfer-Encoding: quoted-printable X-Trace: usenet.stanford.edu 1449779130 28888 208.118.235.17 (10 Dec 2015 20:25:30 GMT) X-Complaints-To: action@cs.stanford.edu Cc: bug-bash@gnu.org To: chet.ramey@case.edu Envelope-to: bug-bash@gnu.org Content-Disposition: inline User-Agent: Internet Messaging Program (IMP) H3 (4.2) X-Virus-Scanned: amavisd-new at alunos.dcc.fc.up.pt X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 193.136.39.109 X-Mailman-Approved-At: Thu, 10 Dec 2015 15:25:29 -0500 X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com gnu.bash.bug:11978 Hello, This is a suggestion for a bash security hardening patch which =20 prevents xtrace from being initialized to the SHELLOPTS environment =20 variable when a new shell starts. xtrace can be used to exploit bogus system()/popen() calls on setuid =20 binaries via a specially crafted PS4 environment variable leading to =20 privilege escalation, like so: # gcc -xc - -otest <<< 'int main() { setuid(0); system("/bin/date"); }' # chmod 4755 ./test # ls -l ./test -rwsr-xr-x. 1 root root 8549 Dec 10 18:06 ./test # exit $ env -i SHELLOPTS=3Dxtrace PS4=3D'$(id)' ./test uid=3D0(root) Thu Dec 10 18:06:36 WET 2015 This means, that setuid programs which call system(3)/popen(3) (a =20 horrendously bad practice in any case) are vulnerable, since it's safe =20 to assume that most of these do not ignore such environment variables. CVE-2005-2959 reported by Tavis Ormandy would be an example against sudo from bash-4.2.53/shell.c: 1722 /* Initialize the shell options. Don't import the shell options 1723 from the environment variables $SHELLOPTS or $BASHOPTS if we a= re 1724 running in privileged or restricted mode or if the shell =20 is running 1725 setuid. */ 1726 #if defined (RESTRICTED_SHELL) 1727 initialize_shell_options =20 (privileged_mode||restricted||running_setuid); 1728 initialize_bashopts (privileged_mode||restricted||running_setuid)= ; 1729 #else 1730 initialize_shell_options (privileged_mode||running_setuid); 1731 initialize_bashopts (privileged_mode||running_setuid); 1732 #endif initialize_shell_options() is defined in bash-4.2.53/builtins/set.def 555=09void 556=09initialize_shell_options (no_shellopts) 557=09 int no_shellopts; 558=09{ 559=09 char *temp; 560=09 SHELL_VAR *var; 561 562=09 if (no_shellopts =3D=3D 0) 563=09 { 564=09 var =3D find_variable ("SHELLOPTS"); 565=09 /* set up any shell options we may have inherited. */ 566=09 if (var && imported_p (var)) 567=09=09{ 568=09=09 temp =3D (array_p (var) || assoc_p (var)) ? (char *)NULL : = =20 savestring (value_cell (var)); 569=09=09 if (temp) 570=09=09 { 571=09=09 parse_shellopts (temp); 572=09=09 free (temp); 573=09=09 } 574=09=09} 575=09 } 576 577=09 /* Set up the $SHELLOPTS variable. */ 578=09 set_shellopts (); 579=09} parse_shellopts() is also defined in bash-4.2.53/builtins/set.def 535 void 536 parse_shellopts (value) 537 char *value; 538 { 539 char *vname; 540 int vptr; 541 542 vptr =3D 0; 543 while (vname =3D extract_colon_unit (value, &vptr)) 544 { 545 set_minus_o_option (FLAG_ON, vname); 546 free (vname); 547 } 548 } Suggested patch: $ diff -Naur bash-4.2.53.patch/bash-4.2.53 bash-4.2.53 diff -Naur bash-4.2.53.patch/bash-4.2.53/builtins/set.def =20 bash-4.2.53/builtins/set.def --- bash-4.2.53.patch/bash-4.2.53/builtins/set.def 2011-01-10 =20 14:22:25.000000000 +0000 +++ bash-4.2.53/builtins/set.def 2015-12-10 18:29:54.494932199 +0000 @@ -542,6 +542,10 @@ vptr =3D 0; while (vname =3D extract_colon_unit (value, &vptr)) { + /* xtrace can be used to exploit bogus system()/popen() calls =20 on setuid binaries + via a specially crafted PS4 environment variable leading to =20 privilege escalation. */ + if(!strcmp(vname, "xtrace")) + break; set_minus_o_option (FLAG_ON, vname); free (vname); } After compilation: # rm /bin/bash # cp bash-4.2.53/bash /bin/bash # ls -l /bin/sh lrwxrwxrwx. 1 root root 9 Oct 4 18:18 /bin/sh -> /bin/bash # exit $ env -i SHELLOPTS=3Dxtrace PS4=3D'$(id)' ./test Thu Dec 10 18:30:41 WET 2015 Thanks, Federico Bento. ---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.