Online (Live) Digital Forensics
Online digital forensics is conducted while the system is running and may be connected to a network. This approach captures volatile data, such as RAM contents, running processes, network connections, open files, and active sessions, information that would be lost if the system were shut down.
This method is particularly useful in incident response, malware analysis, and detecting ongoing attacks. Investigators must handle live systems carefully to avoid inadvertently altering evidence.
- Advantages
- Captures evidence that would otherwise be lost.
- Detects live malware or intrusions.
- Drawbacks
- Risk of changing evidence during collection.
- Potential interference from malware or attackers.
- Examples
- Taking a memory dump from a live server to find encryption keys.
- Monitoring network traffic during an active breach.
Offline Digital Forensics
Offline digital forensics involves investigating digital evidence without connecting the device to any network. This approach works with physically acquired data, such as hard drives, USB drives, and memory cards.
Typically, investigators create a bit-for-bit forensic image of the storage media to preserve the original evidence. Offline analysis allows tools to examine files, metadata, logs, and deleted or hidden data. The main focus is on maintaining evidence integrity and avoiding contamination.
- Advantages
- Safer, with no risk of remote tampering or malware activation.
- Provides full access to files and system data.
- Drawbacks
- Cannot capture volatile information like RAM contents, active processes, or open network connections.
- Some logs or system states may be lost after shutdown.
- Examples
- Cloning a suspect’s hard drive to recover deleted files.
- Analyzing data from a crashed USB stick.
Accessing Environment Variables
Password or secret keys can be stored in environment variables; the application or service accesses those variables when a password or secret key is needed; you can use the env command to review them
To add an environment variable, you can use the export command
export # Shell built-in: sets an environment variable and makes it available to all child processes
SECRET_A_API # Name of the environment variable
= # Assign operator
8vjZYsQxW9v6a4hA # Value being assigned to the environment variable
(RPi) export SECRET_A_API=8vjZYsQxW9v6a4hA
To review them using env command
env # Shell command that prints all environment variables and their current values
(RPi) env
SHELL=/bin/bash
NO_AT_BRIDGE=1
PWD=/home/pi
LOGNAME=pi
XDG_SESSION_TYPE=tty
MOTD_SHOWN=pam
HOME=/home/pi
LANG=en_GB.UTF-8
SECRET_A_API=8vjZYsQxW9v6a4hA
Accessing Startup Service
Also known as System V init is also known as an old init daemon used for startup items (E.g., a script that started when the operating system started). Startup items are saved in the /etc/init.d/ folder and have specfiic structure
grep # Command-line utility to search for text patterns within files
-n # Show the line number of each matching line
-r # Recursively search directories and their subdirectories
-I # Ignore binary files (do not search inside non-text files)
Default-Start # The text pattern to search for (commonly used in SysV init scripts to indicate runlevels)
/etc/init.d # Directory containing traditional init scripts for services
(RPi) grep -nrI Default-Start /etc/init.d
/etc/init.d/cron:10:# Default-Start: 2 3 4 5
/etc/init.d/ssh:7:# Default-Start: 2 3 4 5
/etc/init.d/rpcbind:9:# Default-Start: S
/etc/init.d/avahi-daemon:8:# Default-Start: 2 3 4 5
Systemd
A newer init daemon is used for parallel startup items/services (E,.g. a script that runs when the operating system starts). Usually, the system-wide startup items/services saved in the /etc/systemd/system folder and have a specific structure
ls # List directory contents
-l # Long listing format: shows permissions, owner, group, size, and modification date
-a # Show all files, including hidden files (those starting with a dot)
/etc/systemd/system # Directory containing systemd service unit files and custom overrides
(RPi) ls -la /etc/systemd/system
total 88
drwxr-xr-x 20 root root 4096 Aug 20 10:35 .
drwxr-xr-x 5 root root 4096 May 2 17:07 ..
drwxr-xr-x 2 root root 4096 May 2 17:08 bluetooth.target.wants
lrwxrwxrwx 1 root root 42 May 2 17:09 dbus-fi.w1.wpa_supplicant1.service -> /lib/systemd/system/wpa_supplicant.service
lrwxrwxrwx 1 root root 37 May 2 17:08 dbus-org.bluez.service -> /lib/systemd/system/bluetooth.service
lrwxrwxrwx 1 root root 40 May 2 17:09 dbus-org.freedesktop.Avahi.service -> /lib/systemd/system/avahi-daemon.service
lrwxrwxrwx 1 root root 40 May 2 17:09 dbus-org.freedesktop.ModemManager1.service -> /lib/systemd/system/ModemManager.service
lrwxrwxrwx 1 root root 45 May 2 17:07 dbus-org.freedesktop.timesync1.service -> /lib/systemd/system/systemd-timesyncd.service
lrwxrwxrwx 1 root root 36 May 2 17:16 default.target -> /lib/systemd/system/graphical.target
drwxr-xr-x 2 root root 4096 May 2 17:04 default.target.wants
drwxr-xr-x 2 root root 4096 May 2 17:09 dev-serial1.device.wants
drwxr-xr-x 2 root root 4096 May 2 17:12 dhcpcd.service.d
lrwxrwxrwx 1 root root 35 May 2 17:11 display-manager.service -> /lib/systemd/system/lightdm.service
drwxr-xr-x 2 root root 4096 May 2 17:36 getty.target.wants
drwxr-xr-x 2 root root 4096 May 2 17:16 getty@tty1.service.d
drwxr-xr-x 2 root root 4096 May 2 17:09 graphical.target.wants
drwxr-xr-x 2 root root 4096 May 2 17:08 halt.target.wants
drwxr-xr-x 2 root root 4096 May 2 17:36 multi-user.target.wants
drwxr-xr-x 2 root root 4096 May 2 17:09 network-online.target.wants
drwxr-xr-x 2 root root 4096 May 2 17:08 poweroff.target.wants
drwxr-xr-x 2 root root 4096 May 2 17:15 printer.target.wants
drwxr-xr-x 2 root root 4096 May 2 17:09 rc-local.service.d
drwxr-xr-x 2 root root 4096 May 2 17:08 reboot.target.wants
drwxr-xr-x 2 root root 4096 May 2 17:08 remote-fs.target.wants
drwxr-xr-x 2 root root 4096 May 2 17:15 sockets.target.wants
lrwxrwxrwx 1 root root 31 May 2 17:36 sshd.service -> /lib/systemd/system/ssh.service
-rw-r--r-- 1 root root 179 Aug 20 10:35 update.service
drwxr-xr-x 2 root root 4096 May 2 17:09 sysinit.target.wants
lrwxrwxrwx 1 root root 35 May 2 17:05 syslog.service -> /lib/systemd/system/rsyslog.service
drwxr-xr-x 2 root root 4096 May 2 17:05 timers.target.wants
To access the SSH service, you can view the .service file that contains the configuration
cat # Reads the contents of a file and outputs to standard output
/etc/systemd/system/sshd.service # Path to the systemd service unit file for SSH daemon (sshd)
(RPi) cat /etc/systemd/system/sshd.service
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
Alias=sshd.service
Recent Accessed Files/Folders
The find command can get a list of the most recently accessed files or folders (E.g., files/folders were read). The following will print the last files that were read
sudo # Run the following command with superuser (root) privileges
find # Search for files and directories in a directory hierarchy
. # Start searching from the current directory
-type f # Restrict results to files only (ignore directories)
-atime -1 # Match files that were last accessed within the last 1 day
-printf “%Ad-%Am-%AY %AH-%AM-%AS %h%f\n” # Custom output format:(%Ad) day of last access. (%Am) month of last access.(%AY) year of last access.(%AH) hour of last access.(%AM) minute of last access.(%AS) second of last access.(%h) directory path containing the file.(%f) file name(\n) newline at end of each output line
| # Pipe: send output of find to the next command
sort -n # Sort the output numerically (here sorts by date/time fields)
(RPi) sudo find . -type f -atime -1 -printf "%Ad-%Am-%AY %AH-%AM-%AS %h%f\n" | sort -n
10-08-2023 21-24-54.9930529990 ./app/b/run.py
10-08-2023 21-24-55.3170477670 ./app/a/run.py
10-08-2023 21-24-55.9250379500 ./creds
10-08-2023 23-38-19.0940423980 ./temp
Recent Modified Files/Folders
The find command can be used to get a list of the most recent modified files (E.g., content changed). The following will print the last files whose content changed
sudo # Run the following command with superuser (root) privileges
find # Search for files and directories in a directory hierarchy
. # Start searching from the current directory
-type f # Restrict results to files only (ignore directories)
-ctime -1 # Match files whose status (metadata) changed in the last 1 day
-printf “%Cd-%Cm-%CY %CH-%CM-%CS %h%f\n” # Custom output format: (%Cd) day of last status change. (%Cm) month of last status change. (%CY) year of last status change. (%CH) hour of last status change. (%CM) minute of last status change. (%CS) second of last status change. (%h) directory path containing the file. (%f) file name. (\n) newline at the end of each output line.
| # Pipe: send output of find to the next command
sort -n # Sort the output numerically (here sorts by date/time fields)
(RPi) sudo find . -type f -mtime -1 -printf "%Td-%Tm-%TY %TH-%TM-%TS %h%f\n" | sort -n
10-08-2023 23-26-38.4205909130 ./.bash_history
10-08-2023 23-46-33.2525871390 ./x
10-08-2023 23-50-39.9322762010 ./creds
10-08-2023 23-51-11.2037410210 ./api.p
10-08-2023 23-51-21.4755656850 ./run.sh
Recent Changed Files/Folders
The find command can be used to get a list of the most recently changed files (E.g., permissions changed). The following will print the last files whose meta data changed
sudo # Run the following command with superuser (root) privileges
find # Search for files and directories in a directory hierarchy
. # Start searching from the current directory
-type f # Restrict results to files only (ignore directories)
-mtime -1 # Match files whose **content was modified** in the last 1 day
-printf “%Td-%Tm-%TY %TH-%TM-%TS %h%f\n” # Custom output format: (%Td) day of last modification. (%Tm) month of last modification. (%TY) year of last modification. (%TH) hour of last modification. (%TM) minute of last modification. (%TS) second of last modification. (%h) directory path containing the file. (%f) file name. (\n) newline at the end of each output line.
| # Pipe: send output of find to the next command
sort -n # Sort the output numerically (here sorts by date/time fields)
(RPi) sudo find . -type f -ctime -1 -printf "%Cd-%Cm-%CY %CH-%CM-%CS %h%f\n" | sort -n
10-08-2023 23-17-50.0660037610 ./.cache/lxsession/LXDE-pi/run.log
10-08-2023 23-26-38.4245907720 ./.bash_history
10-08-2023 23-46-33.2525871390 ./x
10-08-2023 23-50-39.9322762010 ./creds
10-08-2023 23-51-01.4439078220 ./contract
Accessing accounts shadow
A file that has encrypted user passwords
sudo # Run the following command with superuser (root) privileges
cat # Display the contents of a file to standard output
/etc/shadow # Path to the shadow password file on Linux
(RPi) pi@jdoe:~ $ sudo cat /etc/shadow
root:*:19480:0:99999:7:::
daemon:*:19480:0:99999:7:::
bin:*:19480:0:99999:7:::
sys:*:19480:0:99999:7:::
sync:*:19480:0:99999:7:::
games:*:19480:0:99999:7:::
man:*:19480:0:99999:7:::
lp:*:19480:0:99999:7:::
mail:*:19480:0:99999:7:::
news:*:19480:0:99999:7:::
uucp:*:19480:0:99999:7:::
proxy:*:19480:0:99999:7:::
www-data:*:19480:0:99999:7:::
backup:*:19480:0:99999:7:::
list:*:19480:0:99999:7:::
irc:*:19480:0:99999:7:::
gnats:*:19480:0:99999:7:::
nobody:*:19480:0:99999:7:::
systemd-network:*:19480:0:99999:7:::
systemd-resolve:*:19480:0:99999:7:::
_apt:*:19480:0:99999:7:::
pi:$5$SD.7RGax6g$cA9SFp3QDYnU9D4ncl.KxRBvyOaeG/gg5fN/bIZI49A:19480:0:99999:7:::
systemd-timesync:*:19480:0:99999:7:::
messagebus:*:19480:0:99999:7:::
_rpc:*:19480:0:99999:7:::
statd:*:19480:0:99999:7:::
sshd:*:19480:0:99999:7:::
avahi:*:19480:0:99999:7:::
dnsmasq:*:19480:0:99999:7:::
lightdm:*:19480:0:99999:7:::
rtkit:*:19480:0:99999:7:::
pulse:*:19480:0:99999:7:::
saned:*:19480:0:99999:7:::
colord:*:19480:0:99999:7:::
hplip:*:19480:0:99999:7:::
rpi-first-boot-wizard:*:19480:0:99999:7:::
systemd-coredump:!*:19480::::::
Bash history
Bash is a command language interpreter that is used for working with files and data, sometimes there are different shells are installed, and you can list them using cat /etc/shells; the Bash shell usually saves the user input commands into a file called .bash_history
cat # Display the contents of a file to standard output
~/.bash_history # Path to the current user’s Bash history file (contains commands previously run in the shell)
(RPi) cat ~/.bash_history
./run.sh
sudo ./run.sh
Logs
The logs location in Linux distros is /var/log/, not IoT devices enable logging because it consumes their resources.
/var/log/auth.log (user logins and authentication)
cat # Display the contents of a file to standard output
/var/log/auth.log # Path to the authentication log file; records all login attempts, sudo usage, and authentication-related events
(RPi) cat /var/log/auth.log
May 2 17:36:45 jdoe systemd-logind[456]: New seat seat0.
May 2 17:36:45 jdoe systemd-logind[456]: Watching system buttons on /dev/input/event0 (vc4-hdmi-0)
May 2 17:36:45 jdoe systemd-logind[456]: Watching system buttons on /dev/input/event1 (vc4-hdmi-1)
May 2 17:36:46 jdoe sshd[587]: Server listening on 0.0.0.0 port 22.
May 2 17:36:46 jdoe sshd[587]: Server listening on :: port 22.
May 2 17:36:52 jdoe login[620]: pam_unix(login:session): session opened for user pi(uid=1000) by LOGIN(uid=0)
May 2 17:36:52 jdoe systemd-logind[456]: New session 1 of user pi.
May 2 17:36:52 jdoe systemd: pam_unix(systemd-user:session): session opened for user pi(uid=1000) by (uid=0)
May 2 17:37:11 jdoe sshd[879]: Connection closed by 192.168.2.1 port 50356 [preauth]
Aug 20 10:22:07 jdoe sshd[892]: Invalid user pc from 192.168.2.1 port 50357
Aug 20 10:22:09 jdoe sshd[892]: pam_unix(sshd:auth): check pass; user unknown
Aug 20 10:22:09 jdoe sshd[892]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.2.1
deamon.log (background processes – called daemons)
cat # Display the contents of a file to standard output
/var/log/daemon.log # Path to the daemon log file; contains messages from background services (daemons) on the system
(RPi) tail /var/log/daemon.log
Aug 20 10:37:33 jdoe sh[1950]: Ncat: Listening on :::4444
Aug 20 10:37:33 jdoe sh[1950]: Ncat: Listening on 0.0.0.0:4444
Aug 20 10:38:32 jdoe systemd[1]: session-3.scope: Succeeded.
Aug 20 10:38:32 jdoe systemd[1]: session-3.scope: Consumed 33.015s CPU time.
Aug 20 10:38:35 jdoe systemd[1]: Started Session 4 of user pi.
Aug 20 10:47:54 jdoe systemd[1]: Starting Discard unused blocks on filesystems from /etc/fstab...
Aug 20 10:47:56 jdoe fstrim[2113]: /: 113.9 GiB (122311024640 bytes) trimmed on /dev/mmcblk0p2
Aug 20 10:47:56 jdoe fstrim[2113]: /boot: 203.7 MiB (213555200 bytes) trimmed on /dev/mmcblk0p1
Aug 20 10:47:56 jdoe systemd[1]: fstrim.service: Succeeded.
Aug 20 10:47:56 jdoe systemd[1]: Finished Discard unused blocks on filesystems from /etc/fstab
syslog.log (Global logs)
head # Display the first part of a file (default: first 10 lines)
/var/log/syslog.log # Path to the system log file; contains general system messages, kernel logs, and service events
(RPi) head /var/log/syslog.log
May 2 17:36:45 jdoe kernel: [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083]
May 2 17:36:45 jdoe systemd-modules-load[147]: Failed to find module 'lp'
May 2 17:36:45 jdoe kernel: [ 0.000000] Linux version 6.1.21-v8+ (dom@buildbot) (aarch64-linux-gnu-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023
May 2 17:36:45 jdoe kernel: [ 0.000000] random: crng init done
May 2 17:36:45 jdoe kernel: [ 0.000000] Machine model: Raspberry Pi 4 Model B Rev 1.5
May 2 17:36:45 jdoe kernel: [ 0.000000] efi: UEFI not found.
May 2 17:36:45 jdoe kernel: [ 0.000000] Reserved memory: created CMA memory pool at 0x000000000ec00000, size 512 MiB
May 2 17:36:45 jdoe kernel: [ 0.000000] OF: reserved mem: initialized node linux,cma, compatible id shared-dma-pool
May 2 17:36:45 jdoe systemd-modules-load[147]: Failed to find module 'ppdev'
May 2 17:36:45 jdoe kernel: [ 0.000000] Zone ranges:
Sudoers
A file that is used to determine if a user has permission to run commands or not, the sudoers file location is /etc/sudoers
sudo # Run the following command with superuser (root) privileges
cat # Display the contents of a file to standard output
/etc/sudoers # Path to the sudoers configuration file; defines which users/groups can run commands with elevated (sudo) privileges
(RPi) sudo cat /etc/sudoers
# This file MUST be edited with the 'visudo' command as root.
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
# See the man page for details on how to write a sudoers file.
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
root ALL=(ALL:ALL) ALL
%sudo ALL=(ALL:ALL) ALL
pi ALL=(root) NOPASSWD: /usr/bin/vi
@includedir /etc/sudoers.d
Wifi Passwords
Wifi password are saved in /etc/NetworkManager/system-connections/???.nmconnection where ??? is the SSID (Name of the wireless network)
ls # List directory contents
-l # Long listing format: shows permissions, owner, group, size, and modification date
-a # Show all files, including hidden files (those starting with a dot)
/etc/NetworkManager/system-connections/ # Directory containing saved network connection profiles managed by NetworkManager
(RPi) ls -la /etc/NetworkManager/system-connections/
total 12
drwxr-xr-x 2 root root 4096 Aug 20 12:22 .
drwxr-xr-x 7 root root 4096 Feb 22 19:59 ..
-rw------- 1 root root 264 Aug 20 12:22 LINKSYS22.nmconnection
sudo # Run command as superuser (needed to access protected files)
cat # Risplay the contents of a file
/etc/NetworkManager/system-connections/ # Directory storing saved network connections
LINKSYS22.nmconnection # Specific network configuration file for the Wi-Fi named LINKSYS22
(RPi) sudo cat /etc/NetworkManager/system-connections/LINKSYS22.nmconnection
[connection]
id=LINKSYS22
uuid=230dcf1d-70cf-4c1d-824e-c37b4cb752dc
type=wifi
interface-name=wlp4s0
[wifi]
hidden=true
ssid=LINKSYS22
[wifi-security]
key-mgmt=wpa-psk
psk=9SP28RFH38JE
[ipv4]
method=auto
[ipv6]
addr-gen-mode=stable-privacy
method=auto
[proxy]
Passwords
The grep command can be used to find any file that has a specific pattern or string
grep # Search for text patterns in files
-R # Recursive; search in current directory and all subdirectories
-i # Case-insensitive search (matches Pass, pass, PASS, etc.)
-e # Specifies the pattern to search
“pass\|user” # Pattern matches lines containing either “pass” OR “user”
. # Search starting from the current directory
(RPi) grep -Rie "pass\|user" .
./.bashrc:# set variable identifying the chroot you work in (used in the prompt below)
./.hidden_p: password=S8NR9VAFY1RN0GKNP61M