Bug#628843: (forw) [Pkg-shadow-devel] Bug#628843: login: tty hijacking possible in "su" via TIOCSTI ioctl

June 02nd, 2011 - 01:40 am ET by Christian PERRIER | Report spam

tags 628843 help security
thanks

Security team, I need advice and help here. My co-maintainer for
shadow, Nicolas, is more or less MIA, so I'm left nearly alone to
maintain shadow. As Nicolas was also upstream, you understand how
desperate is my situation..:-)

(maybe this bug will ring a bell for Nicolas, still)

My expertise is, as you may expect, way outreached. So, in short, what
I need is someone with enough expertise to look at this bug report and
help deciding if adopting Redhat's patch is correct (assuming it
applies: I'm not sure that RH is using the same "su" than we do).

Mail CC'ed to submitter, too, so that Daniel also knows that the only
person who answersneeds help..:-)


Date: Wed, 1 Jun 2011 15:24:47 -0400
From: Daniel Ruoso <daniel@ruoso.com>
To: Debian Bug Tracking System <submit@bugs.debian.org>
Subject: [Pkg-shadow-devel] Bug#628843: login: tty hijacking possible in "su" via TIOCSTI ioctl
Reply-To: Daniel Ruoso <daniel@ruoso.com>, 628843@bugs.debian.org
X-CRM114-Status: Good ( pR: 39.0933 )

Package: login
Version: 1:4.1.4.2+svn3283-2+squeeze1
Severity: critical

After investigating why RedHat have a different behavior regarding "su -c" I
found out that there was a patch in RedHat to prevent tty hijacking when using
"su -c".

What makes the hijacking possible is that "su -c" still gives the command a
controlling tty, which means it has ioctl access to /dev/tty. This means it
can send things to the tty input buffer, which will be read just after su
ends.

The original report (with patch) on RedHat (from 2005?!?!?!) is:
https://bugzilla.redhat.com/show_bu...;id=173008

A very simple exploit follows (Perl code)

____BEGIN_CODE____
#!/usr/bin/perl
require "sys/ioctl.ph";
open my $tty_fh, '<', '/dev/tty' or die $!;
foreach my $c (split //, 'cat /etc/shadow'.$/) {
ioctl($tty_fh, &TIOCSTI, $c);
}
____END_CODE____

The scenario is:

Root runs a command as a less priviledged user with "su -c", if the user was
compromised, the script will be able to run commands as root by injecting
keystrokes on the terminal.

Debian Release: 6.0.1
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.32-5-686 (SMP w/1 CPU core)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages login depends on:
ii libc6 2.11.2-10 Embedded GNU C Library: Shared lib
ii libpam-modules 1.1.1-6.1 Pluggable Authentication Modules f
ii libpam-runtime 1.1.1-6.1 Runtime support for the PAM librar
ii libpam0g 1.1.1-6.1 Pluggable Authentication Modules l

login recommends no packages.

login suggests no packages.




_______________________________________________
Pkg-shadow-devel mailing list
Pkg-shadow-devel@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-...adow-devel











To UNSUBSCRIBE, email to debian-bugs-rc-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
email Follow the discussionReplies 6 repliesReplies Make a reply

Similar topics

Replies

#1 owner
June 02nd, 2011 - 01:40 am ET | Report spam
Processing commands for :

tags 628843 help security


Bug #628843 [login] login: tty hijacking possible in "su" via TIOCSTI ioctl
Added tag(s) security and help.
thanks


Stopping processing here.

Please contact me if you need assistance.
628843: http://bugs.debian.org/cgi-bin/bugr...i?bugb8843
Debian Bug Tracking System
Contact with problems


To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Replies Reply to this message
#2 Daniel Ruoso
June 02nd, 2011 - 08:20 am ET | Report spam

On Thu, Jun 02, 2011 at 07:34:59AM +0200, Christian PERRIER wrote:
My expertise is, as you may expect, way outreached. So, in short, what
I need is someone with enough expertise to look at this bug report and
help deciding if adopting Redhat's patch is correct (assuming it
applies: I'm not sure that RH is using the same "su" than we do).



Ok, to give more context to the fix applied by RedHat.

What they did was use setsid() to start a new session and remove the
controlling terminal from the running command. This removes from the
child process the ability to open "/dev/tty", which is how the
hijacking works.

But doing only that is complicated because the translation of Ctrl+C
to SIGINT depends on controlling the tty, so you wouldn't be able to
stop the process easily. What they did was simply to add SIGINT to the
signal mask that causes the su to exit the waitpit loop.

The thing I don't like about RedHat's patch is that it turns a SIGINT
on su into a SIGTERM to the process, it would be better to send the
same signal received.

I don't have the time to do it right now, but I can give a shot on
writing a patch that preserves the signal interaction sane, which is
not the case in RedHat.

daniel






To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Replies Reply to this message
#3 Nicolas François
June 04th, 2011 - 02:10 pm ET | Report spam

Hello,

Here is a patch proposal. It forwards the right signal to the child also
supports SIGTSTP.

I would appreciate if this could be reviewed by somebody more confident
with signal processing than me.

I expect sudo to have the same issue.

Also sg probably has the same issue (i.e. it cannot be used to drop group
privileges). I will look at it.

Other utils to switch user or group might also be affected.
(Anybody got a list and could try?)


Best Regards,
Nekral


Index: src/su.c
=
src/su.c (révision 3317)
+++ src/su.c (copie de travail)
@@ -88,7 +88,7 @@

#ifdef USE_PAM
static pam_handle_t *pamh = NULL;
-static bool caught = false;
+static int caught = 0;
/* PID of the child, in case it needs to be killed */
static pid_t pid_child = 0;
#endif
@@ -235,9 +235,9 @@

