Forensics w systemie Linux — jak odczytać ślady włamań
Analiza cyfrowa Linux

Forensics w systemie Linux — jak odczytać ślady włamań

Forensics w systemie Linux — jak odczytać ślady włamań

Poniżej znajdziesz praktyczny, krok‑po‑kroku przewodnik po analizie incydentów (DFIR) na systemach Linux — od przygotowania i zbierania dowodów, przez analizę dysku i pamięci, aż po korelację wydarzeń i raportowanie. Skupiłem się na technikach i narzędziach używanych przez analityków (SleuthKit, dd/dcfldd/dc3dd, auditd, LiME/Volatility, journalctl itp.) oraz na przykładach komend — wszystko w kontekście odzyskiwania śladów włamania, zachowując zasady zachowania dowodów.


1. Zasady wstępne — legalność, bezpieczeństwo, notacja

  1. Legalność i uprawnienia — upewnij się, że masz prawo do wykonywania analiz (zgoda właściciela, polecenie przełożonego, procedury prawne).
  2. Zachowaj nienaruszalność dowodów — wykonuj działania kopiujące; nie pracuj bezpośrednio na systemie produkcyjnym, jeśli chcesz zachować oryginały.
  3. Dokumentuj wszystko — daty, osoby wykonujące działania, polecenia, sumy kontrolne, nośniki, czas i sposób zdobycia obrazu. To podstawa łańcucha dowodowego (chain of custody).

2. Co zebrać najpierw — volatile vs non‑volatile

  • Volatile (ulotne): pamięć RAM, aktywne procesy, otwarte połączenia sieciowe, tablice ARP/conntrack, zawartość cache, login sessions. Musisz je złapać przed rebootem.
  • Non‑volatile: obrazy dysków/partycji, pliki logów, konfiguracje (/etc), konta użytkowników, pliki w home, pliki cron, binaria.

Zasada: najpierw zrób zrzut pamięci, potem obraz dysku.

Forensics w systemie Linux — jak odczytać ślady włamań
Forensics w systemie Linux — jak odczytać ślady włamań

3. Zrzut pamięci (memory acquisition)

Dlaczego: w pamięci znajdziesz procesy, połączenia sieciowe, zaszyfrowane klucze, shell history w RAM, in‑memory malware.
Narzędzia popularne: LiME, AVML, Volatility 3 (do analizy). Przykładowy workflow: podmontuj moduł LiME i wykonaj dump pamięci na zdalny serwer lub nośnik.

Przykład (LiME):

# na maszynie ofiary: skompilowany moduł lime.ko
insmod lime.ko "path=/mnt/usb/memdump.lime format=lime"
# albo zrzut do stdout -> nc (ostrożnie, zabezpiecz)

Po przechwyceniu użyj Volatility 3 lub Volatility 2 z profilem dla jądra/architektury do ekstrakcji procesów, socketów, modułów, haszy i haseł w pamięci.


4. Tworzenie obrazu dysku (forensic imaging)

Narzędzia: dd, dcfldd, dc3dd, ewfacquire (dla E01) — wybierz narzędzie które wspiera haszowanie i zapis w bezpiecznym formacie. Ważne: używaj conv=sync,noerror lub narzędzi z wbudowanym hashowaniem. Zapisuj sumy kontrolne (MD5/SHA256).

Przykład:

# prosty obraz z dd (nie zapominaj o hashu)
sudo dd if=/dev/sdb of=/evidence/image.dd bs=4M conv=sync,noerror status=progress
sha256sum /evidence/image.dd > /evidence/image.dd.sha256

Lepiej: dcfldd lub dc3dd mają opcje tworzenia hashów w trakcie tworzenia obrazu.


5. Analiza systemu plików i timeline (SleuthKit, fls, mactime)

The Sleuth Kit (TSK) oferuje narzędzia do przeglądania obrazu dysku bez modyfikacji — fls, icat, ils, ffind. Na ich podstawie można wygenerować timeline (pliki z odczytami MAC times — Modified, Accessed, Changed) i przejrzeć zmiany plików w czasie przy pomocy mactime. To pomaga odtworzyć chronologię działań atakującego.

Przykład:

fls -r -m / image.dd > fls_output.txt
mactime -b fls_output.txt > timeline.txt

