Combining Xephyr + unshare + capsh + chroot

Antivirus, forensics, intrusion detection, cryptography, etc.
Post Reply
Message
Author
User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

Combining Xephyr + unshare + capsh + chroot

#1 Post by rufwoof »

It's (relatively) trivial for say a window running as spot to see or enter commands into another window running as root. Sharing the same X session and ... X wasn't designed with security foremost in mind. A browser running as spot that has a flaw that permits remote cli access, could easily pawn the entire system/LAN.

Its equally (relatively) trivial to block that. Xephyr runs another X ... such that a window running on X0 (DISPLAY:0), can't stuff/read things into/from X1 (DISPLAY:1).

Combine that with unshare, capabilities (capsh ... such as being able to drop the capability to chroot), along with chroot ... and Barry with his EasyOS has provided great guidance as to how to create 'containers'.

I've been experimenting with using a chroot into / ... instead of a pre-created chroot folder/directory. Using / ... and everything is already set up.

First we create a Xephyr (another) X instance (DISPLAY:1)

Code: Select all

Xephyr :1 -fullscreen -dpi 133 -title chroot -br -nolisten tcp -nolisten local &
PID=$!
and prepare a script that we'll run when we chroot

Code: Select all

echo "#!/bin/sh" >/CHR
echo "DISPLAY=:1 export DISPLAY" >>/CHR
echo "rox -p /root/Choices/ROX-Filer/PuppyPin" >>/CHR
echo "jwm" >>/CHR
chmod +x /CHR
and then unshare/capsh/chroot into /, running that /CHR script

Code: Select all

DISPLAY=:1 unshare -p -m --mount-proc=/proc -f capsh --drop=cap_sys_admin,cap_sys_boot,cap_sys_chroot,
cap_sys_ptrace,cap_sys_time,cap_sys_tty_config,cap_chown,
cap_kill,cap_dac_override,cap_dac_read_search,cap_fowner,
cap_setfcap,cap_setpcap,cap_net_admin,cap_mknod,
cap_sys_module,cap_sys_nice,cap_sys_resource --chroot=/ -- /CHR
kill $PID
I've had to split that single command line over several lines when posting here, as otherwise the message displayed is massively wide and you annoyingly have to horizontally scroll the view to see it.

Those capsh drops work relatively well, but you can use capsh --print to view what capabilities remain, or you might remove some from the above set ... according to whatever your objective. Those settings worked OK in both EasyOS 1.0.8 and FatDog 8.0 RC (i.e. when the above lines of code were dropped into a script file with #!/bin/sh at the top). Within the chroot you're still root, but a root with restricted permissions, a duff-root (which in effect is comparable to a restricted userid).

Xephyr as above is set to run fullscreen. Best perhaps to change that to --resizeable at first, until you become more familiar with how it all works (remember you can use alt-tab to flip between windows, or alt-F6 to minimise the window. Opening a terminal and running jwm -exit will close the session, or you can just switch to the main real root session and right click the tray entry and select the close option).

Within the above settings, the chroot can read/write files etc. as usual, but whilst its root its a disabled root. Run ps within the chroot for instance and you only see a limited set of processes. Try and chown a file and ... not permitted. Try and chroot out of the chroot and ... not permitted. Try and mount sda3 (or whatever) and not permitted, but you can see sda3 files if they were already mounted by the 'real root'. Try and use tools to spy or enter keys into real root and ... not permitted. Run a browser and that's fine, or any other program (subject to not relying upon capabilities that have been dropped).

A word of caution for running that in Fatdog. As Fatdog chroot's seamonkey to spot, then when you run defaultbrowser (assuming that is set to seamonkey) it will complain that it cannot chroot (as we've dropped the chroot capability), and fires up the browser as root (but the duff-root). Would be better perhaps to also add a --user=spot parameter, but I haven't tested/tried that.

Clickable thumbnail. I created the ps terminal first (trying a few things such as chroot, mounting sda3), then added other windows (seamonkey viewing a youtube, audacious, libreoffice spreadsheet ... all running under the duff-root (Xephyr/unshare/capsh/chroot)).

Image Image Image
Last edited by rufwoof on Thu 21 Feb 2019, 03:19, edited 3 times in total.
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#2 Post by rufwoof »

Testing the extension of cap drops to ...

Code: Select all

