Linux: Malware Scanner
Anleitung zum Einsatz von ClamAV mit zusätzlichen Signatur-Datenbanken von Linux Malware Detect (GitHub) und Sanesecurity.
ClamAV
Installation
sudo aptitude install clamav clamav-daemon
Anpassungen
systemd
- /etc/clamav/clamd.conf
PidFile /run/clamav/clamd.pid
sudo systemctl stop clamav-daemon.service sudo rmdir /run/clamav sudo cp /lib/systemd/system/clamav-daemon.service /etc/systemd/system/ sudo systemctl daemon-reload
- /etc/systemd/system/clamav-daemon.socket
[Unit] Description=Clam AntiVirus Socket ConditionPathExistsGlob=/var/lib/clamav/main.{c[vl]d,inc} ConditionPathExistsGlob=/var/lib/clamav/daily.{c[vl]d,inc} [Socket] ListenStream=/run/clamav/clamd.ctl SocketUser=clamav SocketGroup=clamav RemoveOnStop=false [Install] WantedBy=sockets.target
- /etc/systemd/system/clamav-daemon.service
[Unit] Description=Clam AntiVirus Daemon After=local-fs.target Requires=clamav-daemon.socket ConditionPathExistsGlob=/var/lib/clamav/main.{c[vl]d,inc} ConditionPathExistsGlob=/var/lib/clamav/daily.{c[vl]d,inc} [Service] Type=simple User=clamav RuntimeDirectory=clamav PIDFile=/run/clamav/clamd.pid PermissionsStartOnly=true ExecStart=/usr/sbin/clamd -c /etc/clamav/clamd.conf --foreground=true ExecReload=/bin/kill -USR2 $MAINPID ExecStop=/bin/kill -TERM $MAINPID Restart=on-failure RestartSec=10s StandardError=null StandardOutput=syslog RestrictAddressFamilies=AF_INET AF_UNIX RestrictRealtime=true RestrictNamespaces=true PrivateTmp=true PrivateDevices=true PrivateUsers=true ProtectHome=true ProtectKernelModules=true ProtectKernelTunables=true ProtectSystem=strict ProtectControlGroups=true MemoryDenyWriteExecute=true RemoveIPC=false InaccessiblePaths=/boot /root ReadWritePaths=/var/lib/clamav /var/log/clamav NoNewPrivileges=true CapabilityBoundingSet=CAP_SETUID CAP_SETGID CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH SystemCallArchitectures=x86-64 SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @privileged @raw-io ptrace [Install] WantedBy=multi-user.target Also=clamav-daemon.socket
sudo systemctl start clamav-daemon.service
AppArmor
ClamAV funktioniert mit AppArmor nicht einwandfrei.
sudo ln -s /etc/apparmor.d/usr.sbin.clamd /etc/apparmor.d/disable/usr.sbin.clamd sudo ln -s /etc/apparmor.d/usr.bin.freshclam /etc/apparmor.d/disable/usr.bin.freshclam
Download von Signatur-Datenbanken
Damit auch die Signaturen des Google Safebrowsing Dienstes verwendet werden, muss die /etc/clamav/freshclam.conf um die entsprechende Option ergänzt werden. Wer den Download der Signatur-Datenbanken über einen Proxy leiten lassen will, ergänzt die entsprechenden Optionen. Außerdem sollte man einen lokal gelegenen Mirror bevorzugen.
- /etc/clamav/freshclam.conf
SafeBrowsing yes DatabaseMirror db.de.clamav.net HTTPProxyServer host.domain.tld HTTPProxyPort port
Zusätzliche Signatur-Datenbanken
Neben den Signaturen von ClamAV kann man zusätzliche (nicht offizielle) Signaturen von Linux Malware Detect und Sanesecurity einbinden. Wer die Signatur-Datenbanken einbindet, kann die obige systemd Unit-Datei ergänzen, um die Ausgabe von Fehler- und Warnmeldungen zu unterdrücken, die sich aufgrund mit ClamAV inkompatibler Inhalte in den Datenbanken ergeben können. Läuft der clamd Daemon mal nicht, kann man temporär die Ergänzung zwecks Fehlersuche wieder auskommentieren und/oder/bzw. die OfficialDatabaseOnly false Option in der /etc/clamav/clamd.conf Datei setzen.
- /etc/systemd/system/clamav-daemon.service
[Service] StandardError=null
Download, Aktualisierung und Einpflegen der Datenbanken kann man über Skripte durchführen. Als Debian-Paket ist clamav-unofficial-sigs verfügbar:
sudo aptitude install clamav-unofficial-sigs
Ein darauf basierendes und weiter gepflegtes Skript ist das gleichnamige clamav-unofficial-sigs Skript von eXtremeSHOK.
Alternativ kann man das folgende clamav-3dparty-update Skript verwenden, das etwas einfacher gehalten ist und Signatur-Datenbanken von LMD und Sanesecurity (mit niedriger und mittlerer False Positives Rate) herunterlädt und aktualisiert. Für das Skript werden GnuPG 2
, git
, rsync
und curl
benötigt. Die Downloads werden über den Proxy weitergeleitet, der in der RSYNC_PROXY Variable steht (hier: Privoxy → Tor). Wer keinen Proxy verwendet, muss die Variable auskommentieren und die Aufrufe von curl und git im Skript entsprechend ändern:
# RSYNC_PROXY="host.domain.tld:port" # export RSYNC_PROXY --proxy $RSYNC_PROXY für curl entfernen -c http.proxy=$RSYNC_PROXY für git entfernen
Vor dem ersten Start wird git
installiert – die anderen genannten Anwendungen müssten bereits automatisch installiert worden sein – und die Verzeichnisstruktur angelegt:
sudo aptitude install git sudo mkdir -p /var/lib/clamav-3dparty/{lmd/tmp,sanesecurity/gpg,sanesecurity-bad,yararules,yararules-bad} sudo chmod 700 /var/lib/clamav-3dparty/sanesecurity/gpg sudo chown -R clamav:clamav /var/lib/clamav-3dparty/
- /usr/local/bin/clamav-3dparty-update
#!/bin/sh ################################################################ # Script to download and update additional Sanesecurity and LMD # signatures for ClamAV # V. 1.1 # Copyright 2018 K. Raven <kraven@secure.mailbox.org> # License: BSD-2-Clause License # <https://opensource.org/licenses/bsd-license.php> ################################################################ clamdb_dir="/var/lib/clamav" dbs_dir="/var/lib/clamav-3dparty" ss_dir="$dbs_dir/sanesecurity" ss_gpg_dir="$ss_dir/gpg" ss_dblist="$ss_dir/ss-rsync" ss_url="rsync.sanesecurity.net" ss_mirror_ips="$(dig +ignore +short "$ss_url")" ss_gpg_url="http://www.sanesecurity.net/publickey.gpg" lmd_base_url="https://cdn.rfxn.com/downloads" lmd_sigver_file="maldet.sigs.ver" lmd_sigver_url="$lmd_base_url/$lmd_sigver_file" lmd_sig_file="maldet-sigpack.tgz" lmd_sig_url="$lmd_base_url/$lmd_sig_file" lmd_dir="$dbs_dir/lmd" lmd_dir_tmp="$lmd_dir/tmp" RSYNC_PROXY="sub.domain.tld:8118" export RSYNC_PROXY curl="curl --silent --connect-timeout 60 --retry 3 --location --remote-name" if [ -z "$ss_mirror_ips" ] ; then ss_mirror_ips=$(host -t A "$ss_url" | sed -n '/has address/{s/.*address \([^ ]*\).*/\1/;p;}') fi trap "rm $ss_dblist $ss_dir/mirror_ips" EXIT for i in $ss_mirror_ips; do if [ "$(ping -c 1 -n -q $i >/dev/null ; echo $?)" = "0" ]; then echo "$i" >> $ss_dir/mirror_ips fi done ss_mirror_ip="$(cat $ss_dir/mirror_ips | shuf -n1)" if [ ! -f $ss_gpg_dir/pubring.kbx ]; then cd $ss_gpg_dir && \ $curl --proxy $RSYNC_PROXY $ss_gpg_url -o publickey.gpg && \ gpg -q --no-options --no-default-keyring --homedir $ss_gpg_dir --keyring $ss_gpg_dir/pubring.kbx --import $ss_gpg_dir/publickey.gpg fi sleep 3 # Sanesecurity signatures # low+med fp risk dbs # http://sanesecurity.com/usage/signatures/ # list dbs: # rsync --list-only "rsync://$ss_mirror_ip/sanesecurity" ss_dbs=" junk.ndb jurlbl.ndb jurlbla.ndb lott.ndb phish.ndb rogue.hdb sanesecurity.ftm sigwhitelist.ign2 scam.ndb spam.ldb spamimg.hdb spamattach.hdb spear.ndb spearl.ndb blurl.ndb foxhole_generic.cdb foxhole_filename.cdb foxhole_js.ndb malwarehash.hsb hackingteam.hsb badmacro.ndb shelter.ldb winnow_malware.hdb winnow_malware_links.ndb winnow_spam_complete.ndb winnow_phish_complete_url.ndb winnow.complex.patterns.ldb winnow_extended_malware.hdb winnow_extended_malware_links.ndb winnow.attachments.hdb winnow_bad_cw.hdb MiscreantPunch099-Low.ldb scamnailer.ndb bofhland_cracked_URL.ndb bofhland_malware_URL.ndb bofhland_phishing_URL.ndb bofhland_malware_attach.hdb phishtank.ndb" for db in $ss_dbs ; do echo "$db" >> "$ss_dblist" echo "$db.sig" >> "$ss_dblist" done rsync --quiet --no-motd --contimeout=60 --files-from="$ss_dblist" --timeout=60 "rsync://$ss_mirror_ip/sanesecurity" $ss_dir/ 2>/dev/null cd $ss_dir/ && \ for db in $ss_dbs ; do chmod 640 "$db"* status="$(gpg --no-options --trust-model always --no-default-keyring --homedir $ss_gpg_dir/ --keyring $ss_gpg_dir/pubring.kbx -q --no-tty --no-verbose --status-fd 1 --verify "$db".sig 2>/dev/null | egrep "^\[GNUPG:\] VALIDSIG" | cut -d\ -f 2)" ; \ dbtest="$(clamscan --quiet --stdout -d "$db" 2>/dev/null | egrep "^ERROR: Malformed database")" if [ "$status" = "VALIDSIG" -a "$dbtest" != "ERROR: Malformed database" ] ; then cp -f "$db" $clamdb_dir/ else ln -s $ss_dir/"$db" $dbs_dir/sanesecurity-bad/ 2>/dev/null ; ln -s $ss_dir/"$db".sig $dbs_dir/sanesecurity-bad/ 2>/dev/null fi done # LMD signatures cd $lmd_dir_tmp $curl --proxy $RSYNC_PROXY $lmd_sigver_url if [ -f "$lmd_dir/$lmd_sigver_file" -a -f "$lmd_dir_tmp/$lmd_sigver_file" ]; then if [ "$(cat $lmd_dir/$lmd_sigver_file)" = "$(cat $lmd_dir_tmp/$lmd_sigver_file)" ]; then echo "" >/dev/null fi else cd $lmd_dir cp -f $lmd_dir_tmp/$lmd_sigver_file . $curl --proxy $RSYNC_PROXY $lmd_sig_url && \ tar -xzf $lmd_sig_file && \ cd sigs && \ cp -f rfxn.hdb rfxn.ndb rfxn.yara $clamdb_dir fi sleep 3 clamdscan --reload exit 0
Nachdem das Skript gespeichert und ausführbar gemacht wurde, wird noch ein Cron-Job angelegt:
6 */6 * * * clamav [ -x /usr/local/bin/clamav-3dparty-update ] && /usr/local/bin/clamav-3dparty-update
Anwendung
manuell
clamdscan -m -z --fdpass oder --stream Datei|Verzeichnis
automatisch
Man kann den clamd mit entsprechenden Optionen in der clamd.conf „OnAccess“ per fanotify Verzeichnisse überwachen und scannen lassen, bekommt aber Probleme, wenn der clamd mit eigenem clamav Benutzer läuft. Stattdessen werden Verzeichnisse und Dateien mit iwatch per fanotify überwacht und bei Ereignissen wie der Neuanlage oder Veränderung von Dateien ein Skript aufgerufen, das die Dateien per clamdscan dem clamd Daemon zu scannen meldet und bei einem Malware-Fund eine entsprechende E-Mail absetzt.
iwatch Installation
sudo aptitude install iwatch
iwatch Konfiguration
sudo vi /etc/iwatch/iwatch.xml
- iwatch.xml
<?xml version="1.0" ?> <!DOCTYPE config SYSTEM "iwatch.dtd"> <config> <guard email="name@host.domain.tld" name="iwatch"></guard> <watchlist> <title>clamdscan</title> <contactpoint email="name@host.domain.tld" name="admin"/> <path type="recursive" events="create" alert="off" exec="/usr/local/bin/clamd_event '%f'">/pfad/dir1</path> <path type="recursive" events="create" alert="off" exec="/usr/local/bin/clamd_event '%f'">/pfad/dir2</path> <path type="recursive" events="default" alert="off" exec="/usr/local/bin/clamd_event '%f'">/pfad/download</path> <path type="regexception">(\.part|\.swp|datei1\.ext|datei2\.ext)</path> <path type="recursive" events="create" alert="off" exec="/usr/local/bin/clamd_event '%f'">/tmp</path> <path type="regexception">^incomplete.*\.(mp3|m4a|flac)</path> <path type="recursive" events="create" alert="off" exec="/usr/local/bin/clamd_event '%f'">/var/tmp</path> <path type="single" events="default" alert="off" exec="/usr/local/bin/clamd_event '%f'">/var/cache/apt/archives</path> </watchlist> </config>
Ausnahmen für Verzeichnisinhalte werden direkt unter die Regel für das Verzeichnis gesetzt – entweder mit dem regexception Typ für RegEx-Muster oder exception Typ für absolute Pfadangaben zu einzelnen Dateien oder Unterverzeichnissen.
Scan-Skript
- clamd_event
#!/bin/sh # für UID die uid des Benutzers einsetzen, der clamdscan ausführen soll scan="$(sudo -H -u \#UID clamdscan -m -z --no-summary --fdpass "$1")" result="$(echo "$scan" | grep -c FOUND)" if [ $result = 1 ]; then echo "Clamdscan-Resultat:\n$scan" | mail -s "[clamdscan] Alarm" root else exit 0 fi exit 0