Back to /comp/

This is a follow-up about a year after I first wrote about using sudoreplay as a personal keylogger.

I recently switched positions and was provided a new computer for the new position. I setup my sudoreplay a little differently this time than previously, and I think that the setup is both simpler and superior. I use this for being able to second-guess what I did (precisely) in fast-work scenarios, to record sessions to replay for postmortems or future training, to record manual processes for converting them into script/programmatic code in the future, and simple just as a CYA for any work where I need to enter production.

sudoers

First, the sudo which ships on MacOS appears to not have things I expect already enabled for it, including 'sudoreplay' and 'sudoedit' which I use heavily. I instead opted to install sudo through HomeBrew.

Second, I added my own local sudoers modification. I tried to do things more appropriately for how MacOS is setup this time - using the sudoers.d/, zsh (default shell) - here "dayid" is my username, and "pendulum" is the hostname on this MacOS machine.

#/etc/sudoers.d/dayid
dayid pendulum = (dayid) NOPASSWD: LOG_INPUT: LOG_OUTPUT: /bin/zsh

If all you want is the ability to quickly record your own sessions for future replay - that's all you need. Anytime you want to record a shell session, just "sudo -iu <self>" and your session is being recorded.

Command scripts/aliases

The above makes this already usable by just calling "sudo -iu dayid"; but I wanted a little more convenience to myself. One is a small shell script, the other just an alias.

record

The first, named 'record' just uses "cd" to change where I am starting sudo from - so that the default sudoreplay log makes it clearer to my what the session was (more about this below).

#~/Applications/record
#!/bin/sh
# Expects sudoers to have line like:
# dayid»pendulum = (dayid) NOPASSWD: LOG_INPUT: LOG_OUTPUT: /bin/zsh
if [ "${*}" ]
  then
    sessionname=$( echo $* | tr ' ' '_' )
    mkdir -p /tmp/$sessionname > /dev/null 2>&1
    cd /tmp/$sessionname
  else
    sessionname="unnamed"
fi
echo "################################################################################"
echo "# RECORDING SESSION VIA SUDO"
echo "# SESSION NAME: $sessionname"
echo "################################################################################"
sudo -iu dayid
echo "################################################################################"
echo "# ENDED SESSION RECORDING"
cd -
/bin/rmdir /tmp/$sessionname
echo "# CLEANED SESSION DIR: /tmp/$sessionname"
echo "################################################################################"

An example of how the sudoreplay log looks after using the above. Since it contains "CWD" - I can now use that as a hint to myself about why I recorded that specific session (since using sudo -iu means the "COMMAND" will always just show the shell):

Dec 10 15:00:32 2021 : dayid : TTY=/dev/ttys001 ; CWD=/private/tmp/updating_ssl ; USER=dayid ; HOST=pendulum.home.dayid.org ; TSID=00/00/0A ; COMMAND=/bin/zsh

replay

The second simple addition I added is just a shell alias added into ~/.zshrc. Since sudoreplay requires sudo privileges to call it, I alias it so that I can type it simpler each time I want to check replay sessions.

alias replay="/usr/bin/sudo sudoreplay"

Some example use of this is very simple:

dayid$ replay -l
Dec 10 15:03:29 2021 : dayid : TTY=/dev/ttys004 ; CWD=/private/tmp/testing_sudoreplay ; USER=dayid ; HOST=pendulum.home.dayid.org ; TSID=00/00/0B ; COMMAND=/bin/zsh
Dec 10 15:18:20 2021 : dayid : TTY=/dev/ttys001 ; CWD=/private/tmp/editing_httpdconf ; USER=dayid ; HOST=pendulum.home.dayid.org ; TSID=00/00/0C ; COMMAND=/bin/zsh
Dec 10 15:27:13 2021 : dayid : TTY=/dev/ttys001 ; CWD=/private/tmp/updating_sudoersd ; USER=dayid ; HOST=pendulum.home.dayid.org ; TSID=00/00/0D ; COMMAND=/bin/zsh
Dec 10 16:52:23 2021 : dayid : TTY=/dev/ttys001 ; CWD=/private/tmp/checking_dump_status ; USER=dayid ; HOST=pendulum.home.dayid.org ; TSID=00/00/0E ; COMMAND=/bin/zsh

And, just as with regular sudoreplay (and my previous article), to replay just use the TSID:

dayid$ replay 00/00/0E

Full example:

dayid$ record echo hello i am a cat
################################################################################
# RECORDING SESSION VIA SUDO
# SESSION NAME: echo_hello_i_am_a_cat
################################################################################
dayid$ echo "hello, I am a cat."
hello, I am a cat.
dayid$ exit
################################################################################
# ENDED SESSION RECORDING
/Users/dayid/
# CLEANED SESSION DIR: /tmp/echo_hello_i_am_a_cat
################################################################################
dayid$ replay -l | tail -n 1
Dec 13 10:45:05 2021 : dayid : TTY=/dev/ttys002 ; CWD=/private/tmp/echo_hello_i_am_a_cat ; USER=dayid ; HOST=pendulum.home.dayid.org ; TSID=00/00/0F ; COMMAND=/bin/zsh
dayid$ replay 00/00/0F
Replaying sudo session: /bin/zsh
dayid$ echo "hello, I am a cat."
hello, I am a cat.
dayid$ exit