«

»

Jul 25 2012

Revisiting screen lockers and patching a security risk

Recently, I posted about two screen lockers that I’ve used in the past (xtrlock and slock). There has been some great discussion about these lockers, and some potential security problems that come along with using them. One very prominent issue regarding using screen lockers without login managers was raised by a reader, and I want to address it in this separate post.

Just as some background information, many people prefer to use login managers (also known as display managers) in order to be greeted by a graphical login prompt. To use these managers, the X Window System must be started as one of the final steps of the boot process (either by setting the default runlevel to 5 in inittab, setting the display manager to start via the rc system / a daemon, or another method). Some people don’t like the idea of a login manager starting automatically at the end of the boot process, and would prefer to simply be greeted with a terminal login prompt. For those users, it is obviously still necessary to log in as a valid user, but then to start an X session (for their respective graphic environment), one must issue the startx command.

The problem with screen lockers and the startx method of starting Xorg is that it presents a large security flaw. I mentioned in the previous post that one can switch to a different virtual terminal (by using the CTRL+ALT+F# key combination) and log in as a different user. Unless that user can become root and kill the screen locker, though, there’s no problem. However, when Xorg is started using startx, a person can switch to the virtual terminal that issued the startx command, and just hit CTRL+C to kill it. They will then be at the prompt for the user that issued the command, and won’t have to log in. Oops…

A good workaround for this problem is to start Xorg and make sure that the terminal is locked if X is killed. This workaround relies on the package vlock, which is a terminal locking application. For it to work properly, instead of issuing the standard startx command, one needs to issue startx ; vlock. That way, if a person switches to the virtual terminal that started the X session, and hits CTRL+C, it will kill X, but that will automatically start vlock, and subsequently, present the person with nothing more than a login prompt. What’s more, that person will have to enter the password for the user that started the X session.

There might be more elegant methods for fixing this problem, including a script to disable virtual terminal switching when the screen locker is called, and I’ve been looking into such methods. If anyone has further suggestions regarding workarounds, or more permanent solutions, please feel free to comment.

Cheers,
Zach

50 comments

2 pings

Skip to comment form

  1. Watcom

    This is the issue I was talking about in my comment, and I solved it using tmux. Also works with GNU screen. I simply enter tmux, call startx, then CTRL-ALT-F1, CTRL-A D to detach the terminal (which brings me back to the prompt, X is still running), CTRL-D to logout and ALT-F5 to switch back to X. From there I open xterm and type tmux attach, so I still have the console output from inside X. I know, not exactly practical but since I leave my pc on 24/7 I don’t have to do this every day. :)

    I haven’t tried switching back, then CTRL-Z, then calling “bg” to leave X running in the background and CTRL-D to log out, this should work and it’s simpler, but you lose the console output.

  2. Stefan Michelsson

    My solution to this particular problem is starting startx in the background and logging out immediately after that. I have the following code in my .bash_profile:

    if [ `tty` = "/dev/tty1" ]; then
    echo “”
    echo “Starting X in 3 seconds (type Ctrl-C to interrupt)”
    sleep 3
    startx &> ~/.Xstdouterr &
    logout
    fi

    1. Zach

      Hello Stefan,

      Thanks for mentioning your script. I’m going to do some tests against it, and will let you know what I find. I really appreciate you taking the time to let us know of your workaround!

      Cheers,
      Zach

  3. Duncan

    Here, I use a wrapper script that sets up some environment and does a bit of utility work before calling startx… in the background. I then disown all background jobs so when the wrapper script terminates it won’t terminate X as well, and then exit.

    With this arrangement, I can simply source my startx wrapper script in my current login environment, so when it finishes with the backgrounded startx and the disown, it exits the VT login session as well. Thus, switching to that VT won’t help anyone trying to avoid a login, as all they’ll get is the usual getty login prompt. =:^)

    FWIW my X DE of choice is kde, so that’s the session I call in my script, but that’s of course easily changed. Here’s the gist of it. I set a few kde specific vars, etc as well, but including that here would just confuse things, so I won’t: (Hope the line wraps stay correct.)

    — cut here —
    #!/bin/bash
    # make sure I start in ~
    cd

    # sync, in case X crashes the system instead of starting
    sync

    # set the desired DE/xsession
    export XSESSION=KDE-4

    # backgrounde startx so the script continues to run
    startx &

    # disown background jobs so they won’t be killed
    # when the script terminates
    disown -a

    # exit successfully
    exit 0

    — cut here —

    Now, with that script placed in /usr/local/bin/k (which of course allows a similar /usr/bin/g script that sets a gnome xsession, etc) , I can simply do this:

    . k

    That executes the script in the current login session, so will exit after starting X, leaving that VT right back at the getting login prompt. =:^)

    It’s worth noting that while I don’t seem to have the problem now, in the past, sometimes I’d have to add a “sleep 5″ or some such, to sleep a few seconds after calling startx. Otherwise there was some sort of timing issue and the disown wouldn’t be fully processed before the script terminated, so X would still be a child of the invoking script and would be terminated with the script. But adding a few seconds of sleep allowed the disown to complete, and after that, the exiting script wouldn’t terminate X/kde.

    It’s also worth noting that not keeping the CLI login used to cause pam-console permission issues and the like, so I could no longer control alsa from X, since it wasn’t considered a console login and pam-console would therefore reset device permissions to disallow that user access. The workaround for that was to ensure that the pam-console config didn’t mess with the permissions for the affected devices, so they stayed available to users in the audio group or whatever. However, I believe pam-console has been dead for quite some time, and at least here, simply ensuring that the user is in the audio group, etc, seems to be enough, these days.

    But if either of these issues do appear, that should give people at least a hint of what’s going on and how to fix or work around it.

    1. Duncan

      Oh, people who know bash should know this already, but in case it’s not obvious, in the…

      . k

      … there’s a SPACE between the dot and the command name (k).

    2. Zach

      Duncan,

      Thank you very much for your detailed workaround! I will be reviewing all of the methods listed in the comments here, and will post my findings.

      Cheers,
      Zach

  4. Pim Vullers

    An alternative command to use would be just:
    $ startx ; exit
    or ‘logout’ whatever you prefer. This does not require any additional packages and the option that vlock requires the password of the current user only works when there is just one virtual terminal, or when vlock actually also blocks the others.

    1. Zach

      Hello Pim,

      Thank you for the suggestion. Unfortunately both methods are easily circumvented by pressing CTRL+C quickly enough that BASH will not execute the latter command.

      Cheers,
      Zach

      1. Anton

        I think you didn’t understand.
        If person runs it from command line himself it’s impossible to push him away from the keyboard and press ctrl-c ;-)

  5. Andre

    To avoid this, I use
    # startx; exit

    1. Zach

      Hello Andre,

      Thanks for letting me know of your workaround. Unfortunately, both your way and the vlock way are easily circumvented by pressing CTRL+C quickly enough that BASH will not execute the latter command.

      Cheers,
      Zach

  6. Johan Soderberg

    I start X from a terminal with the following command:
    (startx &); sleep 30; exit

    It’s important to use () around startx so it’s started as a subshell.

    1. Zach

      Hello Johan,

      Thank you very much for the suggestion. I’m going to run some tests of starting X in a subshell, and will post my findings.

      Cheers,
      Zach

  7. kitanatahu

    how about startx & ; logout
    or openvt startx ; logout
    instead of the vlock method… this has the advantage of closing the terminal as soon as the startx command is issued so it should solve other potential risks

    1. Zach

      Hello Kitanatahu,

      Yes, thank you for the suggestion. Your first method doesn’t require a terminal locker, and is, therefore, more universal.

      Cheers,
      Zach

  8. Christian Seiler

    Are you really sure that works properly? And if it does, whether it works all the time? If I run

    sleep 10 ; vlock

    in an xterm and then press Ctrl+C before the 10 seconds are up, the xterm session will not be locked. (If I just send it to background with Ctrl+Z, it will be however.)

    Since I don’t use startx, I haven’t actually tested anything, but wouldn’t the following be more sensible?

    startx & vlock

    That would lock the current console immediately after startx is called. Then the VT from which startx is called is already locked, so nobody could do some tricks to try to prevent it from being launched. Since startx doesn’t expect any user input, it should be happy in the background unless your terminal is configured to stop background processes that output stuff to the terminal (by default background processes are only stopped when they try to read).

    DISCLAIMER: Please do NOT take this as security-related advice on how to do this properly, as it is just an untested idea I’m throwing out there. I urge everybody to determine for themselves whether this (a) actually works and (b) is actually secure against threats.

    1. Zach

      Hello Christian,

      You’re correct in the your assessment that this method is easily circumvented. There are some negative side effects of issuing startx in the background like you mentioned. I’m going to mention the various workarounds in a blog post a couple days from now, and will go into more detail about each method. Thanks for the thorough suggestion!

      Cheers,
      Zach

  9. Trevor

    If you run `startx` from within `screen`, you can change back to the virtual terminal yourself, detach from the screen, and exit the virtual terminal. I call this “treehouse X” (http://blog.tremily.us/posts/Screen/).

    1. Zach

      Hello Trevor,

      That is certainly one way to get around the security problem. Thank you for the recommendation!

      Cheers,
      Zach

  10. Enlik

    I use:

    exec startx …..

    :)

    1. Zach

      Hello Enlik,

      I’ve been testing this workaround today, and I believe it works for my needs. In the next few days I’m going to post a list of the workarounds presented in the comments, and the benefits / drawbacks of each method. Thank you for your suggestion!

      Cheers,
      Zach

  11. Toralf Förster

    > startx ; vlock
    Forget it – pressing Ctrl-C fast enough 2x in a row and the 2nd command won’t be executed :-)

    1. Zach

      Hello Toralf,

      You are absolutely correct. I will soon be posting several of the workarounds listed in the comments section, and the pros / cons of each method. Thanks for your input.

      Cheers,
      Zach

  12. Leon

    How about the simple “startx & exit”.
    This runs startx in the background and immediately logs out of the virtual terminal.

    1. Zach

      Hello Leon,

      I played around with this method, and it addresses the security problem but has a couple negative side effects. For instance, the instance of X (and associated applications [the WM, session, et cetera]) remain. I then had to kill those processes before logging in again. It also seemed to slow the subsequent X restart. Thank you for the suggestion though!

      Cheers,
      Zach

  13. YoYo

    Why not just start X with ‘exec startx’ ? It will replace the running shell and when it finishes (ctrl-c, normally or with an error ;) it will just exit and go back to the login prompt…

    1. Zach

      Hello YoYo,

      Thanks for the recommendation. I have tested this method in a few different ways, and it seems to work nicely. I’m going to make another post in the near future about the various workarounds presented here in the comments. At first I thought that it caused a zombie bash process, but I haven’t been able to replicate that problem since the first time that I tried it.

      Cheers,
      Zach

      1. Alec

        There wouldn’t be a zombie process because exec results in the running shell to be replaced with the startx process (literally – the PID of startx will be the same as that of the shell you started it from).

        1. Zach

          Indeed, sir. I thought that it was, but it turned out to be completely unrelated. It was actually a problem with one of my crons.

          Cheers,
          Zach

  14. bleh

    Did i miss something? Wouldn’t `startx; logout` be as good? Also while not much likely, I would not be very surprised if multiple rapid ^C killed them before they did their job – bash is slow. Lastly, this is why startx lusers are all ricers.

    1. Zach

      startx ; logout would work in the same way as startx ; vlock, but unfortunately, neither of them work as intended. One can quickly press CTRL+C and considering BASH is a bit slow, it will nullify the latter command. I disagree with your assessment about people that use startx instead of a login manager. Many of us don’t necessarily use a graphic environment every time that we access our machines, and it seems silly to start a window manager just to start a terminal emulator. Also, booting into runlevel 5 by default can lead to problems if a problem occurs with X. In any case, the freedom of choice is one of the most appealing aspects of Linux.

      Cheers,
      Zach

  15. Adam

    There is still a problem with startx; vlock.
    1. Ctrl-Alt-F1
    2. ^Z
    3.
    4. fg

    I’d say log into the terminal, start a screen session (this is almost always useful anyway), startx. Then you can Ctrl-Alt-F1 and give a ^A-x to lock the screen. You could even give a ^A-d to detach from the first VT and log out of the terminal completely.

    1. Zach

      Hello Adam,

      Indeed, starting a screen session would be one way around the problem. I’m going to post all of the options sometime soon, and let everyone decide which ones work for them. I personally have been using exec startx for a bit, and it seems to work. I have some more testing to do, but I really appreciate your suggestion!

      Cheers,
      Zach

  16. laurentb

    I just have alias startx=”exec startx”.

    1. Zach

      Hello Laurent,

      Thanks for the suggestion. I’ve been doing some testing with the exec startx, and so far it is the solution that works the best for me. I’m going to post something within the next few days with all of the options presented here in the comments, and let everyone decide which ones work for them.

      Cheers,
      Zach

  17. Jo

    How about just disabling contr + alt +fn# keys?

    in xorg.conf in serverflags section add Option DontVTSwitch and DontZap

    http://www.x.org/archive/X11R6.8.1/doc/xorg.conf.5.html#sect4

    1. Zach

      Hello Jo,

      Yes, disabling those key combinations is certainly an option. I don’t like the idea of losing that functionality, but it would certainly resolve the security issue. I’m collecting all of the ideas presented in these comments, and will do another post with the pros and cons of each. Thank you again for your contribution.

      Cheers,
      Zach

      1. ttSnoop

        No it won’t. For example, if X server would die of a segv one can get full access to the VT.

  18. krigstask

    The best thing since sliced bread for login manager haters (like me) is sys-apps/qingy. It replaces regular getty and is capable of starting Xorg session in the same VT where you’ve logged in.

    1. Zach

      Thanks for the suggestion! I’ll have to look further into qingy as an option.

      Cheers,
      Zach

  19. Sparky

    This seems to do the trick:

    stty -isig
    startx
    logout

  20. anonymous

    How about this (works for zsh because of ‘disown’, won’t work for pure POSIX shell):
    > startx &>xorg.log &; disown %1; exit

    Of course, you should not have any other bg jobs (firstly, they will be killed; secondly, %1 must be changed accordingly).

  21. Raphi111

    Nice post, I’ve had this issue for month now. But locking or logging out right after startx wouldn’t do it for me, as I like to open a root session in tty2 :/ . How comes nobody made a screen locker that would lock the CTRL-ALT-Fn already? That would be the best solution. Having the keyboard completely locked while the screen is locked is definitely more secure.

    1. Zach

      Hi Raphil,

      I agree that having the screen locker itself forbid the function keys would likely be the most elegant solution. However, until that time, I’ve been using the workaround of:

      exec startx

      and that works for my needs.

      Cheers,
      Zach

  22. YoYo

    I don’t think that the screen locker should forbid function keys…
    (think user switching… I know the locker could provide buttons / its own functionality for that, but I don’t like that much, when I just want to switch to a text console.. ;)
    VT (console) switching is an integral part of linux, which for security assumes that each console is secured separately…
    If you (from one console/VT) open up another and wish to keep up the former (security wise) open, you have to somehow lock them both (or of course, close the first one…)

    BTW any X program disabling Ctrl-Alt-Fn through X wouldn’t work anyway… you can just unraw the keyboard (google for magic sysrq key) which will ‘take X’s ownership’ of the keyboard and then you could just use kernel’s plain Alt-Fn to switch to whatever console you can (as I said linux expects that you are allowed to switch consoles…)

    1. Zach

      All completely valid points; thanks for sharing them!

      Cheers,
      Zach

  23. Eddie

    I hate login screens but see the need for them. I found that i could use xlsh as alternative for this. This way you could have a (optional) background with an xterm window and a very simpel login shell.
    I also use this on my TTY’s because it looks cool :P

    Link to XLSH: https://github.com/Nadrin/xlsh

  24. voyager

    I believe
    exec startx
    is definitely the simplest solution. I wouldn’t even call it a workaround as it provides the exact functionality you were looking for.
    You can’t switch to your login TTY, kill X and thus circumvent the screen locker. At the same time it still allows you to switch to another TTY to login as a different user; very convenient if you have several people using the same pc… Why would you disable TTY switching? If one user locks his session, no one else can access the terminal. I don’t see a situation where this is desired. Unless you need an extremely secure box, but then you would have to do a lot more to secure it, including denying physical access to the power button etc…

    I simply don’t see any downside to this solution. All the other solutions seem overly complicated and incomplete and don’t offer any advantage over “exec startx”.

    Please, correct me if I’m wrong…

    1. Zach

      I agree with you completely. ‘exec startx’ is definitely the solution that works best for me.

      Cheers,
      Zach

      1. Denis

        I agree with you, when someone change the tty to 1 and press CTRL+C the user would logout an he is loosing the login.

        But i don’t really unterstand, when your Linux Distribution is not secure everyone could add following to your grub line:

        rw init=/bin/bash

        After that i can change the user password and have access to the computer.

        I have encrypted my whole HDD, if someone use /bin/bash, he couldn’t encrypt the hdd, because he doesn’t have the password.
        Also you could set you bios HD Password or something like that, to be more secure ;)

  1. Screen lockers xtrlock and slock | The Z-Issue

    [...] Be sure to view the update to this post for more information about a security problem with startx and screen lockers. This entry was [...]

  2. Keybindings and Openbox menu shortcuts for slock | The Z-Issue

    [...] reviewing several solutions to a security problem regarding screen lockers, I’ve found that the easiest workaround for switching virtual terminals and killing the [...]

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>