Szukaj: nagłych tworzeń/usunięć plików, nietypowych timestampów, modyfikacji plików binarnych, założonych backdoorów.


6. Logi systemowe — gdzie szukać i jak czytać

Najważniejsze lokalizacje i polecenia:

  • /var/log/auth.log (Debian/Ubuntu) lub /var/log/secure (RHEL/CentOS) — logi logowania, sudo, błędne hasła.
  • journalctl — systemd‑journal: pozwala przeglądać dzienniki, filtrować po bootach, usługach, PID. Możesz eksportować pliki journal i analizować offline.
  • /var/log/syslog, /var/log/messages — ogólne wydarzenia systemowe.
  • wtmp/utmp — narzędzia last, who pokazują sesje.
  • /var/log/faillog, /var/log/btmp — nieudane próby logowania.
Czytaj  Programowanie sterowników urządzeń w Linuksie: Jak tworzyć sterowniki dla niestandardowych urządzeń peryferyjnych

Przykłady:

# ostatnie logowania
last -a

# przegląd journal od czasu określonego
journalctl --since "2025-09-15 08:00" --until "2025-09-16 08:00"

# eksport journal do pliku (do analizy offline)
journalctl --utc --output=short-iso > /evidence/journal.txt

Szukaj: nietypowych godzin logowań, powtarzających się nieudanych prób, sudo bez kontekstu, uruchomienia shelli z netcat/ reverse shell, zmiany uprawnień.


7. Auditd i monitoring aktywności systemowej

auditd to system audytu jądra — jeśli był aktywny, da bardzo szczegółowy zapis uruchomień plików, execve, zmian uprawnień, otwarć plików itp. Jeśli nie był skonfigurowany przed incydentem, rozważ jego włączenie do dalszej detekcji. Elastic Security i wielu autorów zalecają auditd jako źródło detekcji.

Podstawowe polecenia:

ausearch -m EXECVE --start recent-date --end recent-date
aureport --summary

8. Procesy, otwarte pliki i połączenia sieciowe

Na żywym systemie:

  • ps auxf, top/htop — procesy; szukaj obcych nazw, procesów uruchomionych z nietypowych ścieżek.
  • lsof -i -Pn — otwarte gniazda sieciowe.
  • ss -tulpn lub netstat -tulpen — nasłuchujące porty i powiązane PIDy.
  • chkconfig --list / systemctl list-units --type=service — usługi systemowe; sprawdź nowe lub podejrzane jednostki systemd.

Szukaj: procesów z nazwami maskującymi (np. systemd z dziwnym PID/ścieżką), otwartych połączeń do egzotycznych adresów, nietypowych nasłuchujących portów.


9. Hakerzy zostawiają artefakty konfiguracji — gdzie patrzeć

  • /etc/passwd, /etc/shadow — nowe konta, nietypowe UID (0).
  • ~/.ssh/authorized_keys — dodane klucze publiczne.
  • /etc/cron.* i crontab -l — zaplanowane zadania (backdoory).
  • /etc/systemd/system/ — niestandardowe usługi (możliwy autostart backdoorów).
  • SUID/SGID pliki: find / -perm /6000 -type f -ls — mogą być wykorzystane do eskalacji.
  • Modyfikacje binariów: porównaj sumy kontrolne z zaufanym repozytorium lub sprawdź daty modyfikacji binarek systemowych.

10. Rootkit i skanery integralności

  • Narzędzia: rkhunter, chkrootkit (szybkie sprawdzenie), AIDE, tripwire (monitoring integralności). Nie polegaj wyłącznie na nich — rootkity kernelowe mogą ukrywać wpisy.
  • Porównuj sumy kontrolne plików systemowych z czystą instalacją lub repo.

11. Analiza sieci i artefakty ruchu

  • Zrzuty pakietów (pcap) jeśli dostępne — tcpdump -w na podejrzanych interfejsach.
  • iptables -L -n -v, conntrack -L — zapisy połączeń i reguły.
  • Logi serwerów (nginx, apache) w /var/log — sprawdź nieautoryzowane uploady, wykorzystania luk (webshell).

12. Korelacja i timeline — jak połączyć wszystko