#ifdef USE_PAM
/* Signal handler for parent process later */
-static void catch_signals (unused int sig)
+static void catch_signals (int sig)
{
- caught = true;
+ caught = sig;
}

/* This I ripped out of su.c from sh-utils after the Mandrake pam patch
@@ -264,6 +264,11 @@
if (doshell) {
(void) shell (shellstr, (char *) args[0], envp);
} else {
+ /* There is no need for a controlling terminal.
+ * This avoids the callee to inject commands on
+ * the caller's tty. */
+ (void) setsid ();
+
execve_shell (shellstr, (char **) args, envp);
}

@@ -283,9 +288,9 @@
(void) fprintf (stderr,
_("%s: signal malfunction"),
Prog);
- caught = true;
+ caught = SIGTERM;
}
- if (!caught) {
+ if (0 == caught) {
struct sigaction action;

action.sa_handler = catch_signals;
@@ -296,36 +301,66 @@
if ( (sigaddset (&ourset, SIGTERM) != 0)
|| (sigaddset (&ourset, SIGALRM) != 0)
|| (sigaction (SIGTERM, &action, NULL) != 0)
+ || ( !doshell /* handle SIGINT (Ctrl-C), SIGQUIT
+ * (Ctrl-\), and SIGTSTP (Ctrl-Z)
+ * since the child does not control
+ * the tty anymore.
+ */
+ && ( (sigaddset (&ourset, SIGINT) != 0)
+ || (sigaddset (&ourset, SIGQUIT) != 0)
+ || (sigaddset (&ourset, SIGTSTP) != 0)
+ || (sigaction (SIGINT, &action, NULL) != 0)
+ || (sigaction (SIGQUIT, &action, NULL) != 0))
+ || (sigaction (SIGTSTP, &action, NULL) != 0))
|| (sigprocmask (SIG_UNBLOCK, &ourset, NULL) != 0)
) {
fprintf (stderr,
_("%s: signal masking malfunction"),
Prog);
- caught = true;
+ caught = SIGTERM;
}
}

- if (!caught) {
+ if (0 == caught) {
+ bool stop = true;
+
do {
pid_t pid;
+ stop = true;

pid = waitpid (-1, &status, WUNTRACED);

- if (((pid_t)-1 != pid) && (0 != WIFSTOPPED (status))) {
+ /* When interrupted by signal, the signal will be
+ * forwarded to the child, and termination will be
+ * forced later.
+ */
+ if ( ((pid_t)-1 == pid)
+ && (EINTR == errno)
+ && (SIGTSTP == caught)) {
+ /* Except for SIGTSTP, which request to
+ * stop the child.
+ * We will SIGSTOP ourself on the next
+ * waitpid round.
+ */
+ kill (child, SIGSTOP);
+ stop = false;
+ } else if ( ((pid_t)-1 != pid)
+ && (0 != WIFSTOPPED (status))) {
/* The child (shell) was suspended.
* Suspend su. */
kill (getpid (), SIGSTOP);
/* wake child when resumed */
kill (pid, SIGCONT);
+ stop = false;
}
- } while (0 != WIFSTOPPED (status));
+ } while (!stop);
}

- if (caught) {
+ if (0 != caught) {
(void) fputs ("", stderr);
(void) fputs (_("Session terminated, terminating shell..."),
stderr);
- (void) kill (child, SIGTERM);
+ (void) kill (child, caught);
}

ret = pam_close_session (pamh, 0);
@@ -339,7 +374,7 @@

ret = pam_end (pamh, PAM_SUCCESS);

- if (caught) {
+ if (0 != caught) {
(void) signal (SIGALRM, kill_child);
(void) alarm (2);





To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Replies Reply to this message
#4 Thijs Kinkhorst
June 09th, 2011 - 04:00 pm ET | Report spam
Op donderdag 02 juni 2011 07:34:59 schreef Christian PERRIER:
Security team, I need advice and help here. My co-maintainer for
shadow, Nicolas, is more or less MIA, so I'm left nearly alone to
maintain shadow. As Nicolas was also upstream, you understand how
desperate is my situation..:-)

(maybe this bug will ring a bell for Nicolas, still)

My expertise is, as you may expect, way outreached. So, in short, what
I need is someone with enough expertise to look at this bug report and
help deciding if adopting Redhat's patch is correct (assuming it
applies: I'm not sure that RH is using the same "su" than we do).

Mail CC'ed to submitter, too, so that Daniel also knows that the only
person who answersneeds help..:-)



Hi Christian,

I'm just mailing to confirm that we did record the issue in our tracker and to
point out that this issue is currently also discueed on oss-security:
http://thread.gmane.org/gmane.comp....neral/5172


Thijs



To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Replies Reply to this message
#5 Christian PERRIER
June 10th, 2011 - 03:10 pm ET | Report spam

Quoting Thijs Kinkhorst ():

Hi Christian,

I'm just mailing to confirm that we did record the issue in our tracker and to
point out that this issue is currently also discueed on oss-security:
http://thread.gmane.org/gmane.comp....neral/5172



Thanks, Thijs, for your answer.

I'm more reliefed now that Nicolas popped up and even proposed a
preliminary patch. I don't have the expertise to give any advice about
his patch but I think that we have there a good start for an
up-to-come fix.

During last week, Nicolas was active "cleaning out" things for shadow
so I think we can have some good hope to have a fixed issue at some
moment in the near future...

But, as Nicolas mentioned, an expert review of his proposal would be
very much welcomed.








To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Replies Reply to this message
Help Create a new topicNext page Replies Make a reply
Search Make your own search