mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 14:16:14 -06:00
[GH-ISSUE #240] Jail "escape" with xfce4-terminal? #170
Labels
No labels
LTS merge
LTS merge
bug
bug
converted-to-discussion
doc-todo
documentation
duplicate
enhancement
file-transfer
firecfg
firejail-in-firejail
firetools
graphics
help wanted
information_old
installation
invalid
modif
moved
needinfo
networking
notabug
notourbug
old-version
overlayfs
packaging
profile-request
pull-request
question
question_old
removal
runtime-permissions
sandbox-ipc
security
stale
wiki
wiki
wontfix
wordpress
workaround
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/firejail#170
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @io7m on GitHub (Jan 20, 2016).
Original GitHub issue: https://github.com/netblue30/firejail/issues/240
Hello. I'm evaluating firejail to replace my current browser setup. I'm using version
0430643b36669aeaf4ea3b9ff31eb092c92b48dcfrom git on Arch Linux.At this point a terminal pops up onscreen and in it, I can access the full system outside of the jail, including my real home directory. It's also possible to do:
... and get a terminal that connects to google.com.
The terminal that is started in both cases is started outside of the jail, so there's no ability to directly communicate to the process from the jail once it's started. No doubt an actual attacker would find a way to work around this limitation (can still execute arbitrary commands on the host).
@netblue30 commented on GitHub (Jan 20, 2016):
Yes, because xfce terminal is running as a single process. If you have multiple windows open, all of them are handled by the same process. You have to make sure the first terminal is started inside the sandbox.
This is the case with most terminals. An exception is the good old xterm. Some other programs such as Firefox have the same problem. In the case of Firefox, they provide a command line option to open a separate process, --no-remote.
@io7m commented on GitHub (Jan 20, 2016):
Yes, I assumed that this was the case.
Is there a way to mitigate the problem? I don't know the exact mechanism involved, but I assume it involves
dbus...@io7m commented on GitHub (Jan 20, 2016):
Perhaps mounting an empty tmpfs directory over
/runin the same way private home directories are created.@genodeftest commented on GitHub (Jan 22, 2016):
I suggest 2 different solutions (depending on the use case):
--new-instance, consultxfce4-terminal --help. You'll probably want a separate starter .desktop file for that.@io7m commented on GitHub (Jan 22, 2016):
I think the wrong point is being made here.
I was making the point that for a given default firejail (assuming the firefox profile, for example), if an attacker manages to get an unprivileged shell (possibly due to an exploit in firefox), then the attacker can effectively escape the sandbox if they can find a program like
xfce4-terminalthat works in this manner and that happens to be currently running on the host.I'm looking for mitigations for this problem and the ability to deny by default, rather than trying to sandbox specific programs as suggested.
We're talking about Linux here, so the main IPC mechanisms are IP, unix domain sockets, or shared memory. IP can be locked down by specifying
nonet. Unix domain sockets can be locked down by forbidding access to as much of the host filesystem as possible (don't allow access to the host's/runin the jail, or preferably whitelist the bare minimum host directories). Shared memory can supposedly be restricted by namespaces, but I don't know how this works.@genodeftest commented on GitHub (Jan 22, 2016):
I understand. You basically say an application with a firejail profile can be used to drop the jail.
Leaving all child processes inside the same jail might break them. This would be the conservative way to go. How about adding a whitelist to that? e.g. your web browser might open a pdf reader for convenience…
Disallowing child processes at all might break applications. Firefox e.g. requires to be able to fork() and exec(). This would be the most secure way to go.
@the8472 commented on GitHub (Jan 27, 2016):
child processes are not the issue, IPC mechanisms being able to communicate with the outside of the sandbox are.
Or by completely disabling unix sockets.
firejail --noprofile --protocol=inet,inet6@netblue30 commented on GitHub (Jan 27, 2016):
You cannot disable the Unix sockets, X11 is connected over such a socket. Firefox will not start.
In my opinion, the attacker will stay away from terminals. An xfce terminal is pretty visible on user desktop, and it is unclear to me how will he be able to manage the new window. All he needs is a stealth /bin/bash or /bin/sh session that will call home and open a terminal session on the attacker's computer. From there he can try to do whatever, but he will still be restricted by seccomp and all other security mechanisms imposed by the sandbox.
@the8472 commented on GitHub (Jan 27, 2016):
Well, the issue is not specific to xfce. Services outside the sandbox offered via IPC are a general concern.
Would it be possible to use seccomp to whitelist paths used to open the socket? Similar to bsd's pledge.
That way the decision about unix sockets wouldn't be binary.
Securing X11 is a separate concern of course (#57).
@netblue30 commented on GitHub (Jan 27, 2016):
IPC namespace is not enabled in the sandbox, it will break X11. There is no support in Linux kernel to selectively disable Unix sockets. You can disable filesystem-based Unix sockets using --blacklist, but you cannot control the abstract sockets without breaking X11.
If you do netstat -a, the sockets starting with @ are abstract. You can look for xfce-terminal sockets and disable them if they are not abstract.
@ssokolow commented on GitHub (Jan 27, 2016):
@netblue30
Actually, it's a perfectly reasonable concern. While it's tricky to get right, it's perfectly possible to launch a terminal window/tab which lives only long enough (a fraction of a second) to launch its own child process in the background and then exit.
I'd say this would be one of the first things an attacker might consider if sandboxing is to be more than "security by obscurity".
@netblue30 commented on GitHub (Jan 27, 2016):
Well, such an attach needs to be demonstrated first outside the sandbox.
@ssokolow commented on GitHub (Jan 27, 2016):
I'm running up against the end of my free time right now, but I'll try to put together a proof of concept either today or tomorrow.
@netblue30 commented on GitHub (Jan 27, 2016):
Sure, no problem. These are some socket attacks I already know about:
@ssokolow commented on GitHub (Jan 27, 2016):
I decided I couldn't wait. Here's your proof of concept.
Given time, I could probably redesign it a shell one-liner to make it harder for something like
disable-devel.incto blacklist without breaking things, but this was quicker for a POC anddisable-devel.inccurrently neglects to disallow Python despite it being present by default on all "desktop-ready out of the box" distros I've tried.Usage: Use some kind of exploit to...
do_nasty_thing.pywhere it won't be noticed.xfce4-terminal --geometry=1x1+0+0 --hide-menubar --hide-borders --hide-toolbar -x python do_nasty_thing.pyIf you're paying attention, you'll notice as a tiny square in the top-left corner of the screen flickers black/white for a split second but then the
ogg123subprocess continues walking through your system sounds long after it's gone.Note: There's some kind of race condition I haven't tracked down yet. On my system, without the
time.sleep(0.05)line, it would only trigger one time in five. I chose the0.05number because it seems to be enough to make it trigger reliably while not perceptibly increasing the time the terminal window is visible. If it doesn't trigger reliably for you, try increasing that number.@netblue30 commented on GitHub (Jan 27, 2016):
We need to find all Unix sockets opened by terminal programs (xfce-terminal, gnome-terminal etc.) and blacklist them if possible. Can you guys please take a look at netstat -a output, something like this:
In my case I have a socket open by lxterminal (LXDE). Thanks.
@ssokolow commented on GitHub (Jan 27, 2016):
There are a lot of niche terminal programs out there and a blacklist is an easy way to build a false sense of security. (Especially when domain sockets are likely to be a less familiar construct for potential ruleset-writers than filesystem paths or TCP/UDP sockets)
What are your plans to ensure that blacklisting doesn't accidentally prevent testing from catching the need for properly-tuned whitelists?
@netblue30 commented on GitHub (Jan 27, 2016):
Without a new kernel module or some heavy modifications in the kernel, the only thing we can do in user space is to blacklist sockets as they are discovered.
Another solution would be to use firejail on top of some mandatory access control framework (grsecurity, selinux, apparmor) that allows filtering of unix sockets.
@ssokolow commented on GitHub (Jan 27, 2016):
Ahh. Well, better than nothing, I suppose.
Also, for the record, I noticed that urxvt can be run in daemonized mode while I was setting mine up but I don't use it that way.
@netblue30 commented on GitHub (Jan 27, 2016):
I am looking at a openSUSE box running XFCE, it is absolutely nutz:
@the8472 commented on GitHub (Jan 27, 2016):
I think seccomp can notify a ptrace tracer and then inspect the syscall arguments (i.e. the socket name) via PTRACE_GETREGS/PTRACE_PEEKDATA and then decide whether to allow the syscall, return an error or kill the process.
So it might be possible to whitelist unix socket access, but it would be non-trivial to get it right since you would have to poke around in a different process.
@netblue30 commented on GitHub (Jan 30, 2016):
I ended up blacklisting some of the terminals in etc/disable-common.inc:
I think the problem is common to all terminals implementing tabs. I put in the terminals for the main desktop environments, there are more to come.
@vn971 commented on GitHub (Feb 19, 2016):
@netblue30 would it be possible to just use
private-tmpby default? It seems like a more appropriate solution because it does not rely on some "magical terminal list" knowledge.The only problem I see with
private-tmpis that it conflicts with--net=none. If you have bothprivate-tmpand--net=none, X11 applications won't start because they will now know how to connect to X11.So, proposed solution:
private-tmpby default/tmp/.X11-unix/above our virtual/tmp/.X11-unix/by default.Would that work? I think it might. Thoughts?
UPDATE: see 2 comments below a more simple solution.
@netblue30 commented on GitHub (Feb 19, 2016):
This is the status:
@vn971 commented on GitHub (Feb 19, 2016):
@netblue30 interesting. I misunderstood how xfce4-terminal and gnome-terminal work. Still, there may be other terminals and applications like lxterminal. A good /tmp may still be needed, won't it? If sandboxing /tmp has no downsides, why not sandbox it by default? (Note that I may not know some downsides of sandboxing /tmp. But as far as I can tell, it'd be OK.)
@vn971 commented on GitHub (Feb 19, 2016):
UPDATE: Further investigation showed that, in order to sandbox the
/tmpcommunication, one of the following is enough:whitelist /tmp/.X11-unixorprivate-tmpThe first alternative allows X11 to be used (but no other means of
/tmpcommunication), while the second alternative will forbid X11 (together with--net=none, it will make applications unable to use a GUI).@netblue30 commented on GitHub (Feb 20, 2016):
On older distro versions, some applications (PulseAudio etc) used to keep Unix sockets under /tmp. In the newer versions they started moving the sockets to /run, but there are still applications with sockets under /tmp.