DISPLAY=:1 unshare -p -m --mount-proc=/proc -f capsh --drop=cap_sys_admin,
cap_sys_tty_config,cap_mknod,cap_sys_ptrace,cap_sys_time,
cap_sys_rawio,cap_sys_module,cap_setfcap,cap_fsetid,cap_setgid,
cap_setuid,cap_dac_override,cap_setpcap,cap_ipc_owner,cap_chown,
cap_sys_chroot,cap_dac_read_search,cap_sys_boot,cap_audit_control,
cap_fowner,cap_kill,cap_net_admin,cap_net_raw,cap_mac_admin,
cap_sys_nice,cap_sys_resource --keep=1 --chroot=/ -- /CHR
Just some examples of things that wont work due to needing dropped cap's

rsyslogd/syslogd (CAP_SYS_ADMIN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH)
cron (CAP_SETUID, CAP_SETGID)
login (CAP_SETUID, CAP_SETGID, CAP_FSETID, CAP_CHOWN)
cvs (CAP_DAC_OVERRIDE, CAP_SETUID, CAP_FSETID)
postfix (CAP_DAC_OVERRIDE, CAP_KILL, CAP_SETUID, CAP_SETGID, CAP_SYS_CHROOT)
apache (CAP_KILL, CAP_SETUID, CAP_SETGID)
sshd (CAP_KILL, CAP_SYS_TTY_CONFIG, CAP_SETUID, CAP_SETGID, CAP_CHOWN)
xinetd (CAP_SETUID, CAP_SETGID)
procmail (CAP_SETUID, CAP_SETGID, CAP_DAC_OVERRIDE)

(If something doesn't work in the duff-root, then just alt-tab (or minimise the fullscreen with jwm's defined alt-F6 key combination (you may have to ctrl-shift toggle beforehand) and run it from the main/real-root desktop)).