Po zebraniu: połącz timeline z pamięci (procesy + sockets), timeline plików (mactime), oraz wpisów z journalctl i /var/log/auth.log. Celem jest ustalenie sekwencji: wejście -> eskalacja -> działania -> exfiltration / persistence. Narzędzia takie jak mactime, SIEM (Elastic, Splunk) lub prosty skrypt do łączenia zdarzeń pomogą w korelacji.


13. Przykładowe „czerwone flagi” (co może wskazywać na włamanie)

  • Nowe konto root lub konto z UID 0.
  • Nowe klucze SSH w authorized_keys.
  • Nietypowe cron wpisy.
  • Niezwykłe pliki SUID/SGID lub zmienione binaria.
  • Procesy uruchomione z /tmp, /var/tmp lub z katalogów domowych.
  • Połączenia sieciowe do podejrzanych IP lub szyfrowanych kanałów w niestandardowych portach.
  • Usługi systemd o nietypowych nazwach.

14. Raportowanie i działania po incydencie

  1. Zachowaj kopie dowodów (obrazy dysków, pamięć, logi).
  2. Przywróć system z zaufanej kopii (reinstall), nie używaj naprawczych „łatek” na zainfekowanym systemie.
  3. Zgłoś incydent — wewnętrzne procedury, prawne, CERT, jeśli wymagane.
  4. Wnioski i wzmocnienia — wdrożenia monitoringu (auditd, OSSEC, EDR), rotacja kluczy/hasel, poprawa zasad dostępu i backupów.

15. Krótkie podsumowanie poleceń (cheat‑sheet)

# zrzut pamięci (LiME) - przykładowo
insmod lime.ko "path=/mnt/usb/memdump.lime format=lime"

# obraz dysku
sudo dc3dd if=/dev/sdb of=/evidence/image.dd hash=sha256

# timeline (TSK)
fls -r -m / image.dd > fls.txt
mactime -b fls.txt > timeline.txt

# przeglądanie journal
journalctl --since "2025-09-20" --until "2025-09-21" --output=short-iso > journal.txt

# procesy / sieć
ps auxf
lsof -i -Pn
ss -tulpn

# szukanie podejrzanych SUID
find / -perm /6000 -type f -ls

Źródła i dalsza literatura

Dla pogłębienia: dokumentacja Sleuth Kit, artykuły o auditd, poradniki o zrzucie pamięci LiME/AVML oraz przewodniki po tworzeniu obrazów dysków (dd, dcfldd, dc3dd). Poniżej kilka istotnych odnośników, których użyłem przygotowując ten przewodnik.

 

Gotowe — przygotowałem skrypt automatycznego zbierania dowodów.

 

#!/usr/bin/env bash
# forensic_collection_script.sh
# Skrypt do automatycznego zbierania dowodów (Linux)
# UWAGA: używaj tylko jeśli masz odpowiednie uprawnienia i zgodę. Zapisz kopię oryginalną i dokumentuj łańcuch dowodowy.
# Zapisuje zrzut pamięci (jeśli dostępny), listę procesów, otwarte pliki, połączenia sieciowe, logi systemowe, klucze SSH, cron, informacje o systemie
# generuje sumy kontrolne i manifest. Kompresuje pakiet dowodowy na końcu.

Czytaj  Bezpieczeństwo systemów: Windows vs Linux vs Android

set -euo pipefail
IFS=$’\n\t’

TIMESTAMP=$(date -u +%Y%m%dT%H%M%SZ)
HOST=$(hostname -s)
OUTDIR=”/tmp/evidence_${HOST}_${TIMESTAMP}”
mkdir -p „$OUTDIR”
LOGFILE=”$OUTDIR/collector.log”
exec > >(tee -a „$LOGFILE”) 2>&1

manifest_file=”$OUTDIR/manifest.txt”
echo „Forensic collection – host: $HOST – started: $TIMESTAMP (UTC)” | tee -a „$manifest_file”

# Helper: run a command and record it in manifest
run_cmd() {
echo „[CMD] $*” | tee -a „$manifest_file”
„$@”
}

hash_file() {
if command -v sha256sum >/dev/null 2>&1; then
sha256sum „$1” | tee -a „$manifest_file”
elif command -v shasum >/dev/null 2>&1; then
shasum -a 256 „$1” | tee -a „$manifest_file”
else
echo „No sha256 utility found” | tee -a „$manifest_file”
fi
}

