NFsec Logo

Logujemy logowania i nie tylko cz.I – moduły PAM

27/01/2016 w Bezpieczeństwo Brak komentarzy.  (artykuł nr 505, ilość słów: 532)

Z

ałóżmy, że posiadamy centralny system logowania, który gromadzi różne dane z wszystkich naszych serwerów. Może być on oparty o komercyjne usługi typu Loggly, Logentries, DataDog lub własne rozwiązania, których sercem jest Elasticsearch, czy RethinkDB. Zależy nam na tym, aby każde normalne logowanie i to na uprzywilejowane konto root, czy to bezpośrednio na maszynę, czy to za pomocą sudo było przesyłane do naszego centrum danych. Dane te mogą posłużyć nie tylko jako ewidencja i kontrola osób, które mają prawo do tego typu działań, ale również umożliwia nam ich analizę i wykrywanie potencjalnych naruszeń bezpieczeństwa.

Jednym z modułów PAM (ang. Pluggable Authentication Modules) jest pam_exec(8), który umożliwia wywołanie zewnętrznego polecenia oraz wykorzystanie w nim zmiennych środowiskowych typu PAM_RHOST, PAM_RUSER, PAM_SERVICE, PAM_TTY, PAM_USER. Jak możemy się domyślić są to idealne zmienne, aby użyć je do uzyskania informacji o tym kto, gdzie i skąd zalogował się na maszynę oraz z jakiego użytkownika wykonywał polecenia administratora. Zacznijmy od stworzenia prostego skryptu w języku bash, który pozwoli nam w formacie json przesłać zdarzenie o logowaniu przez daemona SSH do naszej centrali logowań:

#!/bin/bash

if [ "$PAM_TYPE" != "close_session" ]; then
   message="{\"EventReceivedTime\":\"`date +'%Y-%m-%d %R:%S'`\", \"User\":\"$PAM_USER\",
             \"Remotehost\":\"$PAM_RHOST\", \"LoginHost\":\"$(hostname -f) ($(hostname -i))\",
             \"Service\":\"$PAM_SERVICE\"}"
  echo $message | logger -t CarnivoreSSH
fi

Skrypt zapisujemy w ścieżce /etc/ssh/carnivore.sh (z prawami chmod 650). Zakładam tutaj, że dodaliśmy nasz system do Loggly. Jednak może to być inny dowolny endpoint akceptujący wiadomości w formacie json. Kolejnym krokiem jest wyzwolenie skryptu z poziomu PAM. Do /etc/pam.d/sshd dodajemy linijkę:

session    optional     pam_exec.so seteuid /etc/ssh/carnivore.sh

Od teraz po każdym logowaniu użytkownika w centrum logowania trafi wiadomość (możemy ją odfiltrować za pomocą: syslog.appName:CarnivoreSSH logtype:”json”):

syslog:
severity: Notice
appName: CarnivoreSSH
timestamp: 2016-01-27T20:03:26.041619+01:00
facility: user-level messages
priority: 13
host: darkstar
json:
Service: sshd
Remotehost: 247.19.29.79.provider.isp.pl
LoginHost: darkstar.nfsec.pl (2001:42d0:b:28d9::1 192.168.1.1)
User: agresor
EventReceivedTime: 2016-01-27 20:03:26

Analogicznie możemy wyzwolić zdarzenie logowania, gdy ktoś spróbuje wykonać polecenie “sudo” lub “su“. Wystarczy, że skrypt /usr/local/sbin/carnivore.sh:

#!/bin/bash

if [ "$PAM_TYPE" != "close_session" ]; then
   message="{\"EventReceivedTime\":\"`date +'%Y-%m-%d %R:%S'`\", \"User\":\"$PAM_RUSER\",
             \"Host\":\"$(hostname -f) ($(hostname -i))\",
             \"Action\":\"$PAM_SERVICE\", \"TTY\":\"$PAM_TTY\"}"
   echo $message | logger -t CarnivoreSUDO
fi

Dodamy do /etc/pam.d/sudo lub /etc/pam.d/su:

session    optional     pam_exec.so seteuid /usr/local/sbin/carnivore.sh

Zdarzenie będzie miało wówczas formę:

syslog:
severity: Notice
appName: CarnivoreSUDO
timestamp: 2016-01-27T21:26:13.967908+01:00
facility: user-level messages
priority: 13
host: darkstar
json:
Action: sudo
TTY: /dev/pts/3
EventReceivedTime: 2016-01-27 21:26:13
Host: darkstar.nfsec.pl (2001:42d0:b:28d9::1 192.168.1.1)
User: agresor

Za pomocą $PAM_TYPE jesteśmy w stanie też sterować opuszczeniem stanu zalogowania lub uprzywilejowanego trybu. Tak zebrane wiadomości możemy poddawać dalszej analizie i ustawić odpowiednie alarmowanie w przypadku wystąpienia anomalii lub interesujących nas zdarzeń. Możemy też przechowywać je w zabezpieczonej i zarchiwizowanej formie w przypadku wystąpienia audytu, który wymagać będzie od nas tego typu informacji.

Więcej informacji: Login notifications, pam_exec scripting, Posting successful SSH logins to Slack

Kategorie K a t e g o r i e : Bezpieczeństwo

Tagi T a g i : , , , , , , , ,

Komentowanie tego wpisu jest zablokowane.