The passwordless sudo aspect of QubesOS has been one that’s confused many people and has had many pages of writing put to it over the years. The idea is that privesc is so easy in comparison to vm escapes, that any adversary advanced enough to have one would likely have an entire arsenal of escalation exploits. The conclusion then is to either place trust solely in the Xen hypervisor and its good track record or to make privesc so difficult that the above argument is no longer valid.
This is where my idea comes in: what if every qube has a “rootqube” much like they have a“netqube”? A given qube would have no root access but its rootqube would be able to run commands as root in a terminal. You could even have a sys-root whose job it is to run root terminals for most other qubes. Dom0 would be its own rootqube as one can compromise the system without root access there.
A few months after I had this idea, Kicksecure/Whonix came out with the user-sysmaint split which was founded on a similar principal. The way the split works is that there are two modes one can choose during boot: the regular user, and system maintainer. The main difference is that with root qubes, the root commands can be executed as during use instead of having to shut down and restart in sysmaint mode then back to user.
My question is if this would actually work. Can you shut off root access in this way? If the root user can be separated into a secure area, then most privesc attacks would require a vm escape (rootqubes should be airgapped and otherwise isolated from the rest of the system) but vm escapes typically require root access. This would mean that most attacks against qubes—both practical and theoretical—would be shut off. I initially thought that if such an idea were possible then it would’ve been done already but seeing Kicksecure/Whonix implement a very similar concept gave me confidence that it’s not completely stupid.
Of course, if one doesn’t like rootqubes, then setting a qube’s rootqube to itself would give the same behavior as passwordless sudo. Otherwise, one could have a secure yet convenient way of isolating root access. What do you all think?
this is kinda what templates are for, although they do not prevent people from running commands as root in an AppVM, but this is not possible for practical reasons.
You could put a random root password in your qubes when the appvm boot and disable sudo.
The minimal debian template have a unknown root password and sudo is disabled by default.
You can only access root shell by running qvm-run -u root --pass-io “debian-minimal” “xfce4-terminal”
The problem is how to make it easiser to open a root shell because running this command in dom0’s shell is very not convenient.
I write a script base on another script which installed with i3 called qubes-i3-sensible-terminal solved this problem.
### /usr/local/bin/base/sensible-get-vm
#! /usr/bin/bash
CURRENT_VM_FILE="/tmp/current-vm"
get_id() {
local id=$(xprop -root _NET_ACTIVE_WINDOW)
echo ${id##* } # extract id
}
get_vm() {
CURRENT_VM=$(cat "$CURRENT_VM_FILE")
if [[ -n "$CURRENT_VM" ]]; then
echo "$CURRENT_VM"
exit 0
fi
local id=$(get_id)
local vm=$(xprop -id $id | grep '_QUBES_VMNAME(STRING)')
local vm=${vm#*\"} # extract vmname
echo ${vm%\"*} # extract vmname
exit 0
}
### sensible-open-root-shell
#!/usr/bin/bash
source /usr/local/bin/base/sensible-get-vm
main() {
local vm=$(get_vm)
if [[ -n "$vm" ]]; then
qvm-run -u root "$vm" xfce4-terminal
fi
}
main
Bind a key to execute the sensible-open-root-shell script
Basically you just need to focus on any vm’s opened window and press the keybind, the script will open the vm’s root shell automatically.
But what if you are in a situation that don’t have a specific vm window being opened?There is another script I write that solved the peoblem.
#! /usr/bin/bash
MODE=$1
CURRENT_VM_FILE="/tmp/current-vm"
PANEL_MSG_FILE="/tmp/panel-message"
if [[ -z "$MODE" ]]; then
MODE="app"
fi
case "$MODE" in
"app")
VM_LIST=$(qvm-ls --fields name,class,provides_network | grep "AppVM" | grep False | cut -d ' ' -f 1)
;;
"net")
VM_LIST=$(qvm-ls --fields name,class,provides_network | grep True | cut -d ' ' -f 1)
;;
"template")
VM_LIST=$(qvm-ls --fields name,class | grep "TemplateVM" | cut -d ' ' -f 1)
;;
*)
echo "Invalid mode: $MODE"
exit 1
;;
esac
# You can use i3-dmenu here
SELECTED_VM=$(printf "%s\n" "$VM_LIST" | rofi -dmenu -i -p "AppVM")
if [[ -z "$SELECTED_VM" ]]; then
echo "VM not selected!"
exit 1
fi
/usr/local/bin/qubes-start-vm "$SELECTED_VM"
EXIT_CODE="$?"
if [[ "$EXIT_CODE" == 1 ]]; then
exit 1
else
echo "Current selected vm: $SELECTED_VM" > "$PANEL_MSG_FILE"
echo "$SELECTED_VM" > "$CURRENT_VM_FILE"
fi
/usr/local/bin/base/sensible-get-vm I showed above will read /tmp/current-vm to open the root shell for the vm that you chose.
Using similar concept to write script make i3 way much better than xfce4 to manage vm.
Nice! However, is it reasonably difficult for an attacker to achieve root access in such Debian minimal qubes? Moreover, is there any risk of escalation during use of the root terminal? Ideally, and this isn’t entirely realistic, the rootqubes would only be able to send data to other qubes and not the other way around so as to be in-line with the Bibi model QubesOS uses.
The idea here is to make rootqubes the only way to access root privileges even for an attacker that has near total control of a given qube (typo squatted package maybe), much like how vm escapes are nearly impossible in a fully compromised qube.
Conceptually, your approach sounds interesting. There are some things which are unclear to me though:
How will it actually be used? (example use case?)
Dom0 is currently a “rootqube” as @Atrate pointed out. Why have another (considering this is essentially a trust in one more entity, i.e. less security)?
Another thing:
This is where my idea comes in: what if every qube has a “rootqube” much like they have a“netqube”? A given qube would have no root access but its rootqube would be able to run commands as root in a terminal.
That is quite different from a NetVM. The latter is a gateway of sorts. It does not accept or send commands from/to the client. In that sense, a RootVM would not be an simply an equivalent upstream interface.
You could even have a sys-root whose job it is to run root terminals for most other qubes.
How can this be secured? What mechanism will guarantee isolation? A sys-root becomes pretty much an almighty tool for privesc, so an attacker can break into any qube with it. IOW, I see it as a vulnerable spot in the whole system rather than a security enhancement.
Also, how would a sudo script in the client VM work, if any root command must work as you suggest? What about the performance penalty of the added complexity? What about the meaning of a “command” - are we talking about all possible shells, or other calls too?
The way it would be used is that running commands that require root in a normal qube would return some error message while the rootqube would have a terminal of the root user. The reason why we wouldn’t want to use dom0 for this is because running all commands in dom0 is less secure than either running them in their originating qubes or having a dedicated disposable that can only affect one or a small handful of qubes.
My netqube comparison was only that “netqube” is a property of a qube and that every qube can be given one in settings.
Whether the root terminal exists in the client qube or in a separate qube should be up to implementation but I will continue to say rootqube, though I would like to use disposables given the recent preloaded disposable support.
While I initially had the idea of having rootqubes be as I described above, the idea of simply opening up a terminal via keybind is much more appealing to me now given its simplicity. Rather than having one qube with terminals for other qubes in separate windows, just opening up a window with the root terminal via keybind would lower the damage of compromise back down to what things are like now but without the ability for malware to run root commands silently as the user would always know when root privileges are on the table.
As for how to secure rootqubes, there are a few thoughts. One is that the above explanation on how it limits the window of malicious activity might justify it. For me though, I would like an almost one way qrexec connection with commands simply going one way and having minimal (if any) information go from the client to the rootqube. Of course, the “real” answer to the question of how to secure it is that I don’t have a foolproof plan and that’s why I posted this. I wanted to know if the community had any ideas on how to make this secure.
As for sudo scripts in the client. You’d have to run them in a rootqube or just keep the client a normal qube with passwordless sudo if it’s going to need sudo too often.
So in summary, my up to date idea is as follows: most qubes will have root disabled by default (toggle in settings) but can have a minimal disposable root terminal appear by keybind. These disposables will have some variation of “Root: QUBENAME” as their names and should shut down when the terminal window is closed. Root commands can be run arbitrarily inside the rootqube as would be done normally but with some Qubes/Xen-based isolation making it less likely that the client can infect the rootqube (NX all data coming from the client?) One possibility is that some scripts can only be accessible to the rootqube (to protect them from the client) and can be run from there to get around the sudo script inconvenience you pointed out.
If the disposable rootqube idea doesn’t work out, then maybe quer’s solution would work well enough. I can’t say though.
Have a dedicated rootqube for each VM. - Overkill.
Have one rootqube for all VMs. - No isolation: that rootqube will know every root command of every client qube.
Here is another idea:
Have a “Root Terminal” submenu for each domU to the Qubes Domains. This will be a shortcut for running e.g. qvm-run -u root VM xterm - something which required dom0 privilege, i.e. no conventional privesc possible. I don’t know how one can add such submenus though.
I did more research on the matter and it turns out my disposable idea wasn’t new. All the way back in 2022, Demi Marie said “ This allows one to log in as any user (including root) on a secure Xen TTY. The actual terminal emulator is sandboxed in a disposable VM.” which is the exact idea I had. When combined with a script that opens a root terminal via keybind and the new preloaded disposable support, this should give a secure way to access root. Other methods (like a pop up) of root isolation are actually on the 4.3 issue list being currently worked on.
An idea I’ve always had is why do we still use root passwords to begin with?
Couldn’t all of this be solved if we forced more advanced bio-metric authentication for root access? and then a multi factor for longer scripts could be some ocular or fingerprinting technology. Tracking the Iris of the eyeballs as constant stream of authentication during the shell session as root rather than a one time session based thing. Another authenticating factor could be if the scripts are being read and written by the authenticated user prior to being executed in the first place with some iris tracking technology.
Obviously If they are reading reddit it would know since the root is isolated and must be opened and only worked on while in focus. Then any injected script that managed to bypass the initial eyeball check will be blocked if it has not been confirmed to have been read word for word by the authenticated human eye that apparently wrote the command. If the authenticated is prompted on his screen with a arbitrary root shell session (which they should know right away if they haven’t wrote the script) they can simply look away or cover the screen. Then we can put that script that tried to execute somewhere for local forensics to learn about its origins and catch things in near real time more often maybe.
This type rootqubes authentication would be probably best for more high stakes scenarios. I imagine a terminal session for configuring the algorithms launch codes in an air gapped system should have something like this. But in the not so distant future we may need to really verify that a human is reading these things being entered into our systems. Especially if the bots turn against us or adversaries take control of them to turn them against us.
To add to this, fingerprint technology authenticating every key stroke or mouse click performed as root in a terminal session? Imagine a scenario for an attacker needing to bypass authentication every time a keystroke is typed should they want to arbitrarily execute some command inside a terminal session as a root user?
Then to add to it we could train the authentication on the end users digital fingerprint(another loss in privacy). To the attackers despair, once they have managed to bypass the fingerprint authentication, the iris. They must also type like the end user types as an extra kick in the knee. So if the end user points and pecks terminal commands at 5 words a minute with their middle fingers their adversary would also have to do the same to achieve their objective .