# 1) Check for required privileges
if [ „$EUID” -ne 0 ]; then
echo „Warning: skrypt najlepiej uruchomić jako root (sudo). Kontynuuję, ale niektóre zbiory mogą się nie udać.” | tee -a „$manifest_file”
fi

# 2) Collect volatile data: memory (try AVML -> LiME), processes, network, lsof
collect_memory() {
echo „\n== memoriaz collection ==” | tee -a „$manifest_file”
if command -v avml >/dev/null 2>&1; then
echo „Found AVML, creating memory dump via avml…” | tee -a „$manifest_file”
out=”$OUTDIR/memdump_avml_${TIMESTAMP}.lime”
avml -z „$out” && hash_file „$out” || echo „avml failed” | tee -a „$manifest_file”
elif [ -f „/usr/local/bin/lime.ko” ] || [ -f „./lime.ko” ]; then
echo „LiME kernel module found locally, attempting insmod…” | tee -a „$manifest_file”
# user must ensure lime.ko is compatible with kernel
modfile=”./lime.ko”
if [ -f „/usr/local/bin/lime.ko” ]; then modfile=”/usr/local/bin/lime.ko”; fi
out=”$OUTDIR/memdump_lime_${TIMESTAMP}.lime”
echo „Attempting: insmod $modfile path=$out format=lime” | tee -a „$manifest_file”
if insmod „$modfile” „path=$out” „format=lime” 2>/dev/null; then
echo „LiME insmod OK” | tee -a „$manifest_file”
hash_file „$out” || true
else
echo „LiME insmod failed (kernel mismatch?). Skipping memory dump.” | tee -a „$manifest_file”
fi
else
echo „No memory acquisition tool (avml or LiME) found. Skipping memory dump.” | tee -a „$manifest_file”
fi
}

collect_processes_network() {
echo „\n== processes and network ==” | tee -a „$manifest_file”
ps auxwwf > „$OUTDIR/processes.ps.txt” || true
hash_file „$OUTDIR/processes.ps.txt”

ss -tulpen > „$OUTDIR/ss_tulpen.txt” 2>/dev/null || netstat -tulpen > „$OUTDIR/netstat_tulpen.txt” || true
[ -f „$OUTDIR/ss_tulpen.txt” ] && hash_file „$OUTDIR/ss_tulpen.txt”
[ -f „$OUTDIR/netstat_tulpen.txt” ] && hash_file „$OUTDIR/netstat_tulpen.txt”

lsof -i -Pn > „$OUTDIR/lsof_i.txt” 2>/dev/null || true
hash_file „$OUTDIR/lsof_i.txt” || true

# active TCP connections
ss -tna > „$OUTDIR/ss_tna.txt” || true
hash_file „$OUTDIR/ss_tna.txt” || true
}

collect_logs_and_journal() {
echo „\n== logs and journal ==” | tee -a „$manifest_file”
# journalctl export
if command -v journalctl >/dev/null 2>&1; then
journalctl –utc –output=short-iso > „$OUTDIR/journal.txt” 2>/dev/null || true
hash_file „$OUTDIR/journal.txt” || true
fi

# typical log files
for f in /var/log/auth.log /var/log/secure /var/log/syslog /var/log/messages; do
if [ -f „$f” ]; then
cp –preserve=timestamps „$f” „$OUTDIR/” || true
hash_file „$OUTDIR/$(basename $f)” || true
fi
done

# web server logs (if any)
for dir in /var/log/nginx /var/log/apache2 /var/log/httpd; do
if [ -d „$dir” ]; then
mkdir -p „$OUTDIR/$(basename $dir)”
cp -a „$dir”/* „$OUTDIR/$(basename $dir)/” 2>/dev/null || true
# hash files
find „$OUTDIR/$(basename $dir)” -type f -print0 | xargs -0 -r sha256sum >> „$manifest_file” 2>/dev/null || true
fi
done
}

collect_files_and_config() {
echo „\n== files and configuration ==” | tee -a „$manifest_file”
# passwd / shadow (copy only accessible by root)
cp –preserve=timestamps /etc/passwd „$OUTDIR/” 2>/dev/null || true
cp –preserve=timestamps /etc/group „$OUTDIR/” 2>/dev/null || true
if [ -f /etc/shadow ]; then cp –preserve=timestamps /etc/shadow „$OUTDIR/” 2>/dev/null || true; fi
hash_file „$OUTDIR/passwd” || true

# ssh keys
find /root /home -maxdepth 3 -type f -name authorized_keys -print0 2>/dev/null | xargs -0 -r -I{} bash -c 'cp –preserve=timestamps „{}” „$OUTDIR/” && echo „copied {}” >> „$manifest_file”’ || true

# cron
crontab -l > „$OUTDIR/crontab_root.txt” 2>/dev/null || true
hash_file „$OUTDIR/crontab_root.txt” || true
cp -a /etc/cron.* „$OUTDIR/cron_dirs” 2>/dev/null || true

Czytaj  Konfiguracja sieci w Ubuntu – Kompletny przewodnik

# systemd units (custom)
mkdir -p „$OUTDIR/systemd_units”
cp -a /etc/systemd/system/* „$OUTDIR/systemd_units/” 2>/dev/null || true
find „$OUTDIR/systemd_units” -type f -print0 | xargs -0 -r sha256sum >> „$manifest_file” 2>/dev/null || true

# SUID files list
find / -perm /6000 -type f -ls > „$OUTDIR/suid_files.txt” 2>/dev/null || true
hash_file „$OUTDIR/suid_files.txt” || true
}

collect_disk_image_optional() {
# Optional: create raw image if IMAGING_DEVICE env var set (e.g. IMAGING_DEVICE=/dev/sda)
if [ -n „${IMAGING_DEVICE:-}” ]; then
device=”$IMAGING_DEVICE”
out=”$OUTDIR/disk_image_${HOST}_${TIMESTAMP}.dd”
echo „\n== Disk imaging requested ($device) ==” | tee -a „$manifest_file”
if command -v dc3dd >/dev/null 2>&1; then
echo „Using dc3dd to image $device -> $out” | tee -a „$manifest_file”
dc3dd if=”$device” of=”$out” hash=sha256 || echo „dc3dd failed” | tee -a „$manifest_file”
hash_file „$out” || true
elif command -v dcfldd >/dev/null 2>&1; then
echo „Using dcfldd to image $device -> $out” | tee -a „$manifest_file”
dcfldd if=”$device” of=”$out” hash=sha256 || echo „dcfldd failed” | tee -a „$manifest_file”
hash_file „$out” || true
else
echo „No forensically-aware imaging tool found (dc3dd/dcfldd). Falling back to dd (not recommended).” | tee -a „$manifest_file”
dd if=”$device” of=”$out” bs=4M conv=sync,noerror status=progress || true
hash_file „$out” || true
fi
fi
}

collect_network_packets_optional() {
# Optional: capture short network trace if CAPTURE_IF env var set (e.g. CAPTURE_IF=eth0)
if [ -n „${CAPTURE_IF:-}” ]; then
iface=”$CAPTURE_IF”
out=”$OUTDIR/pcap_${iface}_${TIMESTAMP}.pcap”
echo „Capturing 120 seconds of traffic on $iface to $out” | tee -a „$manifest_file”
timeout 120 tcpdump -n -i „$iface” -w „$out” || true
hash_file „$out” || true
fi
}

collect_system_info() {
echo „\n== system info ==” | tee -a „$manifest_file”
uname -a > „$OUTDIR/uname.txt” || true; hash_file „$OUTDIR/uname.txt” || true
lsb_release -a > „$OUTDIR/lsb_release.txt” 2>/dev/null || true; hash_file „$OUTDIR/lsb_release.txt” || true
dmesg –ctime > „$OUTDIR/dmesg.txt” 2>/dev/null || true; hash_file „$OUTDIR/dmesg.txt” || true
ip addr show > „$OUTDIR/ip_addr.txt” 2>/dev/null || true; hash_file „$OUTDIR/ip_addr.txt” || true
df -h > „$OUTDIR/df_h.txt” 2>/dev/null || true; hash_file „$OUTDIR/df_h.txt” || true
}

# Run collectors
collect_memory
collect_processes_network
collect_logs_and_journal
collect_files_and_config
collect_system_info
collect_disk_image_optional
collect_network_packets_optional

# Finalize: list files, compute full archive hash, compress
echo „\n== Finalizing ==” | tee -a „$manifest_file”
find „$OUTDIR” -type f -print0 | xargs -0 -r sha256sum >> „$manifest_file” 2>/dev/null || true

archive=”${OUTDIR}.tar.gz”
# Use –no-overwrite-dir to be safe; preserve timestamps
tar -czf „$archive” -C „$(dirname „$OUTDIR”)” „$(basename „$OUTDIR”)” || true
if [ -f „$archive” ]; then
echo „Archive created: $archive” | tee -a „$manifest_file”
hash_file „$archive”
fi

echo „Collection finished. Evidence directory: $OUTDIR” | tee -a „$manifest_file”

echo „Na koniec: upewnij się, że kopia została przeniesiona na bezpieczny, write-once nośnik i zanotuj łańcuch dowodowy.” | tee -a „$manifest_file”

# exit
exit 0

 

Co zawiera i jak go użyć (krótkie instrukcje):

  • Skrypt zbiera (w zależności od dostępności narzędzi): zrzut pamięci (AVML/LiME), listę procesów, otwarte pliki, połączenia sieciowe, eksport journalctl, typowe pliki z /var/log, kopie /etc/passwd, /etc/shadow (jeśli dostępne), authorized_keys, wpisy cron, jednostki systemd, listę plików SUID i inne informacje diagnostyczne.
  • Tworzy katalog dowodowy w /tmp/evidence_<host>_<timestamp>/, generuje manifest z poleceniami i sumami kontrolnymi SHA‑256, a na końcu kompresuje katalog do archiwum .tar.gz i hashuje je.
  • Opcjonalne: utworzenie obrazu dysku jeśli ustawisz zmienną środowiskową IMAGING_DEVICE=/dev/sdX przed uruchomieniem; krótkie przechwycenie ruchu jeśli ustawisz CAPTURE_IF=eth0.
  • Uruchomienie: zapisz plik i nadaj prawa wykonywalne, np. chmod +x forensic_collection_script.sh i uruchom sudo ./forensic_collection_script.sh. Jeśli chcesz imaging dysku: sudo IMAGING_DEVICE=/dev/sda ./forensic_collection_script.sh.
  • Ważne: uruchamiaj tylko gdy masz uprawnienia i zgodę. Zbieranie może wpływać na system (szczególnie imaging i insmod LiME). Dokumentuj łańcuch dowodowy i przechowuj archiwa na bezpiecznym nośniku.

Jeśli chcesz, mogę:

  • zmodyfikować skrypt pod twoją dystrybucję (Debian/Ubuntu vs RHEL/CentOS) — od razu naniosę poprawki,
  • dodać eksport do zdalnego serwera (np. z użyciem nc/scp) z uwzględnieniem szyfrowania,
  • albo wygenerować wersję systemd/Ansible playbook do automatycznego uruchamiania na wielu hostach.

Którą opcję wybierasz?

Polecane wpisy
Jak sprawdzić parametry podzespołów Linux
Jak sprawdzić parametry podzespołów Linux

Aby sprawdzić parametry podzespołów w systemie Linux, można skorzystać z różnych poleceń i narzędzi. Oto kilka sposobów: [caption id="attachment_6954" align="aligncenter" Czytaj dalej

Tunelowanie SSH: Jak to zrobić?
Tunelowanie SSH: Jak to zrobić?

Tunelowanie SSH: Jak to zrobić? Tunelowanie SSH to potężna technika, która pozwala na bezpieczne przesyłanie danych przez niezabezpieczone sieci. Umożliwia Czytaj dalej

Marek "Netbe" Lampart Inżynier informatyki Marek Lampart to doświadczony inżynier informatyki z ponad 25-letnim stażem w zawodzie. Specjalizuje się w systemach Windows i Linux, bezpieczeństwie IT, cyberbezpieczeństwie, administracji serwerami oraz diagnostyce i optymalizacji systemów. Na netbe.pl publikuje praktyczne poradniki, analizy i instrukcje krok po kroku, pomagając administratorom, specjalistom IT oraz zaawansowanym użytkownikom rozwiązywać realne problemy techniczne.