Just some of the things that seem to work ok with those new settings (I haven't tested them thoroughly), LibreOffice writer/calc, seamonkey, gimp, mtpaint, audacious, alsamixer, galculator, geany, leafpad, scribus, evince, dotpup (petget).

A nice feature about EasyOS is how it works opposite to Puppy. Everything is written to disk (save area) and you use snapshots that create a sfs copy of that save area (rollbacks restore from a snapshot sfs to the (pre emptied) save area). So saves by default, and never runs out of space (subject to available free space). So to not save you create a snapshot of the save area, use the system as desired, and then rollback to that (or any other) 'safe' snapshot as/when you desire. For the main system (real root) you can set that rollback to occur at the next reboot. So after using duff-root you can simply set they system to rollback to a known safe snapshot at the next reboot and shutdown.
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

jamesbond
Posts: 3433
Joined: Mon 26 Feb 2007, 05:02
Location: The Blue Marble

#3 Post by jamesbond »

Interesting! Keep them coming, rufwoof! :D
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#4 Post by rufwoof »

Here's my current tweaked version of Barry's use of pflask capabilities dropping.

I've set the font size to 1 (otherwise widens out the forums width to a uncomfortable size) so illegible as-is, cut the two lines between the lines of === and paste them into a editor to see the actual text

=========================================

Xephyr :1 -fullscreen -title easy -name Xephyr1 -zap -dpi 132 -nolisten tcp
pflask --mount=bind:/mnt/sda1/easy/1.0.8/home/shared:/shared-folder --keepenv --mount=bind:/tmp/.X11-unix/X1:/tmp/.X11-unix/X1 --no-netns --mount=bind:/dev/snd:/dev/snd --mount=bind:/dev/mixer:/dev/mixer --caps=all,-sys_admin,-sys_boot,-sys_chroot,-sys_ptrace,-sys_time,-sys_tty_config,-chown,-kill,-dac_override,-dac_read_search,-fowner,-setfcap,-setpcap,-net_admin,-mknod,-sys_module,-sys_nice,-sys_resource,-sys_rawio,-fsetid,-setgid,-setuid,-ipc_owner,-audit_control,-net_raw,-mac_admin --no-userns --chroot=/mnt/sda1/easy/1.0.8/containers/easy/container -- /.control/ec-run easy


=========================================
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#5 Post by rufwoof »

[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#6 Post by rufwoof »

This uses minimal protection of Xephyr X isolation, unshare, chroot with cap_sys_chroot capability dropped. That provides reasonable isolation for running a browser within. Requires pflask (that's already in EasyOS), which was easily compiled using the guidance provided with the code.

Could be used as a basis to add a basic EasyOS like container to other Puppy's

Code: Select all

#!/bin/sh

######################################################

# Change these as required ...

# Folder where changes.sfs is stored
CHANGES_SFS_LOC=/mnt/sda1/easy/easyremastered-1.0/home/shared
# Where the main easy.sfs is located
EASY_SFS=/mnt/sda1/easy/easyremastered-1.0/easy.sfs
# dpi setting for container
DPI=144
# Container screen geometry, i.e. actual screen size with the Y value reduced
# by the jwm tray height (28 jwm tray on my 1440x900 resolution setup)
SCR=1440x872

######################################################

# Xephyr parameters
XP="-resizeable -dpi ${DPI} -nolisten tcp"
XP="${XP} -screen ${SCR}+0+0"
XP="${XP} -title Container -name Xephyr2"
	
# pflask parameters
PF="--keepenv --no-netns --no-userns"
PF="${PF} --mount=bind:/etc/machine-id:/etc/machine-id"    # firefox needs this
PF="${PF} --mount=bind:/etc/resolv.conf:/etc/resolv.conf"  # dns (internet) 
PF="${PF} --mount=bind:/dev/snd:/dev/snd"
PF="${PF} --mount=bind:/dev/mixer:/dev/mixer"
PF="${PF} --caps=all,-sys_chroot"
PF="${PF} --chroot=${CHANGES_SFS_LOC}/top"	

# cd to where changes.sfs is located
cd ${CHANGES_SFS_LOC}

# Avoid double click 2 instances
N=`date +%s` # Seconds since January 1970
if [ -f /tmp/container.run ]; then
	L=`cat /tmp/container.run`
	D=`expr $N - $L`
	if [ $D -lt 2 ]; then
		echo "Aborting : use only a single click to run $0"
		exit
	fi
fi
echo $N >/tmp/container.run

# Check required programs are available
[ -z `which popup` ] && xmessage Requires popup && exit
[ -z `which Xephyr` ] && popup Requires Xephyr && sleep 3 && killall popup && exit
[ -z `which pflask` ] && popup Requires pflask && sleep 3 && killall popup && exit
[ -z `which unshare` ] && popup Requires unshare && sleep 3 && killall popup && exit
[ -z `which chroot` ] && popup Requires chroot && sleep 3 && killall popup && exit
[ -z `which capsh` ] && popup Requires capsh && sleep 3 && killall popup && exit
[ -z `which empty` ] && popup Requires empty && sleep 3 && killall popup && exit
[ -z `which sakura` ] && popup Requires sakura && sleep 3 && killall popup && exit
[ -z `which jwm` ] && popup Requires jwm && sleep 3 && killall popup && exit
[ ! -f changes.sfs ] && popup Requires changes.sfs && sleep 3 && killall popup && exit
[ ! -f ${EASY_SFS} ] && popup "Missing ${EASY_SFS}" && sleep 3 && killall popup && exit

# Create a separate X instance so isolated from the main real root X
T=`ps -ef | grep Xephyr2 | wc -l`
if [ $T -ne 2 ]; then
	Xephyr :2 ${XP} &
else
	echo "Aborting as Xephyr2 is already running"
	exit
fi

# Create a changes folder, sfs mount point for easy.sfs and top layer folders
ACTIVE=0
T=`mount | grep '${CHANGES_SFS_LOC}/sfs'`
[ ! -z  "${T}" ] ACTIVE=1
T=`mount | grep '${CHANGES_SFS_LOC}/top'`
[ ! -z  "${T}" ] ACTIVE=1
[ ! -d top ] && mkdir top
[ ! -d sfs ] && mkdir sfs
# Start with a 'clean' snapshot of changes
[ ! -d changes ] && mkdir changes
if [ $ACTIVE -eq 0 ]; then
	[ -d changes ] && rm -rf changes
	DISPLAY=:2 popup "unsquashing changes.sfs "
	urxvt -g 70x4+10+10 -bg '#09A0FF' -e unsquashfs -f -d changes changes.sfs
fi

# To remount a already mounted, we use the -r (read) parameter
T=`mount | grep '${CHANGES_SFS_LOC}/sfs'`
[ -z  "${T}" ] && mount -r -t squashfs ${EASY_SFS} sfs

# aufs mount combining changes and sfs folders -> top
T=`mount | grep '${CHANGES_SFS_LOC}/top'`
[ -z  "${T}" ] && mount -t aufs -o br=changes:sfs none top

# create a script to run inside the chroot (i.e. must be a script, not a bin)
echo "#!/bin/sh" >top/init
echo "DISPLAY=:2 export DISPLAY" >>top/init
echo "sakura --geometry 1x1 -x killall sakura # wake up Xephyr gtk/dbus" >>top/init
killall popup
echo "seamonkey &" >>top/init
echo "jwm" >>top/init
chmod +x top/init

sync
killall popup

# chroot dropping chroot capability (to prevent chroot'ing out of the chroot)
# and using another X session (to isolate it from the main X session)
# chroot (pflask makes things easier) into the top folder applying restrictions 
# We use the main sfs as our base for the chroot, so chroot has very low overhead
DISPLAY=:2 empty -f unshare -m pflask ${PF} -- /init
PID=$!

# Tidy up after closing.
# The above falls through to here, so we need to monitor for when that ends
# kill -0 ... checks for existance (not very intuitive!) 
while kill -0 $PID >/dev/null 2>&1
do
	sleep 2
done
umount top
umount sfs
rm -rf changes.previous
mv -f changes changes.previous
killall Xephyr
# leave changes.previous in case we want to mksquashfs a new 'clean' changes.sfs
rmdir top sfs

exit
######################################################
	Everything below the last exit will be ignored i.e. are comments
######################################################
"
Change log :

	Rufwoof. 20190312 : 12th March 2019 initial version

Notes : 

Run browser (desktop) using a combination of

	unshare (mount points), 
	chroot (isolation)
	capsh (chroot capabilities dropped - to block chroot'ing out of chroot)
	using Xephyr (X separation)
	
Main easy sfs is used as the base for the chroot stores changes in a separate
changes folder i.e. low overheads, easily reset to 'clean'

Uses pflask https://github.com/ghedo/pflask that simplifies chroot'ing

Note that I've tweaked this to fit my 1440x900 display size/resolution and added
into ~/.jwm/jwm-personal a group clause that sets Xephyr2 (the name allocated
to the Xephyr window above) to have no border and no title i.e.

	<Group>
	  <Name>Xephyr2</Name>
	  <Option>noborder</Option>
	  <Option>notitle</Option>
	</Group>

 I've also adjusted the Xephyr -screen parameter size so the containers jwm
 menu/tray sits just above the main systems tray.
 Setting jwm tray Outline tag in jwmrc-theme to be the same colour as the tray
 background helps merge the two stacked tray into more seemingly one.
"
######################################################
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#7 Post by rufwoof »

A simple test for command injection potential requires xdotool to be installed. A cracker with cli access will typically pull down their own alternative tools over the internet, but for testing purposes xdotool suffices.

Open a terminal and su into spot

Code: Select all

su - spot
Scan around the system for a potential target window that is running as root and note the pid for that window. For demonstration purposes we'll just open another terminal window as root. With that root terminal window open, in the terminal running as spot run ps -ef and locate the root terminal with that list and note its pid. Then run

Code: Select all

xdotool search --pid <pid>
for that target root terminal window pid and note its window id <wid>
You may get back one or more window id's, a cracker might refine the search or simply just try each in turn to run something like

Code: Select all

xdotool windowactivate <wid>;xdotool type whoami;xdotool key KP_Enter
You may have to set DISPLAY before running the above, perhaps something like

Code: Select all

DISPLAY=:0 export DISPLAY
Running whoami as in the above example is a benign command injection, typically a cracker would obviously run much more intrusive commands/actions.

It doesn't have to be a terminal window that is used as the target, it could for instance be a filemanager window that has a option to open a terminal and commands could be injected into that to open a terminal window ...etc.

Similar simple methods can also be used to monitor root keystrokes/activities etc. Awareness of how trivial such actions are is a step in the right direction towards better protecting your privacy/data/system.

What Xephyr/chroot/capsh facilitate is to isolate your main real root session from a internet facing program such as a browser, that may have bugs that enable running commands remotely. Running the above commands within the 'container' will still be able to inject commands into other windows within that container, but the chroot and Xephyr separation from the main session/desktop prevents injecting commands into the 'real root' (or watching/entering keystrokes via a key logger/keystroke injector).

Even if you reboot 'clean' sessions each and every time, a cracker that obtained access to real/full root even just briefly during a single session may have tweaked the system, such as installing their own sub-system bootloader chained background process that once the system boots appears totally normal and can't even see that crackers sub-system processes running in the background.
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

Post Reply