如何獲取有關最近一次惡意軟體掃描的電子郵件報告?
maldet / Rfxn Linux MalDetect 文件為獲取電子郵件報告提供了此功能,即使沒有發現任何內容:
-e, --report SCANID email View scan report of most recent scan or of a specific SCANID and optionally e-mail the report to a supplied e-mail address e.g: maldet --report e.g: maldet --report list e.g: maldet --report 050910-1534.21135 e.g: maldet --report SCANID user@domain.com
一切都非常簡單,但我不確定如何在此處將電子郵件地址作為第二個參數傳遞,同時允許第一個參數(掃描 ID)回退到其預設值,以便 maldet 將最新報告的任何內容髮送給此自定義電子郵件地址。我希望能夠使用它(例如在 cron 中)定期檢查 Maldet 是否正在掃描並能夠按預期發送電子郵件報告。
我已經嘗試
maldet --report "" user@domain.com
基於在 bash 中傳遞空變數的標準方法,但它會忽略它並將看起來像空報告的內容輸出到控制台中。我也嘗試過類似的東西
maldet --report 0 user@domain.com
,maldet --report " " user@domain.com
但它會響應{report} no report found, aborting
。如果相關,環境是 Centos。
要麼的作者
maldet
沒有提供這種可能性,要麼忽略了記錄它。從外面是不可能猜到的。最好的方法是UTSL:在程序原始碼中查找它如何處理-e
選項以及是否有辦法啟動“最近掃描”分支並同時啟動電子郵件選項。
很抱歉復活了一個老問題。我在每次掃描後嘗試讓 maldet 通過電子郵件發送報告時遇到了同樣的問題。我按照@Tilman 的建議深入研究了原始碼。負責發送報告郵件的函式 view_report() 可以在
/usr/local/maldetect/internals/functions
v1.6.4 的第 645-706 行找到。具體查看負責的程式碼(第 681-696 行),我們看到只有在儲存為 的 SCANID$rid
是後綴時才會發送郵件,即190429-0343.31494
,對應於報告的文件/usr/local/maldetect/sess/
名session.190429-0343.31494
if [ -f "$sessdir/session.$rid" ] && [ ! -z "$(echo $2 | grep '\@')" ]; then if [ -f "$mail" ]; then cat $sessdir/session.$rid | $mail -s "$email_subj" "$2" elif [ -f "$sendmail" ]; then if ! grep -q "SUBJECT: " "$sessdir/session.$rid"; then echo -e "SUBJECT: $email_subj\n$(cat $sessdir/session.$rid)" > $sessdir/session.$rid fi cat $sessdir/session.$rid | $sendmail -t "$2" else eout "{scan} no \$mail or \$sendmail binaries found, e-mail alerts disabled." exit fi eout "{report} report ID $rid sent to $2" 1 exit fi
處理空 SCANID 的程式碼緊隨其後(第 697-705 行):
if [ "$rid" == "" ] && [ -f "$sessdir/session.last" ]; then rid=`cat $sessdir/session.last` $EDITOR $sessdir/session.$rid elif [ -f "$sessdir/session.$rid" ]; then $EDITOR $sessdir/session.$rid else echo "{report} no report found, aborting." exit fi
我原以為處理空 SCANID 的程式碼會簡單地抓取最新的並通過電子郵件發送。它實際上所做的是查看
/usr/local/maldetect/sess/session.last
maldet 儲存最新SCANID 的位置。並且由於某種原因,它會在終端編輯器中打開相應的報告,而不僅僅是列印出來。請注意,實際上沒有任何工作程式碼可以通過電子郵件發送最新報告。– 更新修復 - 2019 年 5 月 5 日–
由於阻止 LMD 執行我最初修復中要求的完整性檢查是一個潛在的安全風險,因此我使用 LMD 的 custom.cron 創建了一個替代解決方案。好處是完整性檢查仍然存在,並且電子郵件腳本應該通過更新保持不變。您無需接觸 LMD 內部文件或 maldet 每日 cron。
確保
$email_alert="1"
並$email_addr=
設置為至少一個正確的電子郵件地址/usr/local/maldetect/conf.maldet
。然後添加以下內容/usr/local/maldetect/cron/custom.cron
,它將在 maldet 每日 cron 結束時自動執行:## # Please use this file for preservation of custom LMD execution code for the daily cronjob. # NOTE: scripts in this file are called at the end of maldet daily cron as $custom_cron_exec ## # log_cron="1" enable logging, log_cron="0" disable logging # applies only to the code in this file log_cron="1" # logging function borrowed from /maldetect/internals/functions eout() { if [ "$log_cron" == "1" ]; then msg="$1" stdout="$2" appn=maldet if [ ! -d "$logdir" ]; then mkdir -p $logdir ; chmod 700 $logdir fi if [ ! -f "$maldet_log" ]; then touch $maldet_log fi log_size=`$wc -l $maldet_log | awk '{print$1}'` if [ "$log_size" -ge "20000" ]; then trim=1000 printf "%s\n" "$trim,${log_size}d" w | ed -s $maldet_log 2> /dev/null fi if [ ! "$msg" == "" ]; then echo "$(date +"%b %d %H:%M:%S") $(hostname -s) $appn($$): $msg" >> $maldet_log if [ ! -z "$stdout" ]; then echo "$appn($$): $msg" fi fi fi } eout "{cron} running $cron_custom_exec" ## # LMD Daily Email v1.0.0 # Author: kdub Email: kdubdev@gmail.com Date: May 5th, 2019 # https://github.com/kdubdev/linux-malware-detect/blob/master/files/cron/custom.cron # Script to send email of newest report after daily scan. More info: # https://serverfault.com/questions/805158/how-to-get-an-email-report-of-whatever-the-most-recent-maldet-scan-is # # de_version='v1.0.0' eout "{cron} starting LMD Cron Email $de_version" eout "{cron} $intcnf shows email_alert=$email_alert email_addr=$email_addr" # Default email subject defined in /usr/local/maldetect/internals/internals.conf # is email_subj="maldet alert from $(hostname)" # comment this line to use the default email_subj or change to what you want printf -v email_subj '[%s] %s: Scan Report' "$(hostname)" "$appn($$)" # uncomment email_addr below to override recipients. Separate multiple emails with , # use $email_addr to include recipient defined in /usr/local/maldetect/conf.maldet # email_addr="$email_addr,second@domain.tld,third@domain.tld" # this is the email text inserted before the report body_intro="Here are the results of the latest LMD scan:" # this is the email text inserted after the report printf -v body_footer "Email provided by LMD Cron Email %s\nCron file: %s\nLog file: %s" "$de_version" "$cron_custom_exec" "$maldet_log" # this is a very weak email validation, just looking for @ if [ "$email_alert" == "1" ] && [ ! -z "$(echo $email_addr | grep '\@')" ]; then # email_alert is true and email provided, send newest report if [ -f "$sessdir/session.last" ]; then # Get most recent scan id rid=$(cat "$sessdir/session.last") if [ ! -z "$rid" ]; then # session.list contains something if [ -f "$sessdir/session.$rid" ]; then # report exists, get contents body=$(cat "$sessdir/session.$rid") eout "{cron} reading report $sessdir/session.$rid" else # report doesn't exist body="{cron} unable to find report $sessdir/session.$rid." fi if [ -z "$body" ]; then # report file exists but is empty body="{cron} report $sessdir/session.$rid is empty." fi else # session.last is empty body="{cron} $sessdir/session.last is empty." fi else # session.last doesn't exist body="{cron} unable to find $sessdir/session.last." fi # log if body starts with {cron} ie there's a problem reading report if [[ $body == '{cron}'* ]]; then eout "$body" fi # add intro and footer to body body=$(printf "%s\n\n%s\n\n%s\n\n" "$body_intro" "$body" "$body_footer") if [ -f "$mail" ]; then printf "%s" "$body" | $mail -s "$email_subj" "$email_addr" eout "{cron} mail sent using $mail to $email_addr, subject: $email_subj." elif [ -f "$sendmail" ]; then printf "%s\n%s" "$email_subj" "$body" | $sendmail -t "$email_addr" eout "{cron} mail sent using $sendmail to $email_addr, subject: $email_subj." fi fi eout "{cron} mail latest report finished." eout "{cron} done running $cron_custom_exec"
您也可以在此處檢查更新https://github.com/kdubdev/linux-malware-detect/blob/master/files/cron/custom.cron
在腳本中,您可以禁用日誌記錄、覆蓋電子郵件主題和/或收件人,以及自定義電子郵件正文介紹和頁腳。該腳本有大量註釋,因此您可以跟進或進行更改。
我歡迎任何回饋或改進建議。
– 下面的原始修復 –
為了解決這個問題並添加其他改進,我修改了 view_report() 並進行了以下更改:
- 添加選項“最新”作為別名
--report
並--report ""
允許$ maldet --report newest user@domain.com
- 使用時正確通過電子郵件發送最新報告
$ maldet --report newest user@domain.com
或$ maldet --report "" user@domain.com
- 從不必要地使用編輯器來查看報告,而不是簡單地列印到終端
- 改進的日誌記錄
**首先:**您需要設置
autoupdate_version_hashed="0"
以/usr/local/maldetect/conf.maldet
防止 LMD 在執行更新檢查時自動覆蓋您所做的任何更改。請注意,這是一個潛在的安全問題:# This controls validating the LMD executable MD5 hash with known # good upstream hash value. This allows LMD to replace the the # executable / force a reinstallation in the event the LMD executable # is tampered with or corrupted. If you intend to make customizations # to the LMD executable, you should disable this feature. # [0 = disabled, 1 = enabled] autoupdate_version_hashed="0"
**第二:**將您的目前
view_report()
/usr/local/maldetect/internals/functions
(第 645-706 行)替換為:view_report() { # $1 is first arg passed from command line ex. $ maldet --report $1 $2 rid="$1" # $ maldet --report list if [ "$rid" == "list" ]; then tmpf="$tmpdir/.areps$$" for file in `ls $sessdir/session.[0-9]* 2> /dev/null`; do SCANID=`cat $file | grep "SCAN ID" | sed 's/SCAN ID/SCANID/'` FILES=`cat $file | grep "TOTAL FILES" | sed 's/TOTAL //'` HITS=`cat $file | grep "TOTAL HITS" | sed 's/TOTAL //'` CLEAN=`cat $file | grep "TOTAL CLEANED" | sed 's/TOTAL //'` TIME=`cat $file | grep -E "^TIME|^STARTED" | sed -e 's/TIME: //' -e 's/STARTED: //' | awk '{print$1,$2,$3,$4}'` TIME_U=`date -d "$TIME" "+%s" 2> /dev/null` ETIME=`cat $file | grep "ELAPSED" | awk '{print$1,$2}' | sed 's/ELAPSED/RUNTIME/'` if [ -z "$ETIME" ]; then ETIME="RUNTIME: unknown" fi if [ ! -z "$SCANID" ] && [ ! -z "$TIME" ]; then clean_zero=`echo $CLEAN | awk '{print$2}'` if [ -z "$clean_zero" ]; then CLEAN="CLEANED: 0" fi echo "$TIME_U | $TIME | $SCANID | $ETIME | $FILES | $HITS | $CLEAN" >> $tmpf fi done if [ -f "$tmpf" ]; then if [ "$OSTYPE" == "FreeBSD" ]; then cat $tmpf | sort -k1 -n | cut -d'|' -f2-7 | column -t | more else cat $tmpf | sort -k1 -n | tac | cut -d'|' -f2-7 | column -t | more fi rm -f $tmpf 2> /dev/null exit 0 else eout "{list} unable to find report data for list, check \$sessdir" exit 1 fi fi # If no SCANID is provided or "recent" then set $rid to most recent. # $ maldet --report "" or $maldet --report newest if { [ "$rid" == "" ] || [ "$rid" == "newest" ]; } && [ -f "$sessdir/session.last" ]; then rid=`cat $sessdir/session.last` fi # make sure report exists if [ -f "$sessdir/session.$rid" ]; then # if email is provided, then send the report and exit if [ ! -z "$(echo $2 | grep '\@')" ]; then if [ -f "$mail" ]; then cat $sessdir/session.$rid | $mail -s "$email_subj" "$2" elif [ -f "$sendmail" ]; then if ! grep -q "SUBJECT: " "$sessdir/session.$rid"; then echo -e "SUBJECT: $email_subj\n$(cat $sessdir/session.$rid)" > $sessdir/session.$rid fi cat $sessdir/session.$rid | $sendmail -t "$2" else # eout is an internal function to log to maldet_log and echo eout "{scan} no \$mail or \$sendmail binaries found, e-mail alerts disabled." exit fi eout "{report} report ID $rid sent to $2" 1 exit # no email is provided so show report and exit else printf '%b\n' "$(cat $sessdir/session.$rid)" exit fi # can't find requested report so log & echo error else eout "{report} unable to find report session.\$rid, aborting." exit fi }
/usr/local/maldetect/internals/functions
您也可以在此處的拉取請求中找到整個更新的文件: https ://github.com/kdubdev/linux-malware-detect/blob/patch-1/files/internals/functions最後:
/etc/cron.daily/maldet
如果您希望在每次每日掃描後收到電子郵件 ,請將 以下行添加到末尾:$inspath/maldet --report newest user@domain.com
注意:如果不清楚,您可以使用
-e
或--report